-!IF DEFINED(DEBUG)
-LINK_FLAGS = /nologo /DEBUG shell32.lib
-CL_FLAGS = /nologo /Zi /O2 /W3 /DFACTOR_DEBUG
-!ELSE
-LINK_FLAGS = /nologo /safeseh:no shell32.lib
+!IF DEFINED(PLATFORM)
+
+LINK_FLAGS = /nologo shell32.lib
CL_FLAGS = /nologo /O2 /W3
+
+!IF DEFINED(DEBUG)
+LINK_FLAGS = $(LINK_FLAGS) /DEBUG
+CL_FLAGS = $(CL_FLAGS) /Zi /DFACTOR_DEBUG
!ENDIF
+!IF "$(PLATFORM)" == "x86-32"
+LINK_FLAGS = $(LINK_FLAGS) /safeseh
+PLAF_DLL_OBJS = vm\os-windows-nt-x86.32.obj vm\safeseh.obj
+!ELSEIF "$(PLATFORM)" == "x86-64"
+PLAF_DLL_OBJS = vm\os-windows-nt-x86.64.obj
+!ENDIF
+
+ML_FLAGS = /nologo /safeseh
+
EXE_OBJS = vm\main-windows-nt.obj vm\factor.res
-DLL_OBJS = vm\os-windows-nt.obj \
+DLL_OBJS = $(PLAF_DLL_OBJS) \
vm\os-windows.obj \
+ vm\os-windows-nt.obj \
vm\aging_collector.obj \
vm\alien.obj \
vm\arrays.obj \
.c.obj:
cl $(CL_FLAGS) /Fo$@ /c $<
+.asm.obj:
+ ml $(ML_FLAGS) /Fo$@ /c $<
+
.rs.res:
rc $<
-all: factor.com factor.exe factor.dll.lib libfactor-ffi-test.dll
-
libfactor-ffi-test.dll: vm/ffi_test.obj
link $(LINK_FLAGS) /out:libfactor-ffi-test.dll /dll vm/ffi_test.obj
factor.exe: $(EXE_OBJS) $(DLL_OBJS)
link $(LINK_FLAGS) /out:factor.exe /SUBSYSTEM:windows $(EXE_OBJS) $(DLL_OBJS)
+all: factor.com factor.exe factor.dll.lib libfactor-ffi-test.dll
+
+!ENDIF
+
+default:
+ @echo Usage: nmake /f Nmakefile platform
+ @echo Where platform is one of:
+ @echo x86-32
+ @echo x86-64
+ @exit 1
+
+x86-32:
+ nmake PLATFORM=x86-32 /f Nmakefile all
+
+x86-64:
+ nmake PLATFORM=x86-64 /f Nmakefile all
+
clean:
del vm\*.obj
del factor.lib
del factor.dll
del factor.dll.lib
-.PHONY: all clean
+.PHONY: all default x86-32 x86-64 clean
.SUFFIXES: .rs
! Copyright (C) 2008, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
-USING: alien alien.strings alien.c-types alien.data alien.accessors
+USING: alien alien.strings alien.c-types alien.accessors
arrays words sequences math kernel namespaces fry cpu.architecture
-io.encodings.binary io.encodings.utf8 accessors ;
+io.encodings.binary io.encodings.utf8 accessors compiler.units ;
IN: alien.arrays
INSTANCE: array value-type
M: array stack-size drop void* stack-size ;
-M: array c-type-boxer-quot
- unclip [ array-length ] dip [ <c-direct-array> ] 2curry ;
-
-M: array c-type-unboxer-quot drop [ >c-ptr ] ;
-
PREDICATE: string-type < pair
first2 [ c-string = ] [ word? ] bi* and ;
M: string-type c-type-setter
drop [ set-alien-cell ] ;
-{ c-string utf8 } c-string typedef
+[ { c-string utf8 } c-string typedef ] with-compilation-unit
! (c)2009, 2010 Slava Pestov, Joe Groff bsd license
-USING: accessors alien alien.c-types alien.strings arrays
+USING: accessors alien alien.c-types alien.arrays alien.strings arrays
byte-arrays cpu.architecture fry io io.encodings.binary
io.files io.streams.memory kernel libc math sequences words
byte-vectors ;
M: value-type c-type-setter ( type -- quot )
[ c-type-getter ] [ c-type-unboxer-quot ] [ heap-size ] tri
'[ @ swap @ _ memcpy ] ;
+
+M: array c-type-boxer-quot
+ unclip [ array-length ] dip [ <c-direct-array> ] 2curry ;
+
+M: array c-type-unboxer-quot drop [ >c-ptr ] ;
+
<<
: add-f2c-libraries ( -- )
- "I77" "libI77.so" "cdecl" add-library
- "F77" "libF77.so" "cdecl" add-library ;
+ "I77" "libI77.so" cdecl add-library
+ "F77" "libF77.so" cdecl add-library ;
os netbsd? [ add-f2c-libraries ] when
>>
[ "__" append ] [ "_" append ] if ;
HOOK: fortran-c-abi fortran-abi ( -- abi )
-M: f2c-abi fortran-c-abi "cdecl" ;
-M: g95-abi fortran-c-abi "cdecl" ;
-M: gfortran-abi fortran-c-abi "cdecl" ;
-M: intel-unix-abi fortran-c-abi "cdecl" ;
-M: intel-windows-abi fortran-c-abi "cdecl" ;
+M: f2c-abi fortran-c-abi cdecl ;
+M: g95-abi fortran-c-abi cdecl ;
+M: gfortran-abi fortran-c-abi cdecl ;
+M: intel-unix-abi fortran-c-abi cdecl ;
+M: intel-windows-abi fortran-c-abi cdecl ;
HOOK: real-functions-return-double? fortran-abi ( -- ? )
M: f2c-abi real-functions-return-double? t ;
[ \ fortran-invoke 5 [ ] nsequence ] dip define-declared ;
SYNTAX: SUBROUTINE:
- f "c-library" get scan ";" parse-tokens
+ f current-library get scan ";" parse-tokens
[ "()" subseq? not ] filter define-fortran-function ;
SYNTAX: FUNCTION:
- scan "c-library" get scan ";" parse-tokens
+ scan current-library get scan ";" parse-tokens
[ "()" subseq? not ] filter define-fortran-function ;
SYNTAX: LIBRARY:
scan
- [ "c-library" set ]
+ [ current-library set ]
[ set-fortran-abi ] bi ;
HELP: <library>
{ $values
- { "path" "a pathname string" } { "abi" "the ABI used by the library, either " { $snippet "cdecl" } " or " { $snippet "stdcall" } }
+ { "path" "a pathname string" } { "abi" "the ABI used by the library, either " { $link cdecl } " or " { $link stdcall } }
{ "library" library } }
{ $description "Opens a C library using the path and ABI parameters and outputs a library tuple." }
{ $notes "User code should use " { $link add-library } " so that the opened library is added to a global hashtable, " { $link libraries } "." } ;
{ $description "Looks up a library by its logical name. The library object is a hashtable with the following keys:"
{ $list
{ { $snippet "name" } " - the full path of the C library binary" }
- { { $snippet "abi" } " - the ABI used by the library, either " { $snippet "cdecl" } " or " { $snippet "stdcall" } }
+ { { $snippet "abi" } " - the ABI used by the library, either " { $link cdecl } " or " { $link stdcall } }
{ { $snippet "dll" } " - an instance of the " { $link dll } " class; only set if the library is loaded" }
}
} ;
{ $description "Loads a library by logical name and outputs a handle which may be passed to " { $link dlsym } " or " { $link dlclose } ". If the library is already loaded, returns the existing handle." } ;
HELP: add-library
-{ $values { "name" string } { "path" string } { "abi" "one of " { $snippet "\"cdecl\"" } " or " { $snippet "\"stdcall\"" } } }
+{ $values { "name" string } { "path" string } { "abi" "one of " { $link cdecl } " or " { $link stdcall } } }
{ $description "Defines a new logical library named " { $snippet "name" } " located in the file system at " { $snippet "path" } " and the specified ABI. The logical library name can then be used by a " { $link POSTPONE: LIBRARY: } " form to specify the logical library for subsequent " { $link POSTPONE: FUNCTION: } " definitions." }
{ $notes "Because the entire source file is parsed before top-level forms are executed, " { $link add-library } " must be placed within a " { $snippet "<< ... >>" } " parse-time evaluation block."
$nl
{ $examples "Here is a typical usage of " { $link add-library } ":"
{ $code
"<< \"freetype\" {"
- " { [ os macosx? ] [ \"libfreetype.6.dylib\" \"cdecl\" add-library ] }"
- " { [ os windows? ] [ \"freetype6.dll\" \"cdecl\" add-library ] }"
+ " { [ os macosx? ] [ \"libfreetype.6.dylib\" cdecl add-library ] }"
+ " { [ os windows? ] [ \"freetype6.dll\" cdecl add-library ] }"
" [ drop ]"
"} cond >>"
}
[ <library> swap libraries get set-at ] 3bi ;
: library-abi ( library -- abi )
- library [ abi>> ] [ "cdecl" ] if* ;
+ library [ abi>> ] [ cdecl ] if* ;
+
+ERROR: no-such-symbol name library ;
+
+: address-of ( name library -- value )
+ 2dup load-library dlsym [ 2nip ] [ no-such-symbol ] if* ;
SYMBOL: deploy-libraries
assocs classes combinators combinators.short-circuit
compiler.units effects grouping kernel parser sequences
splitting words fry locals lexer namespaces summary math
-vocabs.parser ;
+vocabs.parser words.constant ;
IN: alien.parser
+SYMBOL: current-library
+
: parse-c-type-name ( name -- word )
dup search [ ] [ no-word ] ?if ;
dup "*" tail?
[ *-in-c-type-name ] when ;
-: CREATE-C-TYPE ( -- word )
- scan validate-c-type-name current-vocab create {
+: (CREATE-C-TYPE) ( word -- word )
+ validate-c-type-name current-vocab create {
[ fake-definition ]
[ set-word ]
[ reset-c-type ]
[ ]
} cleave ;
+: CREATE-C-TYPE ( -- word )
+ scan (CREATE-C-TYPE) ;
+
<PRIVATE
GENERIC: return-type-name ( type -- name )
PRIVATE>
+: define-enum-member ( word-string value -- next-value )
+ [ create-in ] dip [ define-constant ] keep 1 + ;
+
+: parse-enum-member ( word-string value -- next-value )
+ over "{" =
+ [ 2drop scan scan-object define-enum-member "}" expect ]
+ [ define-enum-member ] if ;
+
+: parse-enum-members ( counter -- )
+ scan dup ";" = not
+ [ swap parse-enum-member parse-enum-members ] [ 2drop ] if ;
+
: scan-function-name ( -- return function )
scan-c-type scan parse-pointers ;
: function-effect ( names return -- effect )
[ { } ] [ return-type-name 1array ] if-void <effect> ;
-:: make-function ( return function library types names -- word quot effect )
- function create-in dup reset-generic
+: create-function ( name -- word )
+ create-in dup reset-generic ;
+
+:: (make-function) ( return function library types names -- quot effect )
return library function types function-quot
names return function-effect ;
-: (FUNCTION:) ( -- word quot effect )
- scan-function-name "c-library" get ";" scan-c-args make-function ;
+:: make-function ( return function library types names -- word quot effect )
+ function create-function
+ return function library types names (make-function) ;
+
+: (FUNCTION:) ( -- return function library types names )
+ scan-function-name current-library get ";" scan-c-args ;
: callback-quot ( return types abi -- quot )
'[ [ _ _ _ ] dip alien-callback ] ;
type-word return types lib library-abi callback-quot (( quot -- alien )) ;
: (CALLBACK:) ( -- word quot effect )
- "c-library" get
+ current-library get
scan-function-name ";" scan-c-args make-callback-type ;
-PREDICATE: alien-function-word < word
+PREDICATE: alien-function-alias-word < word
def>> {
[ length 5 = ]
[ last \ alien-invoke eq? ]
} 1&& ;
+PREDICATE: alien-function-word < alien-function-alias-word
+ [ def>> third ] [ name>> ] bi = ;
+
PREDICATE: alien-callback-type-word < typedef-word
"callback-effect" word-prop ;
+
+: global-quot ( type word -- quot )
+ name>> current-library get '[ _ _ address-of 0 ]
+ swap c-type-getter-boxer append ;
+
+: define-global ( type word -- )
+ [ nip ] [ global-quot ] 2bi (( -- value )) define-declared ;
: pprint-library ( library -- )
[ \ LIBRARY: [ text ] pprint-prefix ] when* ;
+: pprint-function ( word quot -- )
+ [ def>> first pprint-c-type ]
+ swap
+ [
+ <block "(" text
+ [ def>> fourth ] [ stack-effect in>> ] bi
+ pprint-function-args
+ ")" text block>
+ ] tri ; inline
+
+M: alien-function-alias-word definer
+ drop \ FUNCTION-ALIAS: \ ; ;
+M: alien-function-alias-word definition drop f ;
+M: alien-function-alias-word synopsis*
+ {
+ [ seeing-word ]
+ [ def>> second pprint-library ]
+ [ definer. ]
+ [ pprint-word ]
+ [ [ def>> third text ] pprint-function ]
+ } cleave ;
+
M: alien-function-word definer
drop \ FUNCTION: \ ; ;
-M: alien-function-word definition drop f ;
M: alien-function-word synopsis*
{
[ seeing-word ]
[ def>> second pprint-library ]
[ definer. ]
- [ def>> first pprint-c-type ]
- [ pprint-word ]
- [
- <block "(" text
- [ def>> fourth ] [ stack-effect in>> ] bi
- pprint-function-args
- ")" text block>
- ]
+ [ [ pprint-word ] pprint-function ]
} cleave ;
M: alien-callback-type-word definer
IN: alien.remote-control
: eval-callback ( -- callback )
- void* { c-string } "cdecl"
+ void* { c-string } cdecl
[ eval>string utf8 malloc-string ] alien-callback ;
: yield-callback ( -- callback )
- void { } "cdecl" [ yield ] alien-callback ;
+ void { } cdecl [ yield ] alien-callback ;
: sleep-callback ( -- callback )
- void { long } "cdecl" [ sleep ] alien-callback ;
+ void { long } cdecl [ sleep ] alien-callback ;
: ?callback ( word -- alien )
dup optimized? [ execute ] [ drop f ] if ; inline
{ $notes "Logical library names are defined with the " { $link add-library } " word." } ;
HELP: FUNCTION:
-{ $syntax "FUNCTION: return name ( parameters )" }
+{ $syntax "FUNCTION: return name ( parameters ) ;" }
{ $values { "return" "a C return type" } { "name" "a C function name" } { "parameters" "a comma-separated sequence of type/name pairs; " { $snippet "type1 arg1, type2 arg2, ..." } } }
-{ $description "Defines a new word " { $snippet "name" } " which calls a C library function with the same name, in the logical library given by the most recent " { $link POSTPONE: LIBRARY: } " declaration."
+{ $description "Defines a new word " { $snippet "name" } " which calls the C library function with the same " { $snippet "name" } " in the logical library given by the most recent " { $link POSTPONE: LIBRARY: } " declaration."
$nl
"The new word must be compiled before being executed." }
{ $examples
"The answer to the question is 42."
} }
"Using the " { $link c-string } " type instead of " { $snippet "char*" } " causes the FFI to automatically convert Factor strings to C strings. See " { $link "c-strings" } " for more information on using strings with the FFI."
-{ $notes "Note that the parentheses and commas are only syntax sugar and can be omitted; they serve no purpose other than to make the declaration slightly easier to read:"
+{ $notes "Note that the parentheses and commas are only syntax sugar and can be omitted; they serve no purpose other than to make the declaration easier to read. The following definitions are equivalent:"
{ $code
"FUNCTION: void glHint ( GLenum target, GLenum mode ) ;"
"FUNCTION: void glHint GLenum target GLenum mode ;"
-} } ;
+}
+"To make a Factor word with a name different from the C function, use " { $link POSTPONE: FUNCTION-ALIAS: } "." } ;
+
+HELP: FUNCTION-ALIAS:
+{ $syntax "FUNCTION-ALIAS: factor-name
+ return c_name ( parameters ) ;" }
+{ $values { "factor-name" "a Factor word name" } { "return" "a C return type" } { "name" "a C function name" } { "parameters" "a comma-separated sequence of type/name pairs; " { $snippet "type1 arg1, type2 arg2, ..." } } }
+{ $description "Defines a new word " { $snippet "factor-name" } " which calls the C library function named " { $snippet "c_name" } " in the logical library given by the most recent " { $link POSTPONE: LIBRARY: } " declaration."
+$nl
+"The new word must be compiled before being executed." }
+{ $notes "Note that the parentheses and commas are only syntax sugar and can be omitted. They serve no purpose other than to make the declaration easier to read." } ;
+
+{ POSTPONE: FUNCTION: POSTPONE: FUNCTION-ALIAS: } related-words
HELP: TYPEDEF:
{ $syntax "TYPEDEF: old new" }
{ $notes "This word differs from " { $link typedef } " in that it runs at parse time, to ensure correct ordering of operations when loading source files. Words defined in source files are compiled before top-level forms are run, so if a source file defines C binding words and uses " { $link typedef } ", the type alias won't be available at compile time." } ;
HELP: C-ENUM:
-{ $syntax "C-ENUM: words... ;" }
-{ $values { "words" "a sequence of word names" } }
-{ $description "Creates a sequence of word definitions in the current vocabulary. Each word pushes an integer according to its index in the enumeration definition. The first word pushes 0." }
+{ $syntax "C-ENUM: type/f words... ;" }
+{ $values { "type" "a name to typedef to int or f" } { "words" "a sequence of word names" } }
+{ $description "Creates a sequence of word definitions in the current vocabulary. Each word pushes an integer according to the rules of C enums." }
{ $notes "This word emulates a C-style " { $snippet "enum" } " in Factor. While this feature can be used for any purpose, using integer constants is discouraged unless it is for interfacing with C libraries. Factor code should use " { $link "words.symbol" } " or " { $link "singletons" } " instead." }
{ $examples
"Here is an example enumeration definition:"
- { $code "C-ENUM: red green blue ;" }
+ { $code "C-ENUM: color_t red { green 3 } blue ;" }
"It is equivalent to the following series of definitions:"
- { $code "CONSTANT: red 0" "CONSTANT: green 1" "CONSTANT: blue 2" }
+ { $code "CONSTANT: red 0" "CONSTANT: green 3" "CONSTANT: blue 4" }
} ;
HELP: C-TYPE:
! Copyright (C) 2005, 2010 Slava Pestov, Alex Chapman.
! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays alien alien.c-types
-alien.arrays alien.strings kernel math namespaces parser
-sequences words quotations math.parser splitting grouping
-effects assocs combinators lexer strings.parser alien.parser
-fry vocabs.parser words.constant alien.libraries ;
+USING: accessors arrays alien alien.c-types alien.arrays
+alien.strings kernel math namespaces parser sequences words
+quotations math.parser splitting grouping effects assocs
+combinators lexer strings.parser alien.parser fry vocabs.parser
+words.constant alien.libraries ;
IN: alien.syntax
SYNTAX: DLL" lexer get skip-blank parse-string dlopen suffix! ;
SYNTAX: BAD-ALIEN <bad-alien> suffix! ;
-SYNTAX: LIBRARY: scan "c-library" set ;
+SYNTAX: LIBRARY: scan current-library set ;
SYNTAX: FUNCTION:
- (FUNCTION:) define-declared ;
+ (FUNCTION:) make-function define-declared ;
+
+SYNTAX: FUNCTION-ALIAS:
+ scan create-function
+ (FUNCTION:) (make-function) define-declared ;
SYNTAX: CALLBACK:
(CALLBACK:) define-inline ;
scan-c-type CREATE-C-TYPE dup save-location typedef ;
SYNTAX: C-ENUM:
- ";" parse-tokens
- [ [ create-in ] dip define-constant ] each-index ;
+ scan dup "f" =
+ [ drop ]
+ [ (CREATE-C-TYPE) dup save-location int swap typedef ] if
+ 0 parse-enum-members ;
SYNTAX: C-TYPE:
void CREATE-C-TYPE typedef ;
-ERROR: no-such-symbol name library ;
-
-: address-of ( name library -- value )
- 2dup load-library dlsym [ 2nip ] [ no-such-symbol ] if* ;
-
SYNTAX: &:
- scan "c-library" get '[ _ _ address-of ] append! ;
-
-: global-quot ( type word -- quot )
- name>> "c-library" get '[ _ _ address-of 0 ]
- swap c-type-getter-boxer append ;
-
-: define-global ( type word -- )
- [ nip ] [ global-quot ] 2bi (( -- value )) define-declared ;
+ scan current-library get '[ _ _ address-of ] append! ;
SYNTAX: C-GLOBAL: scan-c-type CREATE-WORD define-global ;
! Copyright (c) 2007 Sampo Vuori
! Copyright (c) 2008 Matthew Willis
!
+
+
! Adapted from cairo.h, version 1.5.14
! License: http://factorcode.org/license.txt
IN: cairo.ffi
<< {
- { [ os winnt? ] [ "cairo" "libcairo-2.dll" "cdecl" add-library ] }
- { [ os macosx? ] [ "cairo" "/opt/local/lib/libcairo.dylib" "cdecl" add-library ] }
+ { [ os winnt? ] [ "cairo" "libcairo-2.dll" cdecl add-library ] }
+ { [ os macosx? ] [ "cairo" "/opt/local/lib/libcairo.dylib" cdecl add-library ] }
{ [ os unix? ] [ ] }
} cond >>
TYPEDEF: void* cairo_destroy_func_t
: cairo-destroy-func ( quot -- callback )
- [ void { pointer: void } "cdecl" ] dip alien-callback ; inline
+ [ void { pointer: void } cdecl ] dip alien-callback ; inline
! See cairo.h for details
STRUCT: cairo_user_data_key_t
{ unused int } ;
-TYPEDEF: int cairo_status_t
-C-ENUM:
+C-ENUM: cairo_status_t
CAIRO_STATUS_SUCCESS
CAIRO_STATUS_NO_MEMORY
CAIRO_STATUS_INVALID_RESTORE
TYPEDEF: void* cairo_write_func_t
: cairo-write-func ( quot -- callback )
- [ cairo_status_t { pointer: void c-string int } "cdecl" ] dip alien-callback ; inline
+ [ cairo_status_t { pointer: void c-string int } cdecl ] dip alien-callback ; inline
TYPEDEF: void* cairo_read_func_t
: cairo-read-func ( quot -- callback )
- [ cairo_status_t { pointer: void c-string int } "cdecl" ] dip alien-callback ; inline
+ [ cairo_status_t { pointer: void c-string int } cdecl ] dip alien-callback ; inline
! Functions for manipulating state objects
FUNCTION: cairo_t*
cairo_pop_group_to_source ( cairo_t* cr ) ;
! Modify state
-TYPEDEF: int cairo_operator_t
-C-ENUM:
+C-ENUM: cairo_operator_t
CAIRO_OPERATOR_CLEAR
CAIRO_OPERATOR_SOURCE
FUNCTION: void
cairo_set_tolerance ( cairo_t* cr, double tolerance ) ;
-TYPEDEF: int cairo_antialias_t
-C-ENUM:
+C-ENUM: cairo_antialias_t
CAIRO_ANTIALIAS_DEFAULT
CAIRO_ANTIALIAS_NONE
CAIRO_ANTIALIAS_GRAY
FUNCTION: void
cairo_set_antialias ( cairo_t* cr, cairo_antialias_t antialias ) ;
-TYPEDEF: int cairo_fill_rule_t
-C-ENUM:
+C-ENUM: cairo_fill_rule_t
CAIRO_FILL_RULE_WINDING
CAIRO_FILL_RULE_EVEN_ODD ;
FUNCTION: void
cairo_set_line_width ( cairo_t* cr, double width ) ;
-TYPEDEF: int cairo_line_cap_t
-C-ENUM:
+C-ENUM: cairo_line_cap_t
CAIRO_LINE_CAP_BUTT
CAIRO_LINE_CAP_ROUND
CAIRO_LINE_CAP_SQUARE ;
FUNCTION: void
cairo_set_line_cap ( cairo_t* cr, cairo_line_cap_t line_cap ) ;
-TYPEDEF: int cairo_line_join_t
-C-ENUM:
+C-ENUM: cairo_line_join_t
CAIRO_LINE_JOIN_MITER
CAIRO_LINE_JOIN_ROUND
CAIRO_LINE_JOIN_BEVEL ;
{ max_x_advance double }
{ max_y_advance double } ;
-TYPEDEF: int cairo_font_slant_t
-C-ENUM:
+C-ENUM: cairo_font_slant_t
CAIRO_FONT_SLANT_NORMAL
CAIRO_FONT_SLANT_ITALIC
CAIRO_FONT_SLANT_OBLIQUE ;
-TYPEDEF: int cairo_font_weight_t
-C-ENUM:
+C-ENUM: cairo_font_weight_t
CAIRO_FONT_WEIGHT_NORMAL
CAIRO_FONT_WEIGHT_BOLD ;
-TYPEDEF: int cairo_subpixel_order_t
-C-ENUM:
+C-ENUM: cairo_subpixel_order_t
CAIRO_SUBPIXEL_ORDER_DEFAULT
CAIRO_SUBPIXEL_ORDER_RGB
CAIRO_SUBPIXEL_ORDER_BGR
CAIRO_SUBPIXEL_ORDER_VRGB
CAIRO_SUBPIXEL_ORDER_VBGR ;
-TYPEDEF: int cairo_hint_style_t
-C-ENUM:
+C-ENUM: cairo_hint_style_t
CAIRO_HINT_STYLE_DEFAULT
CAIRO_HINT_STYLE_NONE
CAIRO_HINT_STYLE_SLIGHT
CAIRO_HINT_STYLE_MEDIUM
CAIRO_HINT_STYLE_FULL ;
-TYPEDEF: int cairo_hint_metrics_t
-C-ENUM:
+C-ENUM: cairo_hint_metrics_t
CAIRO_HINT_METRICS_DEFAULT
CAIRO_HINT_METRICS_OFF
CAIRO_HINT_METRICS_ON ;
FUNCTION: cairo_status_t
cairo_font_face_status ( cairo_font_face_t* font_face ) ;
-TYPEDEF: int cairo_font_type_t
-C-ENUM:
+C-ENUM: cairo_font_type_t
CAIRO_FONT_TYPE_TOY
CAIRO_FONT_TYPE_FT
CAIRO_FONT_TYPE_WIN32
FUNCTION: cairo_surface_t*
cairo_get_group_target ( cairo_t* cr ) ;
-TYPEDEF: int cairo_path_data_type_t
-C-ENUM:
+C-ENUM: cairo_path_data_type_t
CAIRO_PATH_MOVE_TO
CAIRO_PATH_LINE_TO
CAIRO_PATH_CURVE_TO
FUNCTION: cairo_status_t
cairo_surface_status ( cairo_surface_t* surface ) ;
-TYPEDEF: int cairo_surface_type_t
-C-ENUM:
+C-ENUM: cairo_surface_type_t
CAIRO_SURFACE_TYPE_IMAGE
CAIRO_SURFACE_TYPE_PDF
CAIRO_SURFACE_TYPE_PS
! Image-surface functions
-TYPEDEF: int cairo_format_t
-C-ENUM:
+C-ENUM: cairo_format_t
CAIRO_FORMAT_ARGB32
CAIRO_FORMAT_RGB24
CAIRO_FORMAT_A8
FUNCTION: cairo_status_t
cairo_pattern_set_user_data ( cairo_pattern_t* pattern, cairo_user_data_key_t* key, void* user_data, cairo_destroy_func_t destroy ) ;
-TYPEDEF: int cairo_pattern_type_t
-C-ENUM:
+C-ENUM: cairo_pattern_type_t
CAIRO_PATTERN_TYPE_SOLID
CAIRO_PATTERN_TYPE_SURFACE
CAIRO_PATTERN_TYPE_LINEAR
FUNCTION: void
cairo_pattern_get_matrix ( cairo_pattern_t* pattern, cairo_matrix_t* matrix ) ;
-TYPEDEF: int cairo_extend_t
-C-ENUM:
+C-ENUM: cairo_extend_t
CAIRO_EXTEND_NONE
CAIRO_EXTEND_REPEAT
CAIRO_EXTEND_REFLECT
FUNCTION: cairo_extend_t
cairo_pattern_get_extend ( cairo_pattern_t* pattern ) ;
-TYPEDEF: int cairo_filter_t
-C-ENUM:
+C-ENUM: cairo_filter_t
CAIRO_FILTER_FAST
CAIRO_FILTER_GOOD
CAIRO_FILTER_BEST
classes.tuple.private classes.tuple combinators compiler.tree.debugger
compiler.units destructors io.encodings.utf8 io.pathnames
io.streams.string kernel libc literals math mirrors namespaces
-prettyprint prettyprint.config see sequences specialized-arrays system
-tools.test parser lexer eval layouts generic.single classes ;
+prettyprint prettyprint.config see sequences specialized-arrays
+system tools.test parser lexer eval layouts generic.single classes
+vocabs ;
FROM: math => float ;
+FROM: specialized-arrays.private => specialized-array-vocab ;
QUALIFIED-WITH: alien.c-types c
SPECIALIZED-ARRAY: char
SPECIALIZED-ARRAY: int
{ x>> } inlined?
] unit-test
+[ ] [
+ [
+ struct-test-optimization specialized-array-vocab forget-vocab
+ ] with-compilation-unit
+] unit-test
+
! Test cloning structs
STRUCT: clone-test-struct { x int } { y char[3] } ;
: <NSString> ( str -- alien ) <CFString> -> autorelease ;
-C-ENUM:
+C-ENUM: f
NSApplicationDelegateReplySuccess
NSApplicationDelegateReplyCancel
NSApplicationDelegateReplyFailure ;
: prepare-method ( ret types quot -- type imp )
[ [ encode-types ] 2keep ] dip
- '[ _ _ "cdecl" _ alien-callback ]
+ '[ _ _ cdecl _ alien-callback ]
(( -- callback )) define-temp ;
: prepare-methods ( methods -- methods )
: alien-parameters ( params -- seq )
dup parameters>>
- swap return>> large-struct? [ void* prefix ] when ;
+ swap return>> large-struct? [ struct-return-pointer-type prefix ] when ;
: alien-return ( params -- type )
return>> dup large-struct? [ drop void ] when ;
[ [ dup ] loop ]
[ [ 2 ] [ 3 throw ] if 4 ]
[ int f "malloc" { int } alien-invoke ]
- [ int { int } "cdecl" alien-indirect ]
- [ int { int } "cdecl" [ ] alien-callback ]
+ [ int { int } cdecl alien-indirect ]
+ [ int { int } cdecl [ ] alien-callback ]
[ swap - + * ]
[ swap slot ]
[ blahblah ]
compiler.codegen.fixup
compiler.utilities ;
FROM: namespaces => set ;
+FROM: compiler.errors => no-such-symbol ;
IN: compiler.codegen
SYMBOL: insn-counts
M: double-rep next-fastcall-param
float-regs inc [ ?dummy-stack-params ] [ ?dummy-int-params ] bi ;
-GENERIC: reg-class-full? ( reg-class -- ? )
+GENERIC# reg-class-full? 1 ( reg-class abi -- ? )
-M: stack-params reg-class-full? drop t ;
+M: stack-params reg-class-full? 2drop t ;
M: reg-class reg-class-full?
- [ get ] [ param-regs length ] bi >= ;
+ [ get ] swap '[ _ param-regs length ] bi >= ;
: alloc-stack-param ( rep -- n reg-class rep )
stack-params get
: alloc-fastcall-param ( rep -- n reg-class rep )
[ [ reg-class-of get ] [ reg-class-of ] [ next-fastcall-param ] tri ] keep ;
-: alloc-parameter ( parameter -- reg rep )
- c-type-rep dup reg-class-of reg-class-full?
+:: alloc-parameter ( parameter abi -- reg rep )
+ parameter c-type-rep dup reg-class-of abi reg-class-full?
[ alloc-stack-param ] [ alloc-fastcall-param ] if
- [ param-reg ] dip ;
+ [ abi param-reg ] dip ;
+
+SYMBOL: (stack-value)
+<< void* c-type clone \ (stack-value) define-primitive-type
+stack-params \ (stack-value) c-type (>>rep) >>
+
+: ((flatten-type)) ( type to-type -- seq )
+ [ stack-size cell align cell /i ] dip c-type <repetition> ; inline
: (flatten-int-type) ( type -- seq )
- stack-size cell align cell /i void* c-type <repetition> ;
+ void* ((flatten-type)) ;
+: (flatten-stack-type) ( type -- seq )
+ (stack-value) ((flatten-type)) ;
GENERIC: flatten-value-type ( type -- types )
#! Moves values from C stack to registers (if word is
#! %load-param-reg) and registers to C stack (if word is
#! %save-param-reg).
- [ alien-parameters flatten-value-types ]
- [ '[ alloc-parameter _ execute ] ]
+ [ [ alien-parameters flatten-value-types ] [ abi>> ] bi ]
+ [ '[ _ alloc-parameter _ execute ] ]
bi* each-parameter ; inline
: reverse-each-parameter ( parameters quot -- )
dll-path compiling-word get no-such-library drop
] if ;
-: stdcall-mangle ( params -- symbols )
+: decorated-symbol ( params -- symbols )
[ function>> ] [ parameters>> parameter-offsets drop number>string ] bi
- [ drop ] [ "@" glue ] [ "@" glue "_" prepend ] 2tri
- 3array ;
+ {
+ [ drop ]
+ [ "@" glue ]
+ [ "@" glue "_" prepend ]
+ [ "@" glue "@" prepend ]
+ } 2cleave
+ 4array ;
: alien-invoke-dlsym ( params -- symbols dll )
- [ dup abi>> "stdcall" = [ stdcall-mangle ] [ function>> ] if ]
+ [ dup abi>> callee-cleanup? [ decorated-symbol ] [ function>> ] if ]
[ library>> load-library ]
bi 2dup check-dlsym ;
! Copyright (C) 2008, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: math kernel layouts system strings words quotations byte-arrays
-alien arrays literals sequences ;
+alien alien.syntax arrays literals sequences ;
IN: compiler.constants
! These constants must match vm/memory.h
: segment-end-offset ( -- n ) 2 bootstrap-cells ; inline
! Relocation classes
-CONSTANT: rc-absolute-cell 0
-CONSTANT: rc-absolute 1
-CONSTANT: rc-relative 2
-CONSTANT: rc-absolute-ppc-2/2 3
-CONSTANT: rc-absolute-ppc-2 4
-CONSTANT: rc-relative-ppc-2 5
-CONSTANT: rc-relative-ppc-3 6
-CONSTANT: rc-relative-arm-3 7
-CONSTANT: rc-indirect-arm 8
-CONSTANT: rc-indirect-arm-pc 9
-CONSTANT: rc-absolute-2 10
+C-ENUM: f
+ rc-absolute-cell
+ rc-absolute
+ rc-relative
+ rc-absolute-ppc-2/2
+ rc-absolute-ppc-2
+ rc-relative-ppc-2
+ rc-relative-ppc-3
+ rc-relative-arm-3
+ rc-indirect-arm
+ rc-indirect-arm-pc
+ rc-absolute-2
+ rc-absolute-1 ;
! Relocation types
-CONSTANT: rt-dlsym 0
-CONSTANT: rt-entry-point 1
-CONSTANT: rt-entry-point-pic 2
-CONSTANT: rt-entry-point-pic-tail 3
-CONSTANT: rt-here 4
-CONSTANT: rt-this 5
-CONSTANT: rt-literal 6
-CONSTANT: rt-untagged 7
-CONSTANT: rt-megamorphic-cache-hits 8
-CONSTANT: rt-vm 9
-CONSTANT: rt-cards-offset 10
-CONSTANT: rt-decks-offset 11
-CONSTANT: rt-exception-handler 12
+C-ENUM: f
+ rt-dlsym
+ rt-entry-point
+ rt-entry-point-pic
+ rt-entry-point-pic-tail
+ rt-here
+ rt-this
+ rt-literal
+ rt-untagged
+ rt-megamorphic-cache-hits
+ rt-vm
+ rt-cards-offset
+ rt-decks-offset
+ rt-exception-handler ;
: rc-absolute? ( n -- ? )
- ${ rc-absolute-ppc-2/2 rc-absolute-cell rc-absolute } member? ;
+ ${
+ rc-absolute-ppc-2/2
+ rc-absolute-cell
+ rc-absolute
+ rc-absolute-2
+ rc-absolute-1
+ } member? ;
USING: accessors alien alien.c-types alien.libraries
alien.syntax arrays classes.struct combinators
-compiler continuations effects io io.backend io.pathnames
-io.streams.string kernel math memory namespaces
-namespaces.private parser quotations sequences
-specialized-arrays stack-checker stack-checker.errors
-system threads tools.test words alien.complex concurrency.promises ;
+compiler continuations effects generalizations io
+io.backend io.pathnames io.streams.string kernel
+math memory namespaces namespaces.private parser
+quotations sequences specialized-arrays stack-checker
+stack-checker.errors system threads tools.test words
+alien.complex concurrency.promises ;
FROM: alien.c-types => float short ;
SPECIALIZED-ARRAY: float
SPECIALIZED-ARRAY: char
{ [ os unix? ] [ "libfactor-ffi-test.so" ] }
} cond append-path ;
-"f-cdecl" libfactor-ffi-tests-path "cdecl" add-library
+: mingw? ( -- ? ) os windows? vm-compiler "GCC" head? and ;
-"f-stdcall" libfactor-ffi-tests-path "stdcall" add-library
+"f-cdecl" libfactor-ffi-tests-path mingw? mingw cdecl ? add-library
+
+"f-stdcall" libfactor-ffi-tests-path stdcall add-library
+
+"f-fastcall" libfactor-ffi-tests-path fastcall add-library
>>
LIBRARY: f-cdecl
[ [ alien-indirect ] infer ] [ inference-error? ] must-fail-with
: indirect-test-1 ( ptr -- result )
- int { } "cdecl" alien-indirect ;
+ int { } cdecl alien-indirect ;
{ 1 1 } [ indirect-test-1 ] must-infer-as
[ 3 ] [ &: ffi_test_1 indirect-test-1 ] unit-test
: indirect-test-1' ( ptr -- )
- int { } "cdecl" alien-indirect drop ;
+ int { } cdecl alien-indirect drop ;
{ 1 0 } [ indirect-test-1' ] must-infer-as
[ -1 indirect-test-1 ] must-fail
: indirect-test-2 ( x y ptr -- result )
- int { int int } "cdecl" alien-indirect gc ;
+ int { int int } cdecl alien-indirect gc ;
{ 3 1 } [ indirect-test-2 ] must-infer-as
unit-test
: indirect-test-3 ( a b c d ptr -- result )
- int { int int int int } "stdcall" alien-indirect
+ int { int int int int } stdcall alien-indirect
gc ;
[ f ] [ "f-stdcall" load-library f = ] unit-test
-[ "stdcall" ] [ "f-stdcall" library abi>> ] unit-test
+[ stdcall ] [ "f-stdcall" library abi>> ] unit-test
: ffi_test_18 ( w x y z -- int )
int "f-stdcall" "ffi_test_18" { int int int int }
11 6 -7 ffi_test_19 [ x>> ] [ y>> ] [ z>> ] tri
] unit-test
+: multi_ffi_test_18 ( w x y z w' x' y' z' -- int int )
+ [ int "f-stdcall" "ffi_test_18" { int int int int } alien-invoke ]
+ 4 ndip
+ int "f-stdcall" "ffi_test_18" { int int int int } alien-invoke
+ gc ;
+
+[ 25 85 ] [ 2 3 4 5 6 7 8 9 multi_ffi_test_18 ] unit-test
+
FUNCTION: double ffi_test_6 float x float y ;
[ 6.0 ] [ 3.0 2.0 ffi_test_6 ] unit-test
[ "a" "b" ffi_test_6 ] must-fail
! Test callbacks
-: callback-1 ( -- callback ) void { } "cdecl" [ ] alien-callback ;
+: callback-1 ( -- callback ) void { } cdecl [ ] alien-callback ;
[ 0 1 ] [ [ callback-1 ] infer [ in>> length ] [ out>> length ] bi ] unit-test
[ t ] [ callback-1 alien? ] unit-test
-: callback_test_1 ( ptr -- ) void { } "cdecl" alien-indirect ;
+: callback_test_1 ( ptr -- ) void { } cdecl alien-indirect ;
[ ] [ callback-1 callback_test_1 ] unit-test
-: callback-2 ( -- callback ) void { } "cdecl" [ [ 5 throw ] ignore-errors ] alien-callback ;
+: callback-2 ( -- callback ) void { } cdecl [ [ 5 throw ] ignore-errors ] alien-callback ;
[ ] [ callback-2 callback_test_1 ] unit-test
-: callback-3 ( -- callback ) void { } "cdecl" [ 5 "x" set ] alien-callback ;
+: callback-3 ( -- callback ) void { } cdecl [ 5 "x" set ] alien-callback ;
[ t 3 5 ] [
[
] unit-test
: callback-5 ( -- callback )
- void { } "cdecl" [ gc ] alien-callback ;
+ void { } cdecl [ gc ] alien-callback ;
[ "testing" ] [
"testing" callback-5 callback_test_1
] unit-test
: callback-5b ( -- callback )
- void { } "cdecl" [ compact-gc ] alien-callback ;
+ void { } cdecl [ compact-gc ] alien-callback ;
[ "testing" ] [
"testing" callback-5b callback_test_1
] unit-test
: callback-6 ( -- callback )
- void { } "cdecl" [ [ continue ] callcc0 ] alien-callback ;
+ void { } cdecl [ [ continue ] callcc0 ] alien-callback ;
[ 1 2 3 ] [ callback-6 callback_test_1 1 2 3 ] unit-test
: callback-7 ( -- callback )
- void { } "cdecl" [ 1000000 sleep ] alien-callback ;
+ void { } cdecl [ 1000000 sleep ] alien-callback ;
[ 1 2 3 ] [ callback-7 callback_test_1 1 2 3 ] unit-test
[ f ] [ namespace global eq? ] unit-test
: callback-8 ( -- callback )
- void { } "cdecl" [ [ ] in-thread yield ] alien-callback ;
+ void { } cdecl [ [ ] in-thread yield ] alien-callback ;
[ ] [ callback-8 callback_test_1 ] unit-test
: callback-9 ( -- callback )
- int { int int int } "cdecl" [
+ int { int int int } cdecl [
+ + 1 +
] alien-callback ;
} cleave ;
: double-rect-callback ( -- alien )
- void { void* void* double-rect } "cdecl"
+ void { void* void* double-rect } cdecl
[ "example" set-global 2drop ] alien-callback ;
: double-rect-test ( arg callback -- arg' )
[ f f ] 2dip
- void { void* void* double-rect } "cdecl" alien-indirect
+ void { void* void* double-rect } cdecl alien-indirect
"example" get-global ;
[ 1.0 2.0 3.0 4.0 ]
] unit-test
: callback-10 ( -- callback )
- test_struct_14 { double double } "cdecl"
+ test_struct_14 { double double } cdecl
[
test_struct_14 <struct>
swap >>x2
] alien-callback ;
: callback-10-test ( x1 x2 callback -- result )
- test_struct_14 { double double } "cdecl" alien-indirect ;
+ test_struct_14 { double double } cdecl alien-indirect ;
[ 1.0 2.0 ] [
1.0 2.0 callback-10 callback-10-test
] unit-test
: callback-11 ( -- callback )
- test-struct-12 { int double } "cdecl"
+ test-struct-12 { int double } cdecl
[
test-struct-12 <struct>
swap >>x
] alien-callback ;
: callback-11-test ( x1 x2 callback -- result )
- test-struct-12 { int double } "cdecl" alien-indirect ;
+ test-struct-12 { int double } cdecl alien-indirect ;
[ 1 2.0 ] [
1 2.0 callback-11 callback-11-test
[ 1.0 2.0 ] [ 1.0 2.0 ffi_test_42 [ x>> ] [ y>> ] bi ] unit-test
: callback-12 ( -- callback )
- test_struct_15 { float float } "cdecl"
+ test_struct_15 { float float } cdecl
[
test_struct_15 <struct>
swap >>y
] alien-callback ;
: callback-12-test ( x1 x2 callback -- result )
- test_struct_15 { float float } "cdecl" alien-indirect ;
+ test_struct_15 { float float } cdecl alien-indirect ;
[ 1.0 2.0 ] [
1.0 2.0 callback-12 callback-12-test [ x>> ] [ y>> ] bi
[ 1.0 2 ] [ 1.0 2 ffi_test_43 [ x>> ] [ a>> ] bi ] unit-test
: callback-13 ( -- callback )
- test_struct_16 { float int } "cdecl"
+ test_struct_16 { float int } cdecl
[
test_struct_16 <struct>
swap >>a
] alien-callback ;
: callback-13-test ( x1 x2 callback -- result )
- test_struct_16 { float int } "cdecl" alien-indirect ;
+ test_struct_16 { float int } cdecl alien-indirect ;
[ 1.0 2 ] [
1.0 2 callback-13 callback-13-test
! Test interaction between threads and callbacks
: thread-callback-1 ( -- callback )
- int { } "cdecl" [ yield 100 ] alien-callback ;
+ int { } cdecl [ yield 100 ] alien-callback ;
: thread-callback-2 ( -- callback )
- int { } "cdecl" [ yield 200 ] alien-callback ;
+ int { } cdecl [ yield 200 ] alien-callback ;
: thread-callback-invoker ( callback -- n )
- int { } "cdecl" alien-indirect ;
+ int { } cdecl alien-indirect ;
<promise> "p" set
[ thread-callback-1 thread-callback-invoker "p" get fulfill ] in-thread
[ this_does_not_exist ] [ { "kernel-error" 9 f f } = ] must-fail-with
! More alien-assembly tests are in cpu.* vocabs
-: assembly-test-1 ( -- ) void { } "cdecl" [ ] alien-assembly ;
+: assembly-test-1 ( -- ) void { } cdecl [ ] alien-assembly ;
[ ] [ assembly-test-1 ] unit-test
+
+[ f ] [ "f-fastcall" load-library f = ] unit-test
+[ fastcall ] [ "f-fastcall" library abi>> ] unit-test
+
+: ffi_test_49 ( x -- int )
+ int "f-fastcall" "ffi_test_49" { int }
+ alien-invoke gc ;
+: ffi_test_50 ( x y -- int )
+ int "f-fastcall" "ffi_test_50" { int int }
+ alien-invoke gc ;
+: ffi_test_51 ( x y z -- int )
+ int "f-fastcall" "ffi_test_51" { int int int }
+ alien-invoke gc ;
+: multi_ffi_test_51 ( x y z x' y' z' -- int int )
+ [ int "f-fastcall" "ffi_test_51" { int int int } alien-invoke ]
+ 3dip
+ int "f-fastcall" "ffi_test_51" { int int int } alien-invoke gc ;
+
+[ 4 ] [ 3 ffi_test_49 ] unit-test
+[ 8 ] [ 3 4 ffi_test_50 ] unit-test
+[ 13 ] [ 3 4 5 ffi_test_51 ] unit-test
+[ 13 22 ] [ 3 4 5 6 7 8 multi_ffi_test_51 ] unit-test
+
+: ffi_test_52 ( x y z -- int )
+ int "f-fastcall" "ffi_test_52" { int float int }
+ alien-invoke gc ;
+: ffi_test_53 ( x y z w -- int )
+ int "f-fastcall" "ffi_test_53" { int float int int }
+ alien-invoke gc ;
+: ffi_test_57 ( x y -- test-struct-11 )
+ test-struct-11 "f-fastcall" "ffi_test_57" { int int }
+ alien-invoke gc ;
+: ffi_test_58 ( x y z -- test-struct-11 )
+ test-struct-11 "f-fastcall" "ffi_test_58" { int int int }
+ alien-invoke gc ;
+
+! GCC bugs
+mingw? [
+ [ 13 ] [ 3 4.0 5 ffi_test_52 ] unit-test
+
+ [ 19 ] [ 3 4.0 5 6 ffi_test_53 ] unit-test
+] unless
+
+[ S{ test-struct-11 f 7 -1 } ] [ 3 4 ffi_test_57 ] unit-test
+
+[ S{ test-struct-11 f 7 -3 } ] [ 3 4 7 ffi_test_58 ] unit-test
+
+: fastcall-ii-indirect ( x y ptr -- result )
+ int { int int } fastcall alien-indirect ;
+
+: fastcall-iii-indirect ( x y z ptr -- result )
+ int { int int int } fastcall alien-indirect ;
+
+: fastcall-ifi-indirect ( x y z ptr -- result )
+ int { int float int } fastcall alien-indirect ;
+
+: fastcall-ifii-indirect ( x y z w ptr -- result )
+ int { int float int int } fastcall alien-indirect ;
+
+: fastcall-struct-return-ii-indirect ( x y ptr -- result )
+ test-struct-11 { int int } fastcall alien-indirect ;
+
+: fastcall-struct-return-iii-indirect ( x y z ptr -- result )
+ test-struct-11 { int int int } fastcall alien-indirect ;
+
+: win32? ( -- ? ) os windows? cpu x86.32? and ;
+
+[ 8 ] [
+ 3 4
+ win32? [ &: @ffi_test_50@8 ] [ &: ffi_test_50 ] if
+ fastcall-ii-indirect
+] unit-test
+
+[ 13 ] [
+ 3 4 5
+ win32? [ &: @ffi_test_51@12 ] [ &: ffi_test_51 ] if
+ fastcall-iii-indirect
+] unit-test
+
+mingw? [
+ [ 13 ] [
+ 3 4.0 5
+ win32? [ &: @ffi_test_52@12 ] [ &: ffi_test_52 ] if
+ fastcall-ifi-indirect
+ ] unit-test
+
+ [ 19 ] [
+ 3 4.0 5 6
+ win32? [ &: @ffi_test_53@16 ] [ &: ffi_test_53 ] if
+ fastcall-ifii-indirect
+ ] unit-test
+] unless
+
+[ S{ test-struct-11 f 7 -1 } ]
+[
+ 3 4
+ win32? [ &: @ffi_test_57@8 ] [ &: ffi_test_57 ] if
+ fastcall-struct-return-ii-indirect
+] unit-test
+
+[ S{ test-struct-11 f 7 -3 } ]
+[
+ 3 4 7
+ win32? [ &: @ffi_test_58@12 ] [ &: ffi_test_58 ] if
+ fastcall-struct-return-iii-indirect
+] unit-test
+
+: fastcall-ii-callback ( -- ptr )
+ int { int int } fastcall [ + 1 + ] alien-callback ;
+
+: fastcall-iii-callback ( -- ptr )
+ int { int int int } fastcall [ + + 1 + ] alien-callback ;
+
+: fastcall-ifi-callback ( -- ptr )
+ int { int float int } fastcall
+ [ [ >integer ] dip + + 1 + ] alien-callback ;
+
+: fastcall-ifii-callback ( -- ptr )
+ int { int float int int } fastcall
+ [ [ >integer ] 2dip + + + 1 + ] alien-callback ;
+
+: fastcall-struct-return-ii-callback ( -- ptr )
+ test-struct-11 { int int } fastcall
+ [ [ + ] [ - ] 2bi test-struct-11 <struct-boa> ] alien-callback ;
+
+: fastcall-struct-return-iii-callback ( -- ptr )
+ test-struct-11 { int int int } fastcall
+ [ [ drop + ] [ - nip ] 3bi test-struct-11 <struct-boa> ] alien-callback ;
+
+[ 8 ] [ 3 4 fastcall-ii-callback fastcall-ii-indirect ] unit-test
+
+[ 13 ] [ 3 4 5 fastcall-iii-callback fastcall-iii-indirect ] unit-test
+
+[ 13 ] [ 3 4.0 5 fastcall-ifi-callback fastcall-ifi-indirect ] unit-test
+
+[ 19 ] [ 3 4.0 5 6 fastcall-ifii-callback fastcall-ifii-indirect ] unit-test
+
+[ S{ test-struct-11 f 7 -1 } ]
+[ 3 4 fastcall-struct-return-ii-callback fastcall-struct-return-ii-indirect ] unit-test
+
+[ S{ test-struct-11 f 7 -3 } ]
+[ 3 4 7 fastcall-struct-return-iii-callback fastcall-struct-return-iii-indirect ] unit-test
IN: compiler.tests.redefine23
USING: classes.struct specialized-arrays alien.c-types sequences
compiler.units vocabs tools.test ;
+FROM: specialized-arrays.private => specialized-array-vocab ;
STRUCT: my-struct { x int } ;
SPECIALIZED-ARRAY: my-struct
[ ] [
[
- "specialized-arrays.instances.compiler.tests.redefine23" forget-vocab
+ my-struct specialized-array-vocab forget-vocab
] with-compilation-unit
] unit-test
TYPEDEF: alien.c-types:int type-3
: callback ( -- ptr )
- type-3 { type-1 type-1 } "cdecl" [ + >integer ] alien-callback ;
+ type-3 { type-1 type-1 } cdecl [ + >integer ] alien-callback ;
TYPEDEF: alien.c-types:float type-2
: indirect ( x y ptr -- z )
- type-3 { type-2 type-2 } "cdecl" alien-indirect ;
+ type-3 { type-2 type-2 } cdecl alien-indirect ;
[ ] [
"USING: alien.c-types alien.syntax ;
-! Copyright (C) 2008, 2009 Slava Pestov.
+! Copyright (C) 2008, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
-USING: fry kernel sequences assocs accessors namespaces
+USING: fry kernel sequences assocs accessors
math.intervals arrays classes.algebra combinators columns
-stack-checker.branches locals math
+stack-checker.branches locals math namespaces
compiler.utilities
compiler.tree
compiler.tree.combinators
compiler.tree.propagation.nodes
compiler.tree.propagation.simple
compiler.tree.propagation.constraints ;
+FROM: sets => union ;
+FROM: assocs => change-at ;
IN: compiler.tree.propagation.branches
! For conditionals, an assoc of child node # --> constraint
bi ;
:: update-constraints ( new old -- )
- new [| key value | key old [ value append ] change-at ] assoc-each ;
+ new [| key value | key old [ value union ] change-at ] assoc-each ;
: include-child-constraints ( i -- )
infer-children-data get nth constraints swap at last
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: arrays assocs math math.intervals kernel accessors
sequences namespaces classes classes.algebra
C: --> implication
+: maybe-add ( elt seq -- seq' )
+ 2dup member? [ nip ] [ swap suffix ] if ;
+
: assume-implication ( q p -- )
- [ constraints get [ assoc-stack swap suffix ] 2keep last set-at ]
+ [ constraints get [ assoc-stack maybe-add ] 2keep last set-at ]
[ satisfied? [ assume ] [ drop ] if ] 2bi ;
M: implication assume*
{ [ os winnt? ] [ "zlib1.dll" ] }
{ [ os macosx? ] [ "libz.dylib" ] }
{ [ os unix? ] [ "libz.so" ] }
-} cond "cdecl" add-library >>
+} cond cdecl add-library >>
LIBRARY: zlib
[ fds>> [ enable-all-callbacks ] each ] bi ;
: timer-callback ( -- callback )
- void { CFRunLoopTimerRef void* } "cdecl"
+ void { CFRunLoopTimerRef void* } cdecl
[ 2drop reset-run-loop yield ] alien-callback ;
: init-thread-timer ( -- )
opengl.gl literals ;
IN: core-graphics
-! CGImageAlphaInfo
-C-ENUM:
+C-ENUM: CGImageAlphaInfo
kCGImageAlphaNone
kCGImageAlphaPremultipliedLast
kCGImageAlphaPremultipliedFirst
GENERIC: return-reg ( reg-class -- reg )
! Sequence of registers used for parameter passing in class
-GENERIC: param-regs ( reg-class -- regs )
+GENERIC# param-regs 1 ( reg-class abi -- regs )
-M: stack-params param-regs drop f ;
+M: stack-params param-regs 2drop f ;
-GENERIC: param-reg ( n reg-class -- reg )
+GENERIC# param-reg 1 ( n reg-class abi -- reg )
M: reg-class param-reg param-regs nth ;
-M: stack-params param-reg drop ;
+M: stack-params param-reg 2drop ;
! Is this integer small enough to be an immediate operand for
! %add-imm, %sub-imm, and %mul-imm?
! %and-imm, %or-imm, and %xor-imm?
HOOK: immediate-bitwise? cpu ( n -- ? )
+! What c-type describes the implicit struct return pointer for large structs?
+HOOK: struct-return-pointer-type cpu ( -- c-type )
+
! Is this structure small enough to be returned in registers?
HOOK: return-struct-in-registers? cpu ( c-type -- ? )
HOOK: %end-callback-value cpu ( c-type -- )
-HOOK: callback-return-rewind cpu ( params -- n )
+HOOK: stack-cleanup cpu ( params -- n )
-M: object callback-return-rewind drop 0 ;
+M: object stack-cleanup drop 0 ;
4 ds-reg 0 LWZ rc-absolute-ppc-2 rt-untagged jit-rel\r
] pic-load jit-define\r
\r
-! Tag\r
-: load-tag ( -- )\r
- 4 4 tag-mask get ANDI\r
- 4 4 tag-bits get SLWI ;\r
-\r
-[ load-tag ] pic-tag jit-define\r
+[ 4 4 tag-mask get ANDI ] pic-tag jit-define\r
\r
-! Tuple\r
[\r
3 4 MR\r
- load-tag\r
- 0 4 tuple type-number tag-fixnum CMPI\r
+ 4 4 tag-mask get ANDI\r
+ 0 4 tuple type-number CMPI\r
[ BNE ]\r
- [ 4 3 tuple type-number neg 4 + LWZ ]\r
+ [ 4 3 tuple-class-offset LWZ ]\r
jit-conditional*\r
] pic-tuple jit-define\r
\r
[\r
- 0 4 0 CMPI rc-absolute-ppc-2 rt-literal jit-rel\r
+ 0 4 0 CMPI rc-absolute-ppc-2 rt-untagged jit-rel\r
] pic-check-tag jit-define\r
\r
[\r
! ! ! Megamorphic caches\r
\r
[\r
+ ! class = ...\r
+ 3 4 MR\r
+ 4 4 tag-mask get ANDI\r
+ 4 4 tag-bits get SLWI\r
+ 0 4 tuple type-number tag-fixnum CMPI\r
+ [ BNE ]\r
+ [ 4 3 tuple-class-offset LWZ ]\r
+ jit-conditional*\r
! cache = ...\r
0 3 LOAD32 rc-absolute-ppc-2/2 rt-literal jit-rel\r
! key = hashcode(class)\r
M: linux lr-save 1 cells ;
-M: float-regs param-regs drop { 1 2 3 4 5 6 7 8 } ;
+M: float-regs param-regs 2drop { 1 2 3 4 5 6 7 8 } ;
M: ppc value-struct? drop f ;
M: macosx lr-save 2 cells ;
-M: float-regs param-regs drop { 1 2 3 4 5 6 7 8 9 10 11 12 13 } ;
+M: float-regs param-regs 2drop { 1 2 3 4 5 6 7 8 9 10 11 12 13 } ;
M: ppc value-struct? drop t ;
M: integer float-function-param* FMR ;
: float-function-param ( i src -- )
- [ float-regs param-regs nth ] dip float-function-param* ;
+ [ float-regs cdecl param-regs nth ] dip float-function-param* ;
: float-function-return ( reg -- )
float-regs return-reg double-rep %copy ;
M: ppc %loop-entry ;
M: int-regs return-reg drop 3 ;
-M: int-regs param-regs drop { 3 4 5 6 7 8 9 10 } ;
+M: int-regs param-regs 2drop { 3 4 5 6 7 8 9 10 } ;
M: float-regs return-reg drop 1 ;
M:: ppc %save-param-reg ( stack reg rep -- )
! If the source is a stack location, load it into freg #0.
! If the source is f, then we assume the value is already in
! freg #0.
- n [ 0 rep reg-class-of param-reg rep %load-param-reg ] when*
+ n [ 0 rep reg-class-of cdecl param-reg rep %load-param-reg ] when*
rep double-rep? 5 4 ? %load-vm-addr
func f %alien-invoke ;
M: ppc immediate-bitwise? ( n -- ? ) 0 65535 between? ;
+M: ppc struct-return-pointer-type void* ;
+
M: ppc return-struct-in-registers? ( c-type -- ? )
c-type return-in-registers?>> ;
compiler
-untested
+not loaded
USING: alien alien.c-types tools.test cpu.x86.assembler
cpu.x86.assembler.operands ;
-: assembly-test-1 ( -- x ) int { } "cdecl" [ EAX 3 MOV ] alien-assembly ;
+: assembly-test-1 ( -- x ) int { } cdecl [ EAX 3 MOV ] alien-assembly ;
[ 3 ] [ assembly-test-1 ] unit-test
! Copyright (C) 2005, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
-USING: locals alien.c-types alien.libraries alien.syntax arrays
-kernel fry math namespaces sequences system layouts io
-vocabs.loader accessors init combinators command-line make
-compiler compiler.units compiler.constants compiler.alien
+USING: locals alien alien.c-types alien.libraries alien.syntax
+arrays kernel fry math namespaces sequences system layouts io
+vocabs.loader accessors init classes.struct combinators command-line
+make compiler compiler.units compiler.constants compiler.alien
compiler.codegen compiler.codegen.fixup
compiler.cfg.instructions compiler.cfg.builder
compiler.cfg.intrinsics compiler.cfg.stack-frame
[ align-code ]
bi ;
-M: x86.32 pic-tail-reg EBX ;
+M: x86.32 pic-tail-reg EDX ;
-M: x86.32 reserved-stack-space 4 cells ;
+M: x86.32 reserved-stack-space 0 ;
M: x86.32 %alien-invoke 0 CALL rc-relative rel-dlsym ;
: struct-return@ ( n -- operand )
[ next-stack@ ] [ stack-frame get params>> local@ ] if* ;
-! On x86, parameters are never passed in registers.
+! On x86, parameters are usually never passed in registers, except with Microsoft's
+! "thiscall" and "fastcall" abis
M: int-regs return-reg drop EAX ;
-M: int-regs param-regs drop { } ;
-M: float-regs param-regs drop { } ;
+M: float-regs param-regs 2drop { } ;
+
+M: int-regs param-regs
+ nip {
+ { thiscall [ { ECX } ] }
+ { fastcall [ { ECX EDX } ] }
+ [ drop { } ]
+ } case ;
GENERIC: load-return-reg ( src rep -- )
GENERIC: store-return-reg ( dst rep -- )
+M: stack-params load-return-reg drop EAX swap MOV ;
+M: stack-params store-return-reg drop EAX MOV ;
+
M: int-rep load-return-reg drop EAX swap MOV ;
M: int-rep store-return-reg drop EAX MOV ;
M: x86.32 %prepare-jump
pic-tail-reg 0 MOV xt-tail-pic-offset rc-absolute-cell rel-here ;
-M: x86.32 %load-param-reg
- stack-params assert=
- [ [ EAX ] dip local@ MOV ] dip
- stack@ EAX MOV ;
+M: stack-params copy-register*
+ drop
+ {
+ { [ dup integer? ] [ EAX swap next-stack@ MOV EAX MOV ] }
+ { [ over integer? ] [ EAX swap MOV param@ EAX MOV ] }
+ } cond ;
-M: x86.32 %save-param-reg 3drop ;
+M: x86.32 %save-param-reg [ local@ ] 2dip %copy ;
+
+M: x86.32 %load-param-reg [ swap local@ ] dip %copy ;
: (%box) ( n rep -- )
#! If n is f, push the return register onto the stack; we
#! are boxing a return value of a C function. If n is an
#! integer, push [ESP+n] on the stack; we are boxing a
#! parameter being passed to a callback from C.
- over [ [ next-stack@ ] dip load-return-reg ] [ 2drop ] if ;
+ over [ [ local@ ] dip load-return-reg ] [ 2drop ] if ;
M:: x86.32 %box ( n rep func -- )
n rep (%box)
func "libm" load-library %alien-invoke
dst float-function-return ;
-: stdcall? ( params -- ? )
- abi>> "stdcall" = ;
-
: funny-large-struct-return? ( params -- ? )
#! MINGW ABI incompatibility disaster
[ return>> large-struct? ]
- [ abi>> "mingw" = os windows? not or ]
+ [ abi>> mingw = os windows? not or ]
bi and ;
-M: x86.32 %cleanup ( params -- )
- #! a) If we just called an stdcall function in Windows, it
- #! cleaned up the stack frame for us. But we don't want that
- #! so we 'undo' the cleanup since we do that in %epilogue.
- #! b) If we just called a function returning a struct, we
- #! have to fix ESP.
+: stack-arg-size ( params -- n )
+ dup abi>> '[
+ alien-parameters flatten-value-types
+ [ _ alloc-parameter 2drop ] each
+ stack-params get
+ ] with-param-regs ;
+
+M: x86.32 stack-cleanup ( params -- n )
+ #! a) Functions which are stdcall/fastcall/thiscall have to
+ #! clean up the caller's stack frame.
+ #! b) Functions returning large structs on MINGW have to
+ #! fix ESP.
{
- { [ dup stdcall? ] [ drop ESP stack-frame get params>> SUB ] }
- { [ dup funny-large-struct-return? ] [ drop EAX PUSH ] }
- [ drop ]
+ { [ dup abi>> callee-cleanup? ] [ stack-arg-size ] }
+ { [ dup funny-large-struct-return? ] [ drop 4 ] }
+ [ drop 0 ]
} cond ;
+M: x86.32 %cleanup ( params -- )
+ stack-cleanup [ ESP swap SUB ] unless-zero ;
+
M:: x86.32 %call-gc ( gc-root-count temp -- )
temp gc-root-base special@ LEA
8 save-vm-ptr
M: x86.32 dummy-fp-params? f ;
-M: x86.32 callback-return-rewind ( params -- n )
- #! a) If the callback is stdcall, we have to clean up the
- #! caller's stack frame.
- #! b) If the callback is returning a large struct, we have
- #! to fix ESP.
- {
- { [ dup stdcall? ] [ <alien-stack-frame> [ params>> ] [ return>> ] bi + ] }
- { [ dup funny-large-struct-return? ] [ drop 4 ] }
- [ drop 0 ]
- } cond ;
-
! Dreadful
-M: object flatten-value-type (flatten-int-type) ;
+M: object flatten-value-type (flatten-stack-type) ;
+M: struct-c-type flatten-value-type (flatten-stack-type) ;
+M: long-long-type flatten-value-type (flatten-stack-type) ;
+M: c-type flatten-value-type
+ dup rep>> int-rep? [ (flatten-int-type) ] [ (flatten-stack-type) ] if ;
+
+M: x86.32 struct-return-pointer-type
+ os linux? void* (stack-value) ? ;
check-sse
: div-arg ( -- reg ) EAX ;
: mod-arg ( -- reg ) EDX ;
: temp0 ( -- reg ) EAX ;
-: temp1 ( -- reg ) EDX ;
-: temp2 ( -- reg ) ECX ;
-: temp3 ( -- reg ) EBX ;
+: temp1 ( -- reg ) ECX ;
+: temp2 ( -- reg ) EBX ;
+: temp3 ( -- reg ) EDX ;
+: pic-tail-reg ( -- reg ) EDX ;
: stack-reg ( -- reg ) ESP ;
: frame-reg ( -- reg ) EBP ;
-: vm-reg ( -- reg ) ECX ;
+: vm-reg ( -- reg ) EBX ;
: ctx-reg ( -- reg ) EBP ;
: nv-regs ( -- seq ) { ESI EDI EBX } ;
-: nv-reg ( -- reg ) EBX ;
+: nv-reg ( -- reg ) ESI ;
: ds-reg ( -- reg ) ESI ;
: rs-reg ( -- reg ) EDI ;
: fixnum>slot@ ( -- ) temp0 2 SAR ;
] jit-prolog jit-define
[
- temp3 0 MOV rc-absolute-cell rt-here jit-rel
+ pic-tail-reg 0 MOV rc-absolute-cell rt-here jit-rel
0 JMP rc-relative rt-entry-point-pic-tail jit-rel
] jit-word-jump jit-define
: jit-save-context ( -- )
jit-load-context
- EDX ESP -4 [+] LEA
- ctx-reg context-callstack-top-offset [+] EDX MOV
+ ECX ESP -4 [+] LEA
+ ctx-reg context-callstack-top-offset [+] ECX MOV
ctx-reg context-datastack-offset [+] ds-reg MOV
ctx-reg context-retainstack-offset [+] rs-reg MOV ;
[
! Load callstack object
- EBX ds-reg [] MOV
+ temp3 ds-reg [] MOV
ds-reg bootstrap-cell SUB
! Get ctx->callstack_bottom
jit-load-vm
jit-load-context
- EAX ctx-reg context-callstack-bottom-offset [+] MOV
+ temp0 ctx-reg context-callstack-bottom-offset [+] MOV
! Get top of callstack object -- 'src' for memcpy
- EBP EBX callstack-top-offset [+] LEA
+ temp1 temp3 callstack-top-offset [+] LEA
! Get callstack length, in bytes --- 'len' for memcpy
- EDX EBX callstack-length-offset [+] MOV
- EDX tag-bits get SHR
+ temp2 temp3 callstack-length-offset [+] MOV
+ temp2 tag-bits get SHR
! Compute new stack pointer -- 'dst' for memcpy
- EAX EDX SUB
+ temp0 temp2 SUB
! Install new stack pointer
- ESP EAX MOV
+ ESP temp0 MOV
! Call memcpy
- EDX PUSH
- EBP PUSH
- EAX PUSH
+ temp2 PUSH
+ temp1 PUSH
+ temp0 PUSH
"factor_memcpy" jit-call
ESP 12 ADD
! Return with new callstack
[ jit-jump-quot ]
\ lazy-jit-compile define-combinator-primitive
+[
+ temp1 HEX: ffffffff CMP rc-absolute-cell rt-literal jit-rel
+] pic-check-tuple jit-define
+
! Inline cache miss entry points
: jit-load-return-address ( -- )
- EBX ESP stack-frame-size bootstrap-cell - [+] MOV ;
+ pic-tail-reg ESP stack-frame-size bootstrap-cell - [+] MOV ;
! These are always in tail position with an existing stack
! frame, and the stack. The frame setup takes this into account.
jit-load-vm
jit-save-context
ESP 4 [+] vm-reg MOV
- ESP [] EBX MOV
+ ESP [] pic-tail-reg MOV
"inline_cache_miss" jit-call
jit-restore-context ;
[
ESP [] EAX MOV
ESP 4 [+] EDX MOV
+ jit-load-vm
ESP 8 [+] vm-reg MOV
jit-call
]
EBX tag-bits get SAR
ESP [] EBX MOV
ESP 4 [+] EBP MOV
+ jit-load-vm
ESP 8 [+] vm-reg MOV
"overflow_fixnum_multiply" jit-call
]
! Load context and parameter from datastack
EAX ds-reg [] MOV
EAX EAX alien-offset [+] MOV
- EBX ds-reg -4 [+] MOV
+ EDX ds-reg -4 [+] MOV
ds-reg 8 SUB
! Make the new context active
! Store parameter to datastack
ds-reg 4 ADD
- ds-reg [] EBX MOV ;
+ ds-reg [] EDX MOV ;
[ jit-set-context ] \ (set-context) define-sub-primitive
"new_context" jit-call
! Save pointer to quotation and parameter
- EBX ds-reg MOV
+ EDX ds-reg MOV
ds-reg 8 SUB
! Make the new context active
EAX jit-switch-context
! Push parameter
- EAX EBX -4 [+] MOV
+ EAX EDX -4 [+] MOV
ds-reg 4 ADD
ds-reg [] EAX MOV
0 PUSH
! Jump to initial quotation
- EAX EBX [] MOV
+ EAX EDX [] MOV
jit-jump-quot ;
[ jit-start-context ] \ (start-context) define-sub-primitive
jit-delete-current-context
jit-start-context
] \ (start-context-and-delete) define-sub-primitive
-
-<< "vocab:cpu/x86/bootstrap.factor" parse-file suffix! >>
-call
-untested
+not loaded
compiler
! Copyright (C) 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
-USING: cpu.x86.assembler cpu.x86.assembler.operands kernel
-layouts parser sequences ;
+USING: kernel parser sequences ;
IN: bootstrap.x86
-: jit-save-tib ( -- ) ;
-: jit-restore-tib ( -- ) ;
-: jit-update-tib ( ctx-reg -- ) drop ;
-: jit-install-seh ( -- ) ESP bootstrap-cell ADD ;
-: jit-update-seh ( ctx-reg -- ) drop ;
-
-<< "vocab:cpu/x86/32/bootstrap.factor" parse-file suffix! >>
-call
+<< "vocab:cpu/x86/unix/bootstrap.factor" parse-file suffix! >> call
+<< "vocab:cpu/x86/32/bootstrap.factor" parse-file suffix! >> call
+<< "vocab:cpu/x86/bootstrap.factor" parse-file suffix! >> call
locals parser sequences ;
IN: bootstrap.x86
-: tib-exception-list-offset ( -- n ) 0 bootstrap-cells ;
-: tib-stack-base-offset ( -- n ) 1 bootstrap-cells ;
-: tib-stack-limit-offset ( -- n ) 2 bootstrap-cells ;
+: tib-segment ( -- ) FS ;
+: tib-temp ( -- reg ) EAX ;
-: jit-save-tib ( -- )
- tib-exception-list-offset [] FS PUSH
- tib-stack-base-offset [] FS PUSH
- tib-stack-limit-offset [] FS PUSH ;
-
-: jit-restore-tib ( -- )
- tib-stack-limit-offset [] FS POP
- tib-stack-base-offset [] FS POP
- tib-exception-list-offset [] FS POP ;
-
-:: jit-update-tib ( ctx-reg -- )
- ! There's a redundant load here because we're not allowed
- ! to clobber ctx-reg. Clobbers EAX.
- ! Save callstack base in TIB
- EAX ctx-reg context-callstack-seg-offset [+] MOV
- EAX EAX segment-end-offset [+] MOV
- tib-stack-base-offset [] EAX FS MOV
- ! Save callstack limit in TIB
- EAX ctx-reg context-callstack-seg-offset [+] MOV
- EAX EAX segment-start-offset [+] MOV
- tib-stack-limit-offset [] EAX FS MOV ;
+<< "vocab:cpu/x86/winnt/bootstrap.factor" parse-file suffix! >> call
: jit-install-seh ( -- )
! Create a new exception record and store it in the TIB.
+ ! Clobbers tib-temp.
! Align stack
ESP 3 bootstrap-cells ADD
! Exception handler address filled in by callback.cpp
- 0 PUSH rc-absolute-cell rt-exception-handler jit-rel
+ tib-temp 0 MOV rc-absolute-cell rt-exception-handler jit-rel
+ tib-temp PUSH
! No next handler
0 PUSH
! This is the new exception handler
- tib-exception-list-offset [] ESP FS MOV ;
+ tib-exception-list-offset [] ESP tib-segment MOV ;
:: jit-update-seh ( ctx-reg -- )
! Load exception record structure that jit-install-seh
- ! created from the bottom of the callstack. Clobbers EAX.
- EAX ctx-reg context-callstack-bottom-offset [+] MOV
- EAX bootstrap-cell ADD
+ ! created from the bottom of the callstack.
+ ! Clobbers tib-temp.
+ tib-temp ctx-reg context-callstack-bottom-offset [+] MOV
+ tib-temp bootstrap-cell ADD
! Store exception record in TIB.
- tib-exception-list-offset [] EAX FS MOV ;
+ tib-exception-list-offset [] tib-temp tib-segment MOV ;
-<< "vocab:cpu/x86/32/bootstrap.factor" parse-file suffix! >>
-call
+<< "vocab:cpu/x86/32/bootstrap.factor" parse-file suffix! >> call
+<< "vocab:cpu/x86/bootstrap.factor" parse-file suffix! >> call
cpu.x86.assembler cpu.x86.assembler.operands tools.test ;
IN: cpu.x86.64.tests
-: assembly-test-1 ( -- x ) int { } "cdecl" [ RAX 3 MOV ] alien-assembly ;
+: assembly-test-1 ( -- x ) int { } cdecl [ RAX 3 MOV ] alien-assembly ;
[ 3 ] [ assembly-test-1 ] unit-test
: assembly-test-2 ( a b -- x )
- int { int int } "cdecl" [
+ int { int int } cdecl [
param-reg-0 param-reg-1 ADD
int-regs return-reg param-reg-0 MOV
] alien-assembly ;
FROM: layouts => cell cells ;
IN: cpu.x86.64
-: param-reg-0 ( -- reg ) 0 int-regs param-reg ; inline
-: param-reg-1 ( -- reg ) 1 int-regs param-reg ; inline
-: param-reg-2 ( -- reg ) 2 int-regs param-reg ; inline
-: param-reg-3 ( -- reg ) 3 int-regs param-reg ; inline
+: param-reg-0 ( -- reg ) 0 int-regs cdecl param-reg ; inline
+: param-reg-1 ( -- reg ) 1 int-regs cdecl param-reg ; inline
+: param-reg-2 ( -- reg ) 2 int-regs cdecl param-reg ; inline
+: param-reg-3 ( -- reg ) 3 int-regs cdecl param-reg ; inline
M: x86.64 pic-tail-reg RBX ;
M: x86.64 %vm-field-ptr ( dst offset -- )
[ vm-reg ] dip [+] LEA ;
-: param@ ( n -- op ) reserved-stack-space + stack@ ;
-
M: x86.64 %prologue ( n -- )
temp-reg -7 [RIP+] LEA
dup PUSH
"to_value_struct" f %alien-invoke ;
: load-return-value ( rep -- )
- [ [ 0 ] dip reg-class-of param-reg ]
+ [ [ 0 ] dip reg-class-of cdecl param-reg ]
[ reg-class-of return-reg ]
[ ]
tri %copy ;
M:: x86.64 %box ( n rep func -- )
n [
n
- 0 rep reg-class-of param-reg
+ 0 rep reg-class-of cdecl param-reg
rep %load-param-reg
] [
rep load-return-value
unbox-return ;
: float-function-param ( i src -- )
- [ float-regs param-regs nth ] dip double-rep %copy ;
+ [ float-regs cdecl param-regs nth ] dip double-rep %copy ;
: float-function-return ( reg -- )
float-regs return-reg double-rep %copy ;
! Call GC
"inline_gc" f %alien-invoke ;
+M: x86.64 struct-return-pointer-type void* ;
+
! The result of reading 4 bytes from memory is a fixnum on
! x86-64.
enable-alien-4-intrinsics
: shift-arg ( -- reg ) RCX ;
: div-arg ( -- reg ) RAX ;
: mod-arg ( -- reg ) RDX ;
-: temp0 ( -- reg ) RDI ;
-: temp1 ( -- reg ) RSI ;
+: temp0 ( -- reg ) RAX ;
+: temp1 ( -- reg ) RCX ;
: temp2 ( -- reg ) RDX ;
: temp3 ( -- reg ) RBX ;
+: pic-tail-reg ( -- reg ) RBX ;
: return-reg ( -- reg ) RAX ;
: nv-reg ( -- reg ) RBX ;
: stack-reg ( -- reg ) RSP ;
: fixnum>slot@ ( -- ) temp0 1 SAR ;
: rex-length ( -- n ) 1 ;
-: jit-save-tib ( -- ) ;
-: jit-restore-tib ( -- ) ;
-: jit-update-tib ( ctx-reg -- ) drop ;
-: jit-install-seh ( -- ) stack-reg bootstrap-cell ADD ;
-
: jit-call ( name -- )
RAX 0 MOV rc-absolute-cell jit-dlsym
RAX CALL ;
] jit-prolog jit-define
[
- temp3 5 [RIP+] LEA
+ pic-tail-reg 5 [RIP+] LEA
0 JMP rc-relative rt-entry-point-pic-tail jit-rel
] jit-word-jump jit-define
[ jit-jump-quot ]
\ lazy-jit-compile define-combinator-primitive
+[
+ temp2 HEX: ffffffff MOV rc-absolute-cell rt-literal jit-rel
+ temp1 temp2 CMP
+] pic-check-tuple jit-define
+
! Inline cache miss entry points
: jit-load-return-address ( -- )
RBX RSP stack-frame-size bootstrap-cell - [+] MOV ;
RSP ctx-reg context-callstack-top-offset [+] MOV
! Load new ds, rs registers
- jit-restore-context ;
+ jit-restore-context
+
+ ctx-reg jit-update-tib ;
: jit-pop-context-and-param ( -- )
arg1 ds-reg [] MOV
jit-delete-current-context
jit-start-context
] \ (start-context-and-delete) define-sub-primitive
-
-<< "vocab:cpu/x86/bootstrap.factor" parse-file suffix! >>
-call
-untested
+not loaded
compiler
: arg3 ( -- reg ) RDX ;
: arg4 ( -- reg ) RCX ;
-<< "vocab:cpu/x86/64/bootstrap.factor" parse-file suffix! >>
-call
+<< "vocab:cpu/x86/unix/bootstrap.factor" parse-file suffix! >> call
+<< "vocab:cpu/x86/64/bootstrap.factor" parse-file suffix! >> call
+<< "vocab:cpu/x86/bootstrap.factor" parse-file suffix! >> call
IN: cpu.x86.64.unix
M: int-regs param-regs
- drop { RDI RSI RDX RCX R8 R9 } ;
+ 2drop { RDI RSI RDX RCX R8 R9 } ;
M: float-regs param-regs
- drop { XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 } ;
+ 2drop { XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 } ;
M: x86.64 reserved-stack-space 0 ;
-SYMBOL: (stack-value)
-! The ABI for passing structs by value is pretty great
-<< void* c-type clone \ (stack-value) define-primitive-type
-stack-params \ (stack-value) c-type (>>rep) >>
-
: struct-types&offset ( struct-type -- pairs )
fields>> [
[ type>> ] [ offset>> ] bi 2array
] map ;
: flatten-large-struct ( c-type -- seq )
- heap-size cell align
- cell /i \ (stack-value) c-type <repetition> ;
+ (flatten-stack-type) ;
: flatten-struct ( c-type -- seq )
dup heap-size 16 > [
cpu.x86.assembler.operands ;
IN: bootstrap.x86
+DEFER: stack-reg
+
: stack-frame-size ( -- n ) 8 bootstrap-cells ;
: nv-regs ( -- seq ) { RBX RSI RDI R12 R13 R14 R15 } ;
: arg1 ( -- reg ) RCX ;
: arg3 ( -- reg ) R8 ;
: arg4 ( -- reg ) R9 ;
-<< "vocab:cpu/x86/64/bootstrap.factor" parse-file suffix! >>
-call
+: tib-segment ( -- ) GS ;
+: tib-temp ( -- reg ) R11 ;
+
+: jit-install-seh ( -- ) stack-reg bootstrap-cell ADD ;
+: jit-update-seh ( ctx-reg -- ) drop ;
+
+<< "vocab:cpu/x86/winnt/bootstrap.factor" parse-file suffix! >> call
+<< "vocab:cpu/x86/64/bootstrap.factor" parse-file suffix! >> call
+<< "vocab:cpu/x86/bootstrap.factor" parse-file suffix! >> call
cpu.x86.assembler.operands ;
IN: cpu.x86.64.winnt
-M: int-regs param-regs drop { RCX RDX R8 R9 } ;
+M: int-regs param-regs 2drop { RCX RDX R8 R9 } ;
-M: float-regs param-regs drop { XMM0 XMM1 XMM2 XMM3 } ;
+M: float-regs param-regs 2drop { XMM0 XMM1 XMM2 XMM3 } ;
M: x86.64 reserved-stack-space 4 cells ;
[
! Optimizing compiler's side of callback accesses
! arguments that are on the stack via the frame pointer.
- ! On x86-64, some arguments are passed in registers, and
- ! so the only register that is safe for use here is nv-reg.
+ ! On x86-32 fastcall, and x86-64, some arguments are passed
+ ! in registers, and so the only registers that are safe for
+ ! use here are frame-reg, nv-reg and vm-reg.
frame-reg PUSH
frame-reg stack-reg MOV
frame-reg POP
- ! Callbacks which return structs, or use stdcall, need a
- ! parameter here. See the comment in callback-return-rewind
- ! in cpu.x86.32
+ ! Callbacks which return structs, or use stdcall/fastcall/thiscall,
+ ! need a parameter here.
+
+ ! See the comment for M\ x86.32 stack-cleanup in cpu.x86.32
HEX: ffff RET rc-absolute-2 rt-untagged jit-rel
] callback-stub jit-define
[
! Load word
- nv-reg 0 MOV rc-absolute-cell rt-literal jit-rel
+ temp0 0 MOV rc-absolute-cell rt-literal jit-rel
! Bump profiling counter
- nv-reg profile-count-offset [+] 1 tag-fixnum ADD
+ temp0 profile-count-offset [+] 1 tag-fixnum ADD
! Load word->code
- nv-reg nv-reg word-code-offset [+] MOV
+ temp0 temp0 word-code-offset [+] MOV
! Compute word entry point
- nv-reg compiled-header-size ADD
+ temp0 compiled-header-size ADD
! Jump to entry point
- nv-reg JMP
+ temp0 JMP
] jit-profiling jit-define
[
! ! ! Polymorphic inline caches
-! The PIC stubs are not permitted to touch temp3.
+! The PIC stubs are not permitted to touch pic-tail-reg.
! Load a value from a stack position
[
- temp1 ds-reg HEX: ffffffff [+] MOV rc-absolute rt-untagged jit-rel
+ temp1 ds-reg HEX: 7f [+] MOV rc-absolute-1 rt-untagged jit-rel
] pic-load jit-define
-! Tag
-: load-tag ( -- )
- temp1 tag-mask get AND
- temp1 tag-bits get SHL ;
-
-[ load-tag ] pic-tag jit-define
-
-! The 'make' trick lets us compute the jump distance for the
-! conditional branches there
+[ temp1 tag-mask get AND ] pic-tag jit-define
-! Tuple
[
temp0 temp1 MOV
- load-tag
- temp1 tuple type-number tag-fixnum CMP
+ temp1 tag-mask get AND
+ temp1 tuple type-number CMP
[ JNE ]
- [ temp1 temp0 tuple type-number neg bootstrap-cell + [+] MOV ]
+ [ temp1 temp0 tuple-class-offset [+] MOV ]
jit-conditional
] pic-tuple jit-define
[
- temp1 HEX: ffffffff CMP rc-absolute rt-literal jit-rel
+ temp1 HEX: 7f CMP rc-absolute-1 rt-untagged jit-rel
] pic-check-tag jit-define
-[
- temp2 HEX: ffffffff MOV rc-absolute-cell rt-literal jit-rel
- temp1 temp2 CMP
-] pic-check-tuple jit-define
-
[ 0 JE rc-relative rt-entry-point jit-rel ] pic-hit jit-define
! ! ! Megamorphic caches
[
+ ! class = ...
+ temp0 temp1 MOV
+ temp1 tag-mask get AND
+ temp1 tag-bits get SHL
+ temp1 tuple type-number tag-fixnum CMP
+ [ JNE ]
+ [ temp1 temp0 tuple-class-offset [+] MOV ]
+ jit-conditional
! cache = ...
temp0 0 MOV rc-absolute-cell rt-literal jit-rel
! key = hashcode(class)
temp0 temp2 ADD
! if(get(cache) == class)
temp0 [] temp1 CMP
- bootstrap-cell 4 = 14 22 ? JNE ! Yuck!
- ! megamorphic_cache_hits++
- temp1 0 MOV rc-absolute-cell rt-megamorphic-cache-hits jit-rel
- temp1 [] 1 ADD
- ! goto get(cache + bootstrap-cell)
- temp0 temp0 bootstrap-cell [+] MOV
- temp0 word-entry-point-offset [+] JMP
- ! fall-through on miss
+ [ JNE ]
+ [
+ ! megamorphic_cache_hits++
+ temp1 0 MOV rc-absolute-cell rt-megamorphic-cache-hits jit-rel
+ temp1 [] 1 ADD
+ ! goto get(cache + bootstrap-cell)
+ temp0 temp0 bootstrap-cell [+] MOV
+ temp0 word-entry-point-offset [+] JMP
+ ! fall-through on miss
+ ] jit-conditional
] mega-lookup jit-define
! ! ! Sub-primitives
! load value
temp3 ds-reg [] MOV
! make a copy
- temp1 temp3 MOV
- ! compute positive shift value in temp1
- temp1 CL SHL
+ temp2 temp3 MOV
+ ! compute positive shift value in temp2
+ temp2 CL SHL
shift-arg NEG
! compute negative shift value in temp3
temp3 CL SAR
temp3 tag-mask get bitnot AND
shift-arg 0 CMP
- ! if shift count was negative, move temp0 to temp1
- temp1 temp3 CMOVGE
+ ! if shift count was negative, move temp0 to temp2
+ temp2 temp3 CMOVGE
! push to stack
- ds-reg [] temp1 MOV
+ ds-reg [] temp2 MOV
] \ fixnum-shift-fast define-sub-primitive
: jit-fixnum-/mod ( -- )
! load second parameter
- temp3 ds-reg [] MOV
+ temp1 ds-reg [] MOV
! load first parameter
div-arg ds-reg bootstrap-cell neg [+] MOV
! make a copy
! sign-extend
mod-arg bootstrap-cell-bits 1 - SAR
! divide
- temp3 IDIV ;
+ temp1 IDIV ;
[
jit-fixnum-/mod
<PRIVATE
: (sse-version) ( -- n )
- int { } "cdecl" [
+ int { } cdecl [
"sse-42" define-label
"sse-41" define-label
"ssse-3" define-label
HOOK: instruction-count cpu ( -- n )
M: x86.32 instruction-count
- longlong { } "cdecl" [
+ longlong { } cdecl [
RDTSC
] alien-assembly ;
M: x86.64 instruction-count
- longlong { } "cdecl" [
+ longlong { } cdecl [
RAX 0 MOV
RDTSC
RDX 32 SHL
-untested
+not loaded
compiler
--- /dev/null
+! Copyright (C) 2010 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: cpu.x86.assembler cpu.x86.assembler.operands kernel
+layouts ;
+IN: bootstrap.x86
+
+DEFER: stack-reg
+
+: jit-save-tib ( -- ) ;
+: jit-restore-tib ( -- ) ;
+: jit-update-tib ( ctx-reg -- ) drop ;
+: jit-install-seh ( -- ) stack-reg bootstrap-cell ADD ;
+: jit-update-seh ( ctx-reg -- ) drop ;
--- /dev/null
+! Copyright (C) 2010 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: bootstrap.image.private compiler.constants
+cpu.x86.assembler cpu.x86.assembler.operands kernel layouts
+locals parser sequences ;
+IN: bootstrap.x86
+
+: tib-exception-list-offset ( -- n ) 0 bootstrap-cells ;
+: tib-stack-base-offset ( -- n ) 1 bootstrap-cells ;
+: tib-stack-limit-offset ( -- n ) 2 bootstrap-cells ;
+
+: jit-save-tib ( -- )
+ tib-exception-list-offset [] tib-segment PUSH
+ tib-stack-base-offset [] tib-segment PUSH
+ tib-stack-limit-offset [] tib-segment PUSH ;
+
+: jit-restore-tib ( -- )
+ tib-stack-limit-offset [] tib-segment POP
+ tib-stack-base-offset [] tib-segment POP
+ tib-exception-list-offset [] tib-segment POP ;
+
+:: jit-update-tib ( ctx-reg -- )
+ ! There's a redundant load here because we're not allowed
+ ! to clobber ctx-reg. Clobbers tib-temp.
+ ! Save callstack base in TIB
+ tib-temp ctx-reg context-callstack-seg-offset [+] MOV
+ tib-temp tib-temp segment-end-offset [+] MOV
+ tib-stack-base-offset [] tib-temp tib-segment MOV
+ ! Save callstack limit in TIB
+ tib-temp ctx-reg context-callstack-seg-offset [+] MOV
+ tib-temp tib-temp segment-start-offset [+] MOV
+ tib-stack-limit-offset [] tib-temp tib-segment MOV ;
: gc-root@ ( n -- op ) gc-root-offset special@ ;
+: param@ ( n -- op ) reserved-stack-space + stack@ ;
+
: decr-stack-reg ( n -- )
dup 0 = [ drop ] [ stack-reg swap SUB ] if ;
{ [ os winnt? ] [ "libpq.dll" ] }
{ [ os macosx? ] [ "libpq.dylib" ] }
{ [ os unix? ] [ "libpq.so" ] }
-} cond "cdecl" add-library >>
+} cond cdecl add-library >>
! ConnSatusType
CONSTANT: CONNECTION_OK HEX: 0
{ [ os winnt? ] [ "sqlite3.dll" ] }
{ [ os macosx? ] [ "/usr/lib/libsqlite3.dylib" ] }
{ [ os unix? ] [ "libsqlite3.so" ] }
- } cond "cdecl" add-library >>
+ } cond cdecl add-library >>
! Return values from sqlite functions
CONSTANT: SQLITE_OK 0 ! Successful result
FUNCTION: int sqlite3_bind_int ( sqlite3_stmt* pStmt, int index, int n ) ;
FUNCTION: int sqlite3_bind_int64 ( sqlite3_stmt* pStmt, int index, sqlite3_int64 n ) ;
! Bind the same function as above, but for unsigned 64bit integers
-: sqlite3-bind-uint64 ( pStmt index in64 -- int )
- int "sqlite" "sqlite3_bind_int64"
- { pointer: sqlite3_stmt int sqlite3_uint64 } alien-invoke ;
+FUNCTION-ALIAS: sqlite3-bind-uint64
+ int sqlite3_bind_int64 ( sqlite3_stmt* pStmt, int index, sqlite3_uint64 in64 ) ;
FUNCTION: int sqlite3_bind_null ( sqlite3_stmt* pStmt, int n ) ;
FUNCTION: int sqlite3_bind_text ( sqlite3_stmt* pStmt, int index, c-string text, int len, int destructor ) ;
FUNCTION: int sqlite3_bind_parameter_index ( sqlite3_stmt* pStmt, c-string name ) ;
FUNCTION: int sqlite3_column_int ( sqlite3_stmt* pStmt, int col ) ;
FUNCTION: sqlite3_int64 sqlite3_column_int64 ( sqlite3_stmt* pStmt, int col ) ;
! Bind the same function as above, but for unsigned 64bit integers
-: sqlite3-column-uint64 ( pStmt col -- uint64 )
- sqlite3_uint64 "sqlite" "sqlite3_column_int64"
- { pointer: sqlite3_stmt int } alien-invoke ;
+FUNCTION-ALIAS: sqlite3-column-uint64
+ sqlite3_uint64 sqlite3_column_int64 ( sqlite3_stmt* pStmt, int col ) ;
FUNCTION: double sqlite3_column_double ( sqlite3_stmt* pStmt, int col ) ;
FUNCTION: c-string sqlite3_column_name ( sqlite3_stmt* pStmt, int col ) ;
FUNCTION: c-string sqlite3_column_text ( sqlite3_stmt* pStmt, int col ) ;
M: no-word-error summary
name>>
- "No word named ``"
- "'' found in current vocabulary search path" surround ;
+ "No word named “"
+ "” found in current vocabulary search path" surround ;
M: no-word-error error. summary print ;
M: no-word-in-vocab summary
[ vocab>> ] [ word>> ] bi
- [ "No word named ``" % % "'' found in ``" % % "'' vocabulary" % ] "" make ;
+ [ "No word named “" % % "” found in “" % % "” vocabulary" % ] "" make ;
M: no-word-in-vocab error. summary print ;
M: ambiguous-use-error summary
words>> first name>>
- "More than one vocabulary defines a word named ``" "''" surround ;
+ "More than one vocabulary defines a word named “" "”" surround ;
M: ambiguous-use-error error. summary print ;
M: not-in-a-method-error summary
drop "call-next-method can only be called in a method definition" ;
+M: version-control-merge-conflict summary
+ drop "Version control merge conflict in source code" ;
+
GENERIC: expected>string ( obj -- str )
M: f expected>string drop "end of input" ;
"USING: formatting ;"
"1.23456789 \"%.3f\" printf"
"1.235" }
- { $example
- "USING: formatting ;"
- "1234567890 \"%.5e\" printf"
- "1.23457e+09" }
{ $example
"USING: formatting ;"
"12 \"%'#4d\" printf"
! Copyright (C) 2008 John Benediktsson
! See http://factorcode.org/license.txt for BSD license
-USING: calendar kernel formatting tools.test ;
+USING: calendar kernel formatting tools.test system ;
IN: formatting.tests
[ "%s" printf ] must-infer
[ "%s" sprintf ] must-infer
-[ t ] [ "" "" sprintf = ] unit-test
-[ t ] [ "asdf" "asdf" sprintf = ] unit-test
-[ t ] [ "10" 10 "%d" sprintf = ] unit-test
-[ t ] [ "+10" 10 "%+d" sprintf = ] unit-test
-[ t ] [ "-10" -10 "%d" sprintf = ] unit-test
-[ t ] [ " -10" -10 "%5d" sprintf = ] unit-test
-[ t ] [ "-0010" -10 "%05d" sprintf = ] unit-test
-[ t ] [ "+0010" 10 "%+05d" sprintf = ] unit-test
-[ t ] [ "123.456000" 123.456 "%f" sprintf = ] unit-test
-[ t ] [ "2.44" 2.436 "%.2f" sprintf = ] unit-test
-[ t ] [ "123.10" 123.1 "%01.2f" sprintf = ] unit-test
-[ t ] [ "1.2346" 1.23456789 "%.4f" sprintf = ] unit-test
-[ t ] [ " 1.23" 1.23456789 "%6.2f" sprintf = ] unit-test
-[ t ] [ "1.234000e+08" 123400000 "%e" sprintf = ] unit-test
-[ t ] [ "-1.234000e+08" -123400000 "%e" sprintf = ] unit-test
-[ t ] [ "1.234567e+08" 123456700 "%e" sprintf = ] unit-test
-[ t ] [ "3.625e+08" 362525200 "%.3e" sprintf = ] unit-test
-[ t ] [ "2.500000e-03" 0.0025 "%e" sprintf = ] unit-test
-[ t ] [ "2.500000E-03" 0.0025 "%E" sprintf = ] unit-test
-[ t ] [ " 1.0E+01" 10 "%10.1E" sprintf = ] unit-test
-[ t ] [ " -1.0E+01" -10 "%10.1E" sprintf = ] unit-test
-[ t ] [ " -1.0E+01" -10 "%+10.1E" sprintf = ] unit-test
-[ t ] [ " +1.0E+01" 10 "%+10.1E" sprintf = ] unit-test
-[ t ] [ "-001.0E+01" -10 "%+010.1E" sprintf = ] unit-test
-[ t ] [ "+001.0E+01" 10 "%+010.1E" sprintf = ] unit-test
-[ t ] [ "ff" HEX: ff "%x" sprintf = ] unit-test
-[ t ] [ "FF" HEX: ff "%X" sprintf = ] unit-test
-[ t ] [ "0f" HEX: f "%02x" sprintf = ] unit-test
-[ t ] [ "0F" HEX: f "%02X" sprintf = ] unit-test
-[ t ] [ "2008-09-10"
- 2008 9 10 "%04d-%02d-%02d" sprintf = ] unit-test
-[ t ] [ "Hello, World!"
- "Hello, World!" "%s" sprintf = ] unit-test
-[ t ] [ "printf test"
- "printf test" sprintf = ] unit-test
-[ t ] [ "char a = 'a'"
- CHAR: a "char %c = 'a'" sprintf = ] unit-test
-[ t ] [ "00" HEX: 0 "%02x" sprintf = ] unit-test
-[ t ] [ "ff" HEX: ff "%02x" sprintf = ] unit-test
-[ t ] [ "0 message(s)"
- 0 "message" "%d %s(s)" sprintf = ] unit-test
-[ t ] [ "0 message(s) with %"
- 0 "message" "%d %s(s) with %%" sprintf = ] unit-test
-[ t ] [ "justif: \"left \""
- "left" "justif: \"%-10s\"" sprintf = ] unit-test
-[ t ] [ "justif: \" right\""
- "right" "justif: \"%10s\"" sprintf = ] unit-test
-[ t ] [ " 3: 0003 zero padded"
- 3 " 3: %04d zero padded" sprintf = ] unit-test
-[ t ] [ " 3: 3 left justif"
- 3 " 3: %-4d left justif" sprintf = ] unit-test
-[ t ] [ " 3: 3 right justif"
- 3 " 3: %4d right justif" sprintf = ] unit-test
-[ t ] [ " -3: -003 zero padded"
- -3 " -3: %04d zero padded" sprintf = ] unit-test
-[ t ] [ " -3: -3 left justif"
- -3 " -3: %-4d left justif" sprintf = ] unit-test
-[ t ] [ " -3: -3 right justif"
- -3 " -3: %4d right justif" sprintf = ] unit-test
-[ t ] [ "There are 10 monkeys in the kitchen"
- 10 "kitchen" "There are %d monkeys in the %s" sprintf = ] unit-test
-[ f ] [ "%d" 10 "%d" sprintf = ] unit-test
-[ t ] [ "[monkey]" "monkey" "[%s]" sprintf = ] unit-test
-[ t ] [ "[ monkey]" "monkey" "[%10s]" sprintf = ] unit-test
-[ t ] [ "[monkey ]" "monkey" "[%-10s]" sprintf = ] unit-test
-[ t ] [ "[0000monkey]" "monkey" "[%010s]" sprintf = ] unit-test
-[ t ] [ "[####monkey]" "monkey" "[%'#10s]" sprintf = ] unit-test
-[ t ] [ "[many monke]" "many monkeys" "[%10.10s]" sprintf = ] unit-test
+[ "" ] [ "" sprintf ] unit-test
+[ "asdf" ] [ "asdf" sprintf ] unit-test
+[ "10" ] [ 10 "%d" sprintf ] unit-test
+[ "+10" ] [ 10 "%+d" sprintf ] unit-test
+[ "-10" ] [ -10 "%d" sprintf ] unit-test
+[ " -10" ] [ -10 "%5d" sprintf ] unit-test
+[ "-0010" ] [ -10 "%05d" sprintf ] unit-test
+[ "+0010" ] [ 10 "%+05d" sprintf ] unit-test
+[ "123.456000" ] [ 123.456 "%f" sprintf ] unit-test
+[ "2.44" ] [ 2.436 "%.2f" sprintf ] unit-test
+[ "8.950" ] [ 8.950179003580072 "%.3f" sprintf ] unit-test
+[ "123.10" ] [ 123.1 "%01.2f" sprintf ] unit-test
+[ "1.2346" ] [ 1.23456789 "%.4f" sprintf ] unit-test
+[ " 1.23" ] [ 1.23456789 "%6.2f" sprintf ] unit-test
-[ t ] [ "{ 1, 2, 3 }" { 1 2 3 } "%[%s, %]" sprintf = ] unit-test
-[ t ] [ "{ 1:2, 3:4 }" H{ { 1 2 } { 3 4 } } "%[%s: %s %]" sprintf = ] unit-test
+os windows? [
+ [ "1.234000e+008" ] [ 123400000 "%e" sprintf ] unit-test
+ [ "-1.234000e+008" ] [ -123400000 "%e" sprintf ] unit-test
+ [ "1.234567e+008" ] [ 123456700 "%e" sprintf ] unit-test
+ [ "3.625e+008" ] [ 362525200 "%.3e" sprintf ] unit-test
+ [ "2.500000e-003" ] [ 0.0025 "%e" sprintf ] unit-test
+ [ "2.500000E-003" ] [ 0.0025 "%E" sprintf ] unit-test
+ [ " 1.0E+001" ] [ 10 "%11.1E" sprintf ] unit-test
+ [ " -1.0E+001" ] [ -10 "%11.1E" sprintf ] unit-test
+ [ " -1.0E+001" ] [ -10 "%+11.1E" sprintf ] unit-test
+ [ " +1.0E+001" ] [ 10 "%+11.1E" sprintf ] unit-test
+ [ "-001.0E+001" ] [ -10 "%+011.1E" sprintf ] unit-test
+ [ "+001.0E+001" ] [ 10 "%+011.1E" sprintf ] unit-test
+] [
+ [ "1.234000e+08" ] [ 123400000 "%e" sprintf ] unit-test
+ [ "-1.234000e+08" ] [ -123400000 "%e" sprintf ] unit-test
+ [ "1.234567e+08" ] [ 123456700 "%e" sprintf ] unit-test
+ [ "3.625e+08" ] [ 362525200 "%.3e" sprintf ] unit-test
+ [ "2.500000e-03" ] [ 0.0025 "%e" sprintf ] unit-test
+ [ "2.500000E-03" ] [ 0.0025 "%E" sprintf ] unit-test
+ [ " 1.0E+01" ] [ 10 "%10.1E" sprintf ] unit-test
+ [ " -1.0E+01" ] [ -10 "%10.1E" sprintf ] unit-test
+ [ " -1.0E+01" ] [ -10 "%+10.1E" sprintf ] unit-test
+ [ " +1.0E+01" ] [ 10 "%+10.1E" sprintf ] unit-test
+ [ "-001.0E+01" ] [ -10 "%+010.1E" sprintf ] unit-test
+ [ "+001.0E+01" ] [ 10 "%+010.1E" sprintf ] unit-test
+] if
+
+[ "ff" ] [ HEX: ff "%x" sprintf ] unit-test
+[ "FF" ] [ HEX: ff "%X" sprintf ] unit-test
+[ "0f" ] [ HEX: f "%02x" sprintf ] unit-test
+[ "0F" ] [ HEX: f "%02X" sprintf ] unit-test
+[ "2008-09-10" ] [ 2008 9 10 "%04d-%02d-%02d" sprintf ] unit-test
+[ "Hello, World!" ] [ "Hello, World!" "%s" sprintf ] unit-test
+[ "printf test" ] [ "printf test" sprintf ] unit-test
+[ "char a = 'a'" ] [ CHAR: a "char %c = 'a'" sprintf ] unit-test
+[ "00" ] [ HEX: 0 "%02x" sprintf ] unit-test
+[ "ff" ] [ HEX: ff "%02x" sprintf ] unit-test
+[ "0 message(s)" ] [ 0 "message" "%d %s(s)" sprintf ] unit-test
+[ "0 message(s) with %" ] [ 0 "message" "%d %s(s) with %%" sprintf ] unit-test
+[ "justif: \"left \"" ] [ "left" "justif: \"%-10s\"" sprintf ] unit-test
+[ "justif: \" right\"" ] [ "right" "justif: \"%10s\"" sprintf ] unit-test
+[ " 3: 0003 zero padded" ] [ 3 " 3: %04d zero padded" sprintf ] unit-test
+[ " 3: 3 left justif" ] [ 3 " 3: %-4d left justif" sprintf ] unit-test
+[ " 3: 3 right justif" ] [ 3 " 3: %4d right justif" sprintf ] unit-test
+[ " -3: -003 zero padded" ] [ -3 " -3: %04d zero padded" sprintf ] unit-test
+[ " -3: -3 left justif" ] [ -3 " -3: %-4d left justif" sprintf ] unit-test
+[ " -3: -3 right justif" ] [ -3 " -3: %4d right justif" sprintf ] unit-test
+[ "There are 10 monkeys in the kitchen" ] [ 10 "kitchen" "There are %d monkeys in the %s" sprintf ] unit-test
+[ "10" ] [ 10 "%d" sprintf ] unit-test
+[ "[monkey]" ] [ "monkey" "[%s]" sprintf ] unit-test
+[ "[ monkey]" ] [ "monkey" "[%10s]" sprintf ] unit-test
+[ "[monkey ]" ] [ "monkey" "[%-10s]" sprintf ] unit-test
+[ "[0000monkey]" ] [ "monkey" "[%010s]" sprintf ] unit-test
+[ "[####monkey]" ] [ "monkey" "[%'#10s]" sprintf ] unit-test
+[ "[many monke]" ] [ "many monkeys" "[%10.10s]" sprintf ] unit-test
+
+[ "{ 1, 2, 3 }" ] [ { 1 2 3 } "%[%s, %]" sprintf ] unit-test
+[ "{ 1:2, 3:4 }" ] [ H{ { 1 2 } { 3 4 } } "%[%s: %s %]" sprintf ] unit-test
[ "%H:%M:%S" strftime ] must-infer
[ t ] [ "October" testtime "%B" strftime = ] unit-test
[ t ] [ "Thu Oct 09 12:03:15 2008" testtime "%c" strftime = ] unit-test
[ t ] [ "PM" testtime "%p" strftime = ] unit-test
-
-
USING: accessors arrays assocs calendar combinators fry kernel
generalizations io io.streams.string macros math math.functions
math.parser peg.ebnf quotations sequences splitting strings
-unicode.categories unicode.case vectors combinators.smart ;
+unicode.categories unicode.case vectors combinators.smart
+present ;
+FROM: math.parser.private => format-float ;
IN: formatting
<PRIVATE
: >digits ( string -- digits )
[ 0 ] [ string>number ] if-empty ;
-: pad-digits ( string digits -- string' )
- [ "." split1 ] dip [ CHAR: 0 pad-tail ] [ head-slice ] bi "." glue ;
+: format-simple ( x digits string -- string )
+ [ [ >float ] [ number>string ] bi* "%." ] dip
+ surround format-float ;
-: max-digits ( n digits -- n' )
- 10^ [ * round ] keep / ; inline
+: format-scientific ( x digits -- string ) "e" format-simple ;
-: >exp ( x -- exp base )
- [
- abs 0 swap
- [ dup [ 10.0 >= ] [ 1.0 < ] bi or ]
- [ dup 10.0 >=
- [ 10.0 / [ 1 + ] dip ]
- [ 10.0 * [ 1 - ] dip ] if
- ] while
- ] keep 0 < [ neg ] when ;
-
-: exp>string ( exp base digits -- string )
- [ max-digits ] keep -rot
- [
- [ 0 < "-" "+" ? ]
- [ abs number>string 2 CHAR: 0 pad-head ] bi
- "e" -rot 3append
- ]
- [ number>string ] bi*
- rot pad-digits prepend ;
+: format-decimal ( x digits -- string ) "f" format-simple ;
+
+ERROR: unknown-printf-directive ;
EBNF: parse-printf
fmt-% = "%" => [[ [ "%" ] ]]
fmt-c = "c" => [[ [ 1string ] ]]
fmt-C = "C" => [[ [ 1string >upper ] ]]
-fmt-s = "s" => [[ [ dup number? [ number>string ] when ] ]]
-fmt-S = "S" => [[ [ dup number? [ number>string ] when >upper ] ]]
-fmt-d = "d" => [[ [ >fixnum number>string ] ]]
-fmt-e = digits "e" => [[ first '[ >exp _ exp>string ] ]]
-fmt-E = digits "E" => [[ first '[ >exp _ exp>string >upper ] ]]
-fmt-f = digits "f" => [[ first dup '[ >float _ max-digits number>string _ pad-digits ] ]]
+fmt-s = "s" => [[ [ present ] ]]
+fmt-S = "S" => [[ [ present >upper ] ]]
+fmt-d = "d" => [[ [ >integer number>string ] ]]
+fmt-e = digits "e" => [[ first '[ _ format-scientific ] ]]
+fmt-E = digits "E" => [[ first '[ _ format-scientific >upper ] ]]
+fmt-f = digits "f" => [[ first '[ _ format-decimal ] ]]
fmt-x = "x" => [[ [ >hex ] ]]
fmt-X = "X" => [[ [ >hex >upper ] ]]
-unknown = (.)* => [[ "Unknown directive" throw ]]
+unknown = (.)* => [[ unknown-printf-directive ]]
strings_ = fmt-c|fmt-C|fmt-s|fmt-S
strings = pad width strings_ => [[ reverse compose-all ]]
{ $description "Constructs a subclass of " { $link action } "." } ;
HELP: page-action
-{ $class-description "The class of Chloe page actions. These are actions whose " { $slot "display" } " slot is pre-set to serve the Chloe template stored in the " { $slot "page" } " slot." } ;
+{ $class-description "The class of Chloe page actions. These are actions whose " { $slot "display" } " slot is pre-set to serve the Chloe template stored in the " { $slot "template" } " slot. The " { $slot "template" } " slot contains a pair with shape " { $snippet "{ responder name }" } "." } ;
HELP: validate-integer-id
{ $description "A utility word which validates an integer parameter named " { $snippet "id" } "." }
! Copyright (C) 2010 Erik Charlebois, William Schlieper.
! See http://factorcode.org/license.txt for BSD license.
-USING: arrays kernel game.input namespaces
+USING: accessors alien.c-types arrays kernel game.input namespaces math
classes bit-arrays system sequences vectors x11 x11.xlib ;
IN: game.input.x11
M: x11-game-input-backend read-keyboard
dpy get 256 <bit-array> [ XQueryKeymap drop ] keep
x-bits>hid-bits keyboard-state boa ;
+
+: query-pointer ( -- x y buttons )
+ dpy get dup XDefaultRootWindow
+ 0 <int> 0 <int> 0 <int> 0 <int> 0 <int> 0 <int> 0 <int>
+ [ XQueryPointer drop ] 3keep
+ [ *int ] tri@ ;
+
+SYMBOL: mouse-reset?
M: x11-game-input-backend read-mouse
- 0 0 0 0 2 <vector> mouse-state boa ;
+ mouse-reset? get [ reset-mouse ] unless
+ query-pointer
+ mouse-state new
+ swap 256 /i >>buttons
+ swap 400 - >>dy
+ swap 400 - >>dx
+ 0 >>scroll-dy 0 >>scroll-dx ;
M: x11-game-input-backend reset-mouse
- ;
+ dpy get dup XDefaultRootWindow dup
+ 0 0 0 0 400 400 XWarpPointer drop t mouse-reset? set-global ;
<<
{
- { [ os winnt? ] [ "glib" "libglib-2.0-0.dll" "cdecl" add-library ] }
- { [ os macosx? ] [ "glib" "/opt/local/lib/libglib-2.0.0.dylib" "cdecl" add-library ] }
+ { [ os winnt? ] [ "glib" "libglib-2.0-0.dll" cdecl add-library ] }
+ { [ os macosx? ] [ "glib" "/opt/local/lib/libglib-2.0.0.dylib" cdecl add-library ] }
{ [ os unix? ] [ ] }
} cond
{
- { [ os winnt? ] [ "gobject" "libgobject-2.0-0.dll" "cdecl" add-library ] }
- { [ os macosx? ] [ "gobject" "/opt/local/lib/libgobject-2.0.0.dylib" "cdecl" add-library ] }
+ { [ os winnt? ] [ "gobject" "libgobject-2.0-0.dll" cdecl add-library ] }
+ { [ os macosx? ] [ "gobject" "/opt/local/lib/libgobject-2.0.0.dylib" cdecl add-library ] }
{ [ os unix? ] [ ] }
} cond
{ $class-description "Text area components display a multi-line editor for a string value. The " { $slot "rows" } " and " { $slot "cols" } " properties determine the size of the text area." } ;
HELP: link
-{ $description "Link components render a link to an object stored at a value, with the link title and URL determined by the " { $link link-title } " and " { $link link-href } " generic words. The optional " { $slot "target" } " slot is a target frame to open the link in." } ;
+{ $description "Link components render a value responding to the " { $link link-title } " and " { $link link-href } " generic words. The optional " { $slot "target" } " slot is a target frame to open the link in." } ;
HELP: link-title
{ $values { "obj" object } { "string" string } }
-! Copyright (C) 2008, 2009 Slava Pestov, Daniel Ehrenberg
+! Copyright (C) 2008, 2010 Slava Pestov, Daniel Ehrenberg
! See http://factorcode.org/license.txt for BSD license.
USING: accessors kernel namespaces io math.parser assocs classes
classes.tuple words arrays sequences splitting mirrors
M: url link-title ;
M: url link-href ;
+TUPLE: simple-link title href ;
+
+C: <simple-link> simple-link
+
+M: simple-link link-title title>> ;
+M: simple-link link-href href>> ;
+
TUPLE: link target ;
M: link render*
{ $description "Calls the quotation and wraps any output it compiles in a " { $link with-scope } " form." } ;
ARTICLE: "html.templates.chloe.tags.component" "Component Chloe tags"
-"The following Chloe tags correspond exactly to " { $link "html.components" } ". Singleton component tags do not allow any attributes. Attributes of tuple component tags are mapped to tuple slot values of the component instance."
+"The following Chloe tags correspond exactly to " { $link "html.components" } ". The " { $snippet "name" } " attribute should be the name of a form value (see " { $link "html.forms.values" } "). Singleton component tags do not allow any other attributes. Tuple component tags map all other attributes to tuple slot values of the component instance."
{ $table
{ "Tag" "Component class" }
{ { $snippet "t:checkbox" } { $link checkbox } }
--- /dev/null
+Erik Charlebois
--- /dev/null
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: images.testing ;
+IN: images.pbm.tests
+
+"vocab:images/testing/pbm/test.binary.pbm" decode-test
+"vocab:images/testing/pbm/test.ascii.pbm" decode-test
--- /dev/null
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays ascii bit-arrays byte-arrays combinators
+continuations grouping images images.loader io io.encodings.ascii
+io.encodings.string kernel locals make math math.functions math.parser
+sequences ;
+IN: images.pbm
+
+SINGLETON: pbm-image
+"pbm" pbm-image register-image-class
+
+<PRIVATE
+: read-token ( -- token )
+ [
+ read1 dup blank?
+ [ t ]
+ [
+ dup CHAR: # =
+ [ "\n" read-until 2drop t ]
+ [ f ] if
+ ] if
+ ] [ drop ] while
+ " \n\r\t" read-until drop swap
+ prefix ascii decode ;
+
+: read-number ( -- number )
+ read-token string>number ;
+
+: read-ascii-bits ( -- )
+ read1 {
+ { CHAR: 1 [ 0 , read-ascii-bits ] }
+ { CHAR: 0 [ 255 , read-ascii-bits ] }
+ { f [ ] }
+ [ drop read-ascii-bits ]
+ } case ;
+
+:: read-binary-bits ( width height -- )
+ width 8 align 8 / height * read
+ width 8 align 8 / <groups> [| row |
+ width iota [| n |
+ n 8 / floor row nth
+ n 8 mod 7 swap - bit?
+ [ 0 ] [ 255 ] if ,
+ ] each
+ ] each ;
+
+:: write-binary-bits ( bitmap width -- )
+ bitmap width <groups> [
+ width 8 align 255 pad-tail
+ 8 <groups> [
+ [ 255 = [ f ] [ t ] if ] { } map-as
+ >bit-array reverse bit-array>integer
+ 1array >byte-array write
+ ] each
+ ] each ;
+
+:: read-pbm ( -- image )
+ read-token :> type
+ read-number :> width
+ read-number :> height
+
+ type {
+ { "P1" [ [ [ read-ascii-bits ] ignore-errors ] B{ } make ] }
+ { "P4" [ [ width height read-binary-bits ] B{ } make ] }
+ } case :> data
+
+ image new
+ L >>component-order
+ { width height } >>dim
+ f >>upside-down?
+ data >>bitmap
+ ubyte-components >>component-type ;
+PRIVATE>
+
+M: pbm-image stream>image
+ drop [ read-pbm ] with-input-stream ;
+
+M: pbm-image image>stream
+ drop {
+ [ drop "P4\n" ascii encode write ]
+ [ dim>> first number>string " " append ascii encode write ]
+ [ dim>> second number>string "\n" append ascii encode write ]
+ [ [ bitmap>> ] [ dim>> first ] bi write-binary-bits ]
+ } cleave ;
--- /dev/null
+Image loading for PBM image files.
--- /dev/null
+Erik Charlebois
--- /dev/null
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: images.testing ;
+IN: images.pgm.tests
+
+"vocab:images/testing/pgm/radial.binary.pgm" decode-test
+"vocab:images/testing/pgm/radial.ascii.pgm" decode-test
--- /dev/null
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors alien.c-types ascii combinators images images.loader
+io io.encodings.ascii io.encodings.string kernel locals make math
+math.parser sequences specialized-arrays ;
+SPECIALIZED-ARRAY: ushort
+IN: images.pgm
+
+SINGLETON: pgm-image
+"pgm" pgm-image register-image-class
+
+: read-token ( -- token )
+ [ read1 dup blank?
+ [ t ]
+ [ dup CHAR: # =
+ [ "\n" read-until 2drop t ]
+ [ f ] if
+ ] if
+ ] [ drop ] while
+ " \n\r\t" read-until drop swap
+ prefix ascii decode ;
+
+: read-number ( -- number )
+ read-token string>number ;
+
+:: read-numbers ( n lim -- )
+ n lim = [
+ read-number ,
+ n 1 + lim read-numbers
+ ] unless ;
+
+:: read-pgm ( -- image )
+ read-token :> type
+ read-number :> width
+ read-number :> height
+ read-number :> max
+ width height * :> npixels
+ max 256 >= :> wide
+
+ type {
+ { "P2" [ [ 0 npixels read-numbers ] wide [ ushort-array{ } ] [ B{ } ] if make ] }
+ { "P5" [ wide [ 2 ] [ 1 ] if npixels * read ] }
+ } case :> data
+
+ image new
+ L >>component-order
+ { width height } >>dim
+ f >>upside-down?
+ data >>bitmap
+ wide [ ushort-components ] [ ubyte-components ] if >>component-type ;
+
+M: pgm-image stream>image
+ drop [ read-pgm ] with-input-stream ;
+
+M: pgm-image image>stream
+ drop {
+ [ drop "P5\n" ascii encode write ]
+ [ dim>> first number>string " " append ascii encode write ]
+ [ dim>> second number>string "\n" append ascii encode write ]
+ [ component-type>> ubyte-components = [ "255\n" ] [ "65535\n" ] if ascii encode write ]
+ [ bitmap>> write ]
+ } cleave ;
--- /dev/null
+Image loading for PGM image files.
--- /dev/null
+Erik Charlebois
--- /dev/null
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: images.testing ;
+IN: images.ppm.tests
+
+"vocab:images/testing/ppm/binary.ppm" decode-test
+"vocab:images/testing/ppm/ascii.ppm" decode-test
--- /dev/null
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors ascii combinators images images.loader io
+io.encodings.ascii io.encodings.string kernel locals make math
+math.parser prettyprint sequences ;
+IN: images.ppm
+
+SINGLETON: ppm-image
+"ppm" ppm-image register-image-class
+
+: read-token ( -- token )
+ [ read1 dup blank?
+ [ t ]
+ [ dup CHAR: # =
+ [ "\n" read-until 2drop t ]
+ [ f ] if
+ ] if
+ ] [ drop ] while
+ " \n\r\t" read-until drop swap
+ prefix ascii decode ;
+
+: read-number ( -- number )
+ read-token string>number ;
+
+:: read-numbers ( n lim -- )
+ n lim = [
+ read-number ,
+ n 1 + lim read-numbers
+ ] unless ;
+
+:: read-ppm ( -- image )
+ read-token :> type
+ read-number :> width
+ read-number :> height
+ read-number :> max
+ width height 3 * * :> npixels
+ type {
+ { "P3" [ [ 0 npixels read-numbers ] B{ } make ] }
+ { "P6" [ npixels read ] }
+ } case :> data
+
+ image new
+ RGB >>component-order
+ { width height } >>dim
+ f >>upside-down?
+ data >>bitmap
+ ubyte-components >>component-type ;
+
+M: ppm-image stream>image
+ drop [ read-ppm ] with-input-stream ;
+
+M: ppm-image image>stream
+ drop {
+ [ drop "P6\n" ascii encode write ]
+ [ dim>> first number>string " " append ascii encode write ]
+ [ dim>> second number>string "\n" append ascii encode write ]
+ [ drop "255\n" ascii encode write ]
+ [ bitmap>> write ]
+ } cleave ;
--- /dev/null
+Image loading for PPM image files.
: file-descriptor-callback ( -- callback )
void { CFFileDescriptorRef CFOptionFlags void* }
- "cdecl" [
+ cdecl [
3drop
0 mx get kqueue-mx>> wait-for-events
reset-run-loop
] when ;
: spawn-process ( process -- * )
- [ setup-priority ] [ 250 _exit ] recover
- [ setup-redirection ] [ 251 _exit ] recover
- [ current-directory get absolute-path cd ] [ 252 _exit ] recover
- [ setup-environment ] [ 253 _exit ] recover
- [ get-arguments exec-args-with-path ] [ 254 _exit ] recover
- 255 _exit ;
+ [ setup-priority ] [ 2drop 250 _exit ] recover
+ [ setup-redirection ] [ 2drop 251 _exit ] recover
+ [ current-directory get absolute-path cd ] [ 2drop 252 _exit ] recover
+ [ setup-environment ] [ 2drop 253 _exit ] recover
+ [ get-arguments exec-args-with-path ] [ 2drop 254 _exit ] recover
+ 255 _exit
+ f throw ;
M: unix current-process-handle ( -- handle ) getpid ;
-! Copyright (C) 2008, 2009 Slava Pestov.
+! Copyright (C) 2008, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors sequences assocs arrays continuations
destructors combinators kernel threads concurrency.messaging
concurrency.mailboxes concurrency.promises io.files io.files.info
-io.directories io.pathnames io.monitors debugger fry ;
+io.directories io.pathnames io.monitors io.monitors.private
+debugger fry ;
IN: io.monitors.recursive
! Simulate recursive monitors on platforms that don't have them
] with with each ;
: pump-loop ( -- )
- receive dup +stop+ eq? [
- drop stop-pump
- ] [
- [ '[ _ update-hierarchy ] ignore-errors ] [ pump-step ] bi
- pump-loop
- ] if ;
+ receive {
+ { [ dup +stop+ eq? ] [ drop stop-pump ] }
+ { [ dup monitor-disposed eq? ] [ drop ] }
+ [
+ [ '[ _ update-hierarchy ] ignore-errors ] [ pump-step ] bi
+ pump-loop
+ ]
+ } cond ;
: monitor-ready ( error/t -- )
monitor tget ready>> fulfill ;
] [ drop ] if ;
: password-callback ( -- alien )
- int { void* int bool void* } "cdecl"
+ int { void* int bool void* } cdecl
[| buf size rwflag password! |
password [ B{ 0 } password! ] unless
} cleave
int
{ SOCKET void* int PVOID DWORD LPDWORD void* }
- "stdcall" alien-indirect drop
+ stdcall alien-indirect drop
winsock-error-string [ throw ] when* ; inline
M: object establish-connection ( client-out remote -- )
! Copyright (C) 2007, 2010 Slava Pestov
! Copyright (C) 2007, 2008 Doug Coleman
! See http://factorcode.org/license.txt for BSD license.
-USING: alien alien.c-types assocs continuations alien.destructors kernel
-namespaces accessors sets summary destructors destructors.private ;
+USING: alien alien.c-types alien.syntax assocs continuations
+alien.destructors kernel namespaces accessors sets summary
+destructors destructors.private ;
IN: libc
-: errno ( -- int )
- int "factor" "err_no" { } alien-invoke ;
+LIBRARY: factor
-: set-errno ( int -- )
- void "factor" "set_err_no" { int } alien-invoke ;
+FUNCTION-ALIAS: errno
+ int err_no ( ) ;
+
+FUNCTION-ALIAS: set-errno
+ void set_err_no ( int err-no ) ;
: clear-errno ( -- )
0 set-errno ;
: preserve-errno ( quot -- )
errno [ call ] dip set-errno ; inline
-: (malloc) ( size -- alien )
- void* "libc" "malloc" { ulong } alien-invoke ;
+LIBRARY: libc
+
+FUNCTION-ALIAS: (malloc)
+ void* malloc ( ulong size ) ;
-: (calloc) ( count size -- alien )
- void* "libc" "calloc" { ulong ulong } alien-invoke ;
+FUNCTION-ALIAS: (calloc)
+ void* calloc ( ulong count, ulong size ) ;
-: (free) ( alien -- )
- void "libc" "free" { void* } alien-invoke ;
+FUNCTION-ALIAS: (free)
+ void free ( void* alien ) ;
-: (realloc) ( alien size -- newalien )
- void* "libc" "realloc" { void* ulong } alien-invoke ;
+FUNCTION-ALIAS: (realloc)
+ void* realloc ( void* alien, ulong size ) ;
<PRIVATE
: free ( alien -- )
>c-ptr [ delete-malloc ] [ (free) ] bi ;
-: memcpy ( dst src size -- )
- void "libc" "memcpy" { void* void* ulong } alien-invoke ;
+FUNCTION: void memcpy ( void* dst, void* src, ulong size ) ;
-: memcmp ( a b size -- cmp )
- int "libc" "memcmp" { void* void* ulong } alien-invoke ;
+FUNCTION: int memcmp ( void* a, void* b, ulong size ) ;
: memory= ( a b size -- ? )
memcmp 0 = ;
-: strlen ( alien -- len )
- size_t "libc" "strlen" { c-string } alien-invoke ;
+FUNCTION: size_t strlen ( c-string alien ) ;
DESTRUCTOR: free
+DESTRUCTOR: (free)
IN: math.floats.env.x86.32
M: x86.32 get-sse-env
- void { void* } "cdecl" [
+ void { void* } cdecl [
EAX ESP [] MOV
EAX [] STMXCSR
] alien-assembly ;
M: x86.32 set-sse-env
- void { void* } "cdecl" [
+ void { void* } cdecl [
EAX ESP [] MOV
EAX [] LDMXCSR
] alien-assembly ;
M: x86.32 get-x87-env
- void { void* } "cdecl" [
+ void { void* } cdecl [
EAX ESP [] MOV
EAX [] FNSTSW
EAX 2 [+] FNSTCW
] alien-assembly ;
M: x86.32 set-x87-env
- void { void* } "cdecl" [
+ void { void* } cdecl [
EAX ESP [] MOV
FNCLEX
EAX 2 [+] FLDCW
IN: math.floats.env.x86.64
M: x86.64 get-sse-env
- void { void* } "cdecl" [
- int-regs param-regs first [] STMXCSR
+ void { void* } cdecl [
+ int-regs cdecl param-regs first [] STMXCSR
] alien-assembly ;
M: x86.64 set-sse-env
- void { void* } "cdecl" [
- int-regs param-regs first [] LDMXCSR
+ void { void* } cdecl [
+ int-regs cdecl param-regs first [] LDMXCSR
] alien-assembly ;
M: x86.64 get-x87-env
- void { void* } "cdecl" [
- int-regs param-regs first [] FNSTSW
- int-regs param-regs first 2 [+] FNSTCW
+ void { void* } cdecl [
+ int-regs cdecl param-regs first [] FNSTSW
+ int-regs cdecl param-regs first 2 [+] FNSTCW
] alien-assembly ;
M: x86.64 set-x87-env
- void { void* } "cdecl" [
+ void { void* } cdecl [
FNCLEX
- int-regs param-regs first 2 [+] FLDCW
+ int-regs cdecl param-regs first 2 [+] FLDCW
] alien-assembly ;
ABOUT: "math.libm"
HELP: facos
-{ $values { "x" real } { "y" real } }
+{ $values { "x" real } { "double" real } }
{ $description "Calls the inverse trigonometric cosine function from the C standard library. User code should call " { $link acos } " instead." } ;
HELP: fasin
-{ $values { "x" real } { "y" real } }
+{ $values { "x" real } { "double" real } }
{ $description "Calls the inverse trigonometric sine function from the C standard library. User code should call " { $link asin } " instead." } ;
HELP: fatan
-{ $values { "x" real } { "y" real } }
+{ $values { "x" real } { "double" real } }
{ $description "Calls the inverse trigonometric tangent function from the C standard library. User code should call " { $link atan } " instead." } ;
HELP: fatan2
-{ $values { "x" real } { "y" real } { "z" real } }
+{ $values { "x" real } { "y" real } { "double" real } }
{ $description "Calls the two-parameter inverse trigonometric tangent function from the C standard library. User code should call " { $link arg } " instead." } ;
HELP: fcos
-{ $values { "x" real } { "y" real } }
+{ $values { "x" real } { "double" real } }
{ $description "Calls the trigonometric cosine function from the C standard library. User code should call " { $link cos } " instead." } ;
HELP: fsin
-{ $values { "x" real } { "y" real } }
+{ $values { "x" real } { "double" real } }
{ $description "Calls the trigonometric sine function from the C standard library. User code should call " { $link sin } " instead." } ;
HELP: fcosh
-{ $values { "x" real } { "y" real } }
+{ $values { "x" real } { "double" real } }
{ $description "Calls the hyperbolic cosine function from the C standard library. User code should call " { $link cosh } " instead." } ;
HELP: fsinh
-{ $values { "x" real } { "y" real } }
+{ $values { "x" real } { "double" real } }
{ $description "Calls the hyperbolic sine function from the C standard library. User code should call " { $link sinh } " instead." } ;
HELP: fexp
-{ $values { "x" real } { "y" real } }
+{ $values { "x" real } { "double" real } }
{ $description "Calls the exponential function (" { $snippet "y=e^x" } " from the C standard library. User code should call " { $link exp } " instead." } ;
HELP: flog
-{ $values { "x" real } { "y" real } }
+{ $values { "x" real } { "double" real } }
{ $description "Calls the natural logarithm function from the C standard library. User code should call " { $link log } " instead." } ;
HELP: flog10
-{ $values { "x" real } { "y" real } }
+{ $values { "x" real } { "double" real } }
{ $description "Calls the base 10 logarithm function from the C standard library. User code should call " { $link log10 } " instead." } ;
HELP: fpow
-{ $values { "x" real } { "y" real } { "z" real } }
+{ $values { "x" real } { "y" real } { "double" real } }
{ $description "Calls the power function (" { $snippet "z=x^y" } ") from the C standard library. User code should call " { $link ^ } " instead." } ;
HELP: fsqrt
-{ $values { "x" real } { "y" real } }
+{ $values { "x" real } { "double" real } }
{ $description "Calls the square root function from the C standard library. User code should call " { $link sqrt } " instead." } ;
! Copyright (C) 2006 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
-USING: alien alien.c-types ;
+USING: alien alien.c-types alien.syntax ;
IN: math.libm
-: facos ( x -- y )
- double "libm" "acos" { double } alien-invoke ;
+LIBRARY: libm
-: fasin ( x -- y )
- double "libm" "asin" { double } alien-invoke ;
+FUNCTION-ALIAS: facos
+ double acos ( double x ) ;
-: fatan ( x -- y )
- double "libm" "atan" { double } alien-invoke ;
+FUNCTION-ALIAS: fasin
+ double asin ( double x ) ;
-: fatan2 ( x y -- z )
- double "libm" "atan2" { double double } alien-invoke ;
+FUNCTION-ALIAS: fatan
+ double atan ( double x ) ;
-: fcos ( x -- y )
- double "libm" "cos" { double } alien-invoke ;
+FUNCTION-ALIAS: fatan2
+ double atan2 ( double x, double y ) ;
-: fsin ( x -- y )
- double "libm" "sin" { double } alien-invoke ;
+FUNCTION-ALIAS: fcos
+ double cos ( double x ) ;
-: ftan ( x -- y )
- double "libm" "tan" { double } alien-invoke ;
+FUNCTION-ALIAS: fsin
+ double sin ( double x ) ;
-: fcosh ( x -- y )
- double "libm" "cosh" { double } alien-invoke ;
+FUNCTION-ALIAS: ftan
+ double tan ( double x ) ;
-: fsinh ( x -- y )
- double "libm" "sinh" { double } alien-invoke ;
+FUNCTION-ALIAS: fcosh
+ double cosh ( double x ) ;
-: ftanh ( x -- y )
- double "libm" "tanh" { double } alien-invoke ;
+FUNCTION-ALIAS: fsinh
+ double sinh ( double x ) ;
-: fexp ( x -- y )
- double "libm" "exp" { double } alien-invoke ;
+FUNCTION-ALIAS: ftanh
+ double tanh ( double x ) ;
-: flog ( x -- y )
- double "libm" "log" { double } alien-invoke ;
+FUNCTION-ALIAS: fexp
+ double exp ( double x ) ;
-: flog10 ( x -- y )
- double "libm" "log10" { double } alien-invoke ;
+FUNCTION-ALIAS: flog
+ double log ( double x ) ;
-: fpow ( x y -- z )
- double "libm" "pow" { double double } alien-invoke ;
+FUNCTION-ALIAS: flog10
+ double log10 ( double x ) ;
-: fsqrt ( x -- y )
- double "libm" "sqrt" { double } alien-invoke ;
+FUNCTION-ALIAS: fpow
+ double pow ( double x, double y ) ;
+
+FUNCTION-ALIAS: fsqrt
+ double sqrt ( double x ) ;
! Windows doesn't have these...
-: flog1+ ( x -- y )
- double "libm" "log1p" { double } alien-invoke ;
+FUNCTION-ALIAS: flog1+
+ double log1p ( double x ) ;
-: facosh ( x -- y )
- double "libm" "acosh" { double } alien-invoke ;
+FUNCTION-ALIAS: facosh
+ double acosh ( double x ) ;
-: fasinh ( x -- y )
- double "libm" "asinh" { double } alien-invoke ;
+FUNCTION-ALIAS: fasinh
+ double asinh ( double x ) ;
-: fatanh ( x -- y )
- double "libm" "atanh" { double } alien-invoke ;
+FUNCTION-ALIAS: fatanh
+ double atanh ( double x ) ;
: gl-function-context ( -- context ) 0 ; inline
: gl-function-address ( name -- address ) f dlsym ; inline
-: gl-function-calling-convention ( -- str ) "cdecl" ; inline
+: gl-function-calling-convention ( -- str ) cdecl ; inline
-USING: kernel x11.glx ;
+USING: alien kernel x11.glx ;
IN: opengl.gl.unix
: gl-function-context ( -- context ) glXGetCurrentContext ; inline
: gl-function-address ( name -- address ) glXGetProcAddressARB ; inline
-: gl-function-calling-convention ( -- str ) "cdecl" ; inline
+: gl-function-calling-convention ( -- str ) cdecl ; inline
-USING: alien.c-types alien.syntax kernel windows.types ;
+USING: alien alien.c-types alien.syntax kernel windows.types ;
IN: opengl.gl.windows
LIBRARY: gl
: gl-function-context ( -- context ) wglGetCurrentContext ; inline
: gl-function-address ( name -- address ) wglGetProcAddress ; inline
-: gl-function-calling-convention ( -- str ) "stdcall" ; inline
+: gl-function-calling-convention ( -- str ) stdcall ; inline
{
{ [ os openbsd? ] [ ] } ! VM is linked with it
{ [ os netbsd? ] [ ] }
- { [ os winnt? ] [ "libcrypto" "libeay32.dll" "cdecl" add-library ] }
- { [ os macosx? ] [ "libcrypto" "libcrypto.dylib" "cdecl" add-library ] }
- { [ os unix? ] [ "libcrypto" "libcrypto.so" "cdecl" add-library ] }
+ { [ os winnt? ] [ "libcrypto" "libeay32.dll" cdecl add-library ] }
+ { [ os macosx? ] [ "libcrypto" "libcrypto.dylib" cdecl add-library ] }
+ { [ os unix? ] [ "libcrypto" "libcrypto.so" cdecl add-library ] }
} cond
>>
<< {
{ [ os openbsd? ] [ ] } ! VM is linked with it
{ [ os netbsd? ] [ ] }
- { [ os winnt? ] [ "libssl" "ssleay32.dll" "cdecl" add-library ] }
- { [ os macosx? ] [ "libssl" "libssl.dylib" "cdecl" add-library ] }
- { [ os unix? ] [ "libssl" "libssl.so" "cdecl" add-library ] }
+ { [ os winnt? ] [ "libssl" "ssleay32.dll" cdecl add-library ] }
+ { [ os macosx? ] [ "libssl" "libssl.dylib" cdecl add-library ] }
+ { [ os unix? ] [ "libssl" "libssl.so" cdecl add-library ] }
} cond >>
CONSTANT: X509_FILETYPE_PEM 1
IN: pango.cairo
<< {
- { [ os winnt? ] [ "pangocairo" "libpangocairo-1.0-0.dll" "cdecl" add-library ] }
- { [ os macosx? ] [ "pangocairo" "/opt/local/lib/libpangocairo-1.0.0.dylib" "cdecl" add-library ] }
+ { [ os winnt? ] [ "pangocairo" "libpangocairo-1.0-0.dll" cdecl add-library ] }
+ { [ os macosx? ] [ "pangocairo" "/opt/local/lib/libpangocairo-1.0.0.dylib" cdecl add-library ] }
{ [ os unix? ] [ ] }
} cond >>
LIBRARY: pango
-TYPEDEF: int PangoStyle
-C-ENUM:
+C-ENUM: PangoStyle
PANGO_STYLE_NORMAL
PANGO_STYLE_OBLIQUE
PANGO_STYLE_ITALIC ;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
<< {
- { [ os winnt? ] [ "pango" "libpango-1.0-0.dll" "cdecl" add-library ] }
- { [ os macosx? ] [ "pango" "/opt/local/lib/libpango-1.0.0.dylib" "cdecl" add-library ] }
+ { [ os winnt? ] [ "pango" "libpango-1.0-0.dll" cdecl add-library ] }
+ { [ os macosx? ] [ "pango" "/opt/local/lib/libpango-1.0.0.dylib" cdecl add-library ] }
{ [ os unix? ] [ ] }
} cond >>
-IN: specialized-arrays.tests
-USING: tools.test alien.syntax specialized-arrays
-specialized-arrays.private sequences alien accessors
-kernel arrays combinators compiler compiler.units classes.struct
-combinators.smart compiler.tree.debugger math libc destructors
-sequences.private multiline eval words vocabs namespaces
-assocs prettyprint alien.data math.vectors definitions
-compiler.test ;
+USING: tools.test alien.syntax specialized-arrays sequences
+alien accessors kernel arrays combinators compiler
+compiler.units classes.struct combinators.smart
+compiler.tree.debugger math libc destructors sequences.private
+multiline eval words vocabs namespaces assocs prettyprint
+alien.data math.vectors definitions compiler.test ;
+FROM: specialized-arrays.private => specialized-array-vocab ;
FROM: alien.c-types => int float bool char float ulonglong ushort uint
heap-size little-endian? ;
+IN: specialized-arrays.tests
SPECIALIZED-ARRAY: int
SPECIALIZED-ARRAYS: bool ushort char uint float ulonglong ;
} second
] unit-test
+[ ] [
+ [
+ test-struct specialized-array-vocab forget-vocab
+ ] with-compilation-unit
+] unit-test
+
! Regression
STRUCT: fixed-string { text char[64] } ;
ALIEN: 123 100 <direct-int-array> byte-length
] unit-test
+[ ] [
+ [
+ fixed-string specialized-array-vocab forget-vocab
+ ] with-compilation-unit
+] unit-test
+
! Test prettyprinting
[ "int-array{ 1 2 3 }" ] [ int-array{ 1 2 3 } unparse ] unit-test
[ "int-array@ f 100" ] [ f 100 <direct-int-array> unparse ] unit-test
[ 80 ] [ 10 <struct-resize-test-array> byte-length ] unit-test
[ { 10 20 30 } ] [ { 10 20 30 } struct-resize-test-usage ] unit-test
+
+[ ] [
+ [
+ struct-resize-test specialized-array-vocab forget-vocab
+ ] with-compilation-unit
+] unit-test
[ callbacks get ] dip '[ _ <callback> ] cache ;
: callback-bottom ( params -- )
- [ xt>> ] [ callback-return-rewind ] bi
- '[ _ _ callback-xt ] infer-quot-here ;
+ [ xt>> ] [ stack-cleanup ] bi '[ _ _ callback-xt ] infer-quot-here ;
: infer-alien-callback ( -- )
alien-callback-params new
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2010 Slava Pestov, Joe Groff.
! See http://factorcode.org/license.txt for BSD license.
USING: arrays effects fry vectors sequences assocs math math.order accessors kernel
combinators quotations namespaces grouping locals stack-checker.state
stack-checker.backend stack-checker.errors stack-checker.visitor
stack-checker.values stack-checker.recursive-state ;
+FROM: sequences.private => dispatch ;
IN: stack-checker.branches
: balanced? ( pairs -- ? )
: phi-outputs ( phi-in -- stack )
flip [ unify-values ] map ;
-SYMBOL: quotations
+SYMBOLS: combinator quotations ;
-: simple-unbalanced-branches-error ( branches quots -- * )
- [ \ if ] 2dip swap
+: simple-unbalanced-branches-error ( word quots branches -- * )
[ length [ (( ..a -- ..b )) ] replicate ]
[ [ length [ "x" <array> ] bi@ <effect> ] { } assoc>map ] bi
unbalanced-branches-error ;
: unify-branches ( ins stacks -- in phi-in phi-out )
zip [ 0 { } { } ] [
[ keys supremum ] [ ] [ balanced? ] tri
- [ dupd phi-inputs dup phi-outputs ]
- [ quotations get simple-unbalanced-branches-error ]
- if
+ [ dupd phi-inputs dup phi-outputs ] [
+ [ combinator get quotations get ] dip
+ simple-unbalanced-branches-error
+ ] if
] if-empty ;
: branch-variable ( seq symbol -- seq )
M: composed curried/composed? drop t ;
M: declared-effect curried/composed? known>> curried/composed? ;
-:: declare-if-effects ( -- )
- H{ } clone :> variables
- V{ } clone :> branches
- \ if (( ..a -- ..b )) variables branches 0 declare-effect-d
- \ if (( ..a -- ..b )) variables branches 1 declare-effect-d ;
+: declare-if-effects ( -- )
+ H{ } clone V{ } clone
+ [ [ \ if (( ..a -- ..b )) ] 2dip 0 declare-effect-d ]
+ [ [ \ if (( ..a -- ..b )) ] 2dip 1 declare-effect-d ] 2bi ;
: infer-if ( -- )
+ \ if combinator set
2 literals-available? [
(infer-if)
] [
] if ;
: infer-dispatch ( -- )
+ \ dispatch combinator set
pop-literal nip infer-branches
[ #dispatch, ] dip compute-phi-function ;
\ (dlsym) { byte-array object } { c-ptr } define-primitive
\ (exists?) { string } { object } define-primitive
\ (exit) { integer } { } define-primitive
-\ (float>string) { float } { byte-array } define-primitive \ (float>string) make-foldable
+\ (format-float) { float byte-array } { byte-array } define-primitive \ (format-float) make-foldable
\ (fopen) { byte-array byte-array } { alien } define-primitive
\ (identity-hashcode) { object } { fixnum } define-primitive
\ (save-image) { byte-array byte-array } { } define-primitive
[ with-inner-d ] 2dip (effect-here) ; inline
: (diff-variable) ( diff variable vars -- diff' )
- [ at* nip ] [ '[ _ _ at - ] ] [ '[ _ _ set-at 0 ] ] 2tri if ;
+ [ key? ] [ '[ _ _ at - ] ] [ '[ _ _ set-at 0 ] ] 2tri if ;
: (check-variable) ( actual-count declared-count variable vars -- diff ? )
[ - ] 2dip dupd '[ _ _ (diff-variable) t ] [ dup 0 <= ] if ;
[ >>actual ] keep
2dup [ [ variables>> ] [ effect>> ] bi ] dip check-variables
[ 2drop ] [ drop combinator-unbalanced-branches-error ] if ;
-
! A typo
{ 1 0 } [ { [ ] } dispatch ] must-infer-as
+! Make sure the error is correct
+[
+ [ { [ drop ] [ dup ] } dispatch ] infer
+] [ word>> \ dispatch eq? ] must-fail-with
+
DEFER: inline-recursive-2
: inline-recursive-1 ( -- ) inline-recursive-2 ;
: inline-recursive-2 ( -- ) inline-recursive-1 ;
! See http://factorcode.org/license.txt for BSD license.
USING: unix alien alien.c-types kernel math sequences strings
io.backend.unix splitting io.encodings.utf8 io.encodings.string
-specialized-arrays ;
+specialized-arrays alien.syntax ;
SPECIALIZED-ARRAY: char
IN: system-info.linux
-: (uname) ( buf -- int )
- int f "uname" { c-string } alien-invoke ;
+FUNCTION-ALIAS: (uname)
+ int uname ( c-string buf ) ;
: uname ( -- seq )
65536 <char-array> [ (uname) io-error ] keep
IN: tools.deploy.test.9
: callback-test ( -- callback )
- int { int } "cdecl" [ 1 + ] alien-callback ;
+ int { int } cdecl [ 1 + ] alien-callback ;
: indirect-test ( -- )
- 10 callback-test int { int } "cdecl" alien-indirect 11 assert= ;
+ 10 callback-test int { int } cdecl alien-indirect 11 assert= ;
MAIN: indirect-test
TR: tabs>spaces "\t" "\s" ;
+GENERIC: (>address) ( object -- n )
+
+M: integer (>address) ;
+M: alien (>address) alien-address ;
+
PRIVATE>
M: byte-array disassemble
2array disassemble
] with-destructors ;
-M: pair disassemble first2 disassemble* [ tabs>spaces print ] each ;
+M: pair disassemble first2 [ (>address) ] bi@ disassemble* [ tabs>spaces print ] each ;
M: word disassemble word-code 2array disassemble ;
{ [ os macosx? ] [ "libudis86.0.dylib" ] }
{ [ os unix? ] [ "libudis86.so.0" ] }
{ [ os winnt? ] [ "libudis86.dll" ] }
-} cond "cdecl" add-library
+} cond cdecl add-library
>>
LIBRARY: libudis86
[ ] [ \ + usage-profile. ] unit-test
-: callback-test ( -- callback ) void { } "cdecl" [ ] alien-callback ;
+: callback-test ( -- callback ) void { } cdecl [ ] alien-callback ;
-: indirect-test ( callback -- ) void { } "cdecl" alien-indirect ;
+: indirect-test ( callback -- ) void { } cdecl alien-indirect ;
: foobar ( -- ) ;
-! Copyright (C) 2003, 2009 Slava Pestov.
+! Copyright (C) 2003, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays assocs combinators compiler.units
continuations debugger effects fry generalizations io io.files
-io.styles kernel lexer locals macros math.parser namespaces parser
-vocabs.parser prettyprint quotations sequences source-files splitting
-stack-checker summary unicode.case vectors vocabs vocabs.loader
-vocabs.files words tools.errors source-files.errors io.streams.string
-make compiler.errors ;
+io.styles kernel lexer locals macros math.parser namespaces
+parser vocabs.parser prettyprint quotations sequences
+source-files splitting stack-checker summary unicode.case
+vectors vocabs vocabs.loader vocabs.files vocabs.metadata words
+tools.errors source-files.errors io.streams.string make
+compiler.errors ;
IN: tools.test
TUPLE: test-failure < source-file-error continuation ;
'[ _ run-file ] [ file-failure ] recover
] with-variable ;
+SYMBOL: forget-tests?
+
<PRIVATE
-: run-vocab-tests ( vocab -- )
+: forget-tests ( files -- )
+ forget-tests? get
+ [ [ [ forget-source ] each ] with-compilation-unit ] [ drop ] if ;
+
+: test-vocab ( vocab -- )
vocab dup [
dup source-loaded?>> [
- vocab-tests [ run-test-file ] each
+ vocab-tests
+ [ [ run-test-file ] each ]
+ [ forget-tests ]
+ bi
] [ drop ] if
] [ drop ] if ;
+: test-vocabs ( vocabs -- ) [ test-vocab ] each ;
+
PRIVATE>
TEST: unit-test
: :test-failures ( -- ) test-failures get errors. ;
-: test ( prefix -- )
- child-vocabs [ run-vocab-tests ] each ;
+: test ( prefix -- ) child-vocabs test-vocabs ;
-: test-all ( -- ) "" test ;
+: test-all ( -- ) vocabs filter-don't-test test-vocabs ;
! return 0 if you handle the message, else just let DefWindowProc return its val
: ui-wndproc ( -- object )
- uint { void* uint long long } "stdcall" [
+ uint { void* uint long long } stdcall [
pick
trace-messages? get-global [ dup windows-message-name name>> print flush ] when
wm-handlers get-global at* [ call ] [ drop DefWindowProc ] if
0 >>cbClsExtra
0 >>cbWndExtra
f GetModuleHandle >>hInstance
- f GetModuleHandle "fraptor" utf16n string>alien LoadIcon >>hIcon
+ f GetModuleHandle "APPICON" utf16n string>alien LoadIcon >>hIcon
f IDC_ARROW LoadCursor >>hCursor
class-name-ptr >>lpszClassName
IN: ui.gadgets.grids
ARTICLE: "ui-grid-layout" "Grid layouts"
-"Grid gadgets layout their children in a rectangular grid."
+"Grid gadgets layout their children in a rectangular grid. The grid is represented as a sequence of sequences of gadgets. Every child sequence is a row of gadgets. Every row must have an equal number of gadgets in it."
{ $subsections grid }
"Creating grids from a fixed set of gadgets:"
{ $subsections <grid> }
[ invoke-primary-operation ] >>action
COLOR: dark-gray >>column-line-color
6 >>gap
- 5 >>min-rows
- 5 >>max-rows
+ 4 >>min-rows
+ 4 >>max-rows
60 >>min-cols
60 >>max-cols
t >>selection-required?
[ invoke-primary-operation ] >>action
COLOR: dark-gray >>column-line-color
6 >>gap
- 5 >>min-rows
- 5 >>max-rows
+ 4 >>min-rows
+ 4 >>max-rows
60 >>min-cols
60 >>max-cols
t >>selection-required?
<PRIVATE
! Grapheme breaks
-C-ENUM: Any L V T LV LVT Extend Control CR LF
+C-ENUM: f Any L V T LV LVT Extend Control CR LF
SpacingMark Prepend graphemes ;
: jamo-class ( ch -- class )
"vocab:unicode/data/WordBreakProperty.txt" load-interval-file
to: word-break-table
-C-ENUM: wOther wCR wLF wNewline wExtend wFormat wKatakana wALetter wMidLetter
+C-ENUM: f wOther wCR wLF wNewline wExtend wFormat wKatakana wALetter wMidLetter
wMidNum wMidNumLet wNumeric wExtendNumLet words ;
: word-break-classes ( -- table ) ! Is there a way to avoid this?
FUNCTION: int utimes ( c-string path, timeval[2] times ) ;
FUNCTION: ssize_t write ( int fd, void* buf, size_t nbytes ) ;
-"librt" "librt.so" "cdecl" add-library
+"librt" "librt.so" cdecl add-library
[ [ first ] [ ] bi ] dip exec-with-env ;
: with-fork ( child parent -- )
- [ [ fork-process dup zero? ] dip '[ drop @ ] ] dip
- if ; inline
+ [ fork-process ] 2dip if-zero ; inline
CONSTANT: SIGKILL 9
CONSTANT: SIGTERM 15
: close-file ( fd -- ) [ close ] unix-system-call drop ;
-: _exit ( status -- * )
- #! We throw to give this a terminating stack effect.
- int f "_exit" { int } alien-invoke "Exit failed" throw ;
+FUNCTION: int _exit ( int status ) ;
M: unix open-file [ open ] unix-system-call ;
: vm-field-offset ( field -- offset ) vm offset-of ; inline
-C-ENUM:
+C-ENUM: f
collect-nursery-op
collect-aging-op
collect-to-tenured-op
\r
<PRIVATE\r
\r
-: filter-unportable ( seq -- seq' )\r
- [ vocab-name unportable? not ] filter ;\r
-\r
: collect-vocabs ( quot -- seq )\r
[ all-vocabs-recursive no-roots no-prefixes ] dip\r
gather natural-sort ; inline\r
: (load) ( prefix -- failures )\r
[ child-vocabs-recursive no-roots no-prefixes ]\r
[ dup find-vocab-root [ >vocab-link prefix ] [ drop ] if ] bi\r
- filter-unportable\r
+ filter-don't-load\r
require-all ;\r
\r
: load ( prefix -- )\r
: supported-platform? ( platforms -- ? )
[ t ] [ [ os swap class<= ] any? ] if-empty ;
-: unportable? ( vocab -- ? )
+: don't-load? ( vocab -- ? )
{
- [ vocab-tags "untested" swap member? ]
+ [ vocab-tags "not loaded" swap member? ]
[ vocab-platforms supported-platform? not ]
} 1|| ;
+: filter-don't-load ( vocabs -- vocabs' )
+ [ vocab-name don't-load? not ] filter ;
+
+: don't-test? ( vocab -- ? )
+ vocab-tags "not tested" swap member? ;
+
+: filter-don't-test ( vocabs -- vocabs' )
+ [ don't-test? not ] filter ;
+
TUPLE: unsupported-platform vocab requires ;
: unsupported-platform ( vocab requires -- )
CONSTANT: TokenSandBoxInert 15
! } TOKEN_INFORMATION_CLASS;
-TYPEDEF: DWORD ACCESS_MODE
-C-ENUM:
+C-ENUM: ACCESS_MODE
NOT_USED_ACCESS
GRANT_ACCESS
SET_ACCESS
SET_AUDIT_SUCCESS
SET_AUDIT_FAILURE ;
-TYPEDEF: DWORD MULTIPLE_TRUSTEE_OPERATION
-C-ENUM:
+C-ENUM: MULTIPLE_TRUSTEE_OPERATION
NO_MULTIPLE_TRUSTEE
TRUSTEE_IS_IMPERSONATE ;
-TYPEDEF: DWORD TRUSTEE_FORM
-C-ENUM:
+C-ENUM: TRUSTEE_FORM
TRUSTEE_IS_SID
TRUSTEE_IS_NAME
TRUSTEE_BAD_FORM
TRUSTEE_IS_OBJECTS_AND_SID
TRUSTEE_IS_OBJECTS_AND_NAME ;
-TYPEDEF: DWORD TRUSTEE_TYPE
-C-ENUM:
+C-ENUM: TRUSTEE_TYPE
TRUSTEE_IS_UNKNOWN
TRUSTEE_IS_USER
TRUSTEE_IS_GROUP
TRUSTEE_IS_INVALID
TRUSTEE_IS_COMPUTER ;
-TYPEDEF: DWORD SE_OBJECT_TYPE
-C-ENUM:
+C-ENUM: SE_OBJECT_TYPE
SE_UNKNOWN_OBJECT_TYPE
SE_FILE_OBJECT
SE_SERVICE
USING: alien sequences alien.libraries ;
{
- { "advapi32" "\\windows\\coredll.dll" "stdcall" }
- { "gdi32" "\\windows\\coredll.dll" "stdcall" }
- { "user32" "\\windows\\coredll.dll" "stdcall" }
- { "kernel32" "\\windows\\coredll.dll" "stdcall" }
- { "winsock" "\\windows\\ws2.dll" "stdcall" }
- { "mswsock" "\\windows\\ws2.dll" "stdcall" }
- { "libc" "\\windows\\coredll.dll" "stdcall" }
- { "libm" "\\windows\\coredll.dll" "stdcall" }
- ! { "gl" "libGLES_CM.dll" "stdcall" }
- ! { "glu" "libGLES_CM.dll" "stdcall" }
- { "ole32" "ole32.dll" "stdcall" }
+ { "advapi32" "\\windows\\coredll.dll" stdcall }
+ { "gdi32" "\\windows\\coredll.dll" stdcall }
+ { "user32" "\\windows\\coredll.dll" stdcall }
+ { "kernel32" "\\windows\\coredll.dll" stdcall }
+ { "winsock" "\\windows\\ws2.dll" stdcall }
+ { "mswsock" "\\windows\\ws2.dll" stdcall }
+ { "libc" "\\windows\\coredll.dll" stdcall }
+ { "libm" "\\windows\\coredll.dll" stdcall }
+ ! { "gl" "libGLES_CM.dll" stdcall }
+ ! { "glu" "libGLES_CM.dll" stdcall }
+ { "ole32" "ole32.dll" stdcall }
} [ first3 add-library ] each
[ 2nip length ] 3keep
'[
_ npick *void* _ cell * alien-cell _ _
- "stdcall" alien-indirect
+ stdcall alien-indirect
] ;
TUPLE: com-interface-definition word parent iid functions ;
] [
first2 (finish-thunk)
] bi*
- "stdcall" swap compile-alien-callback
+ stdcall swap compile-alien-callback
] 2map ;
: (make-callbacks) ( implementations -- sequence )
! Copyright (C) 2010 Erik Charlebois.
! See http://factorcode.org/license.txt for BSD license.
-USING: alien.c-types alien.libraries alien.syntax classes.struct
-kernel math windows.types windows.ole32 ;
+USING: alien alien.c-types alien.libraries alien.syntax
+classes.struct kernel math windows.types windows.ole32 ;
IN: windows.ddk.hid
-<< "hid" "hid.dll" "stdcall" add-library >>
+<< "hid" "hid.dll" stdcall add-library >>
LIBRARY: hid
TYPEDEF: LONG NTSTATUS
CONSTANT: HIDP_LINK_COLLECTION_ROOT -1
CONSTANT: HIDP_LINK_COLLECTION_UNSPECIFIED 0
-C-ENUM:
+C-ENUM: HIDP_REPORT_TYPE
HidP_Input
HidP_Output
HidP_Feature ;
-TYPEDEF: int HIDP_REPORT_TYPE
STRUCT: USAGE_AND_PAGE
{ Usage USAGE }
ULONG UsageListLength
) ;
-C-ENUM:
+C-ENUM: HIDP_KEYBOARD_DIRECTION
HidP_Keyboard_Break
HidP_Keyboard_Make ;
-TYPEDEF: int HIDP_KEYBOARD_DIRECTION
STRUCT: HIDP_KEYBOARD_MODIFIER_STATE
{ ul ULONG } ;
! Copyright (C) 2010 Erik Charlebois.
! See http://factorcode.org/license.txt for BSD license.
-USING: literals windows.kernel32 math alien.syntax windows.types classes.struct
-alien.c-types windows.errors windows.ole32 windows.advapi32 alien.libraries ;
+USING: literals windows.kernel32 math alien.syntax windows.types
+classes.struct alien alien.c-types windows.errors windows.ole32
+windows.advapi32 alien.libraries ;
IN: windows.ddk.setupapi
-<< "setupapi" "setupapi.dll" "stdcall" add-library >>
+<< "setupapi" "setupapi.dll" stdcall add-library >>
LIBRARY: setupapi
TYPEDEF: DWORDLONG SP_LOG_TOKEN
FUNCTION: BOOL SetupRemoveFileLogEntryW ( HSPFILELOG FileLogHandle, PCWSTR LogSectionName, PCWSTR TargetFilename ) ;
ALIAS: SetupRemoveFileLogEntry SetupRemoveFileLogEntryW
-C-ENUM:
+C-ENUM: SetupFileLogInfo
SetupFileLogSourceFilename
SetupFileLogChecksum
SetupFileLogDiskTagfile
SetupFileLogDiskDescription
SetupFileLogOtherInfo
SetupFileLogMax ;
-TYPEDEF: int SetupFileLogInfo
FUNCTION: BOOL SetupQueryFileLogA ( HSPFILELOG FileLogHandle, PCSTR LogSectionName, PCSTR TargetFilename, SetupFileLogInfo DesiredInfo, PSTR DataOut, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
FUNCTION: BOOL SetupQueryFileLogW ( HSPFILELOG FileLogHandle, PCWSTR LogSectionName, PCWSTR TargetFilename, SetupFileLogInfo DesiredInfo, PWSTR DataOut, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
! Copyright (C) 2010 Erik Charlebois.
! See http://factorcode.org/license.txt for BSD license.
-USING: alien.c-types alien.syntax classes.struct windows.kernel32
-windows.types alien.libraries ;
+USING: alien alien.c-types alien.syntax classes.struct
+windows.kernel32 windows.types alien.libraries ;
IN: windows.ddk.winusb
-<< "winusb" "winusb.dll" "stdcall" add-library >>
+<< "winusb" "winusb.dll" stdcall add-library >>
LIBRARY: winusb
TYPEDEF: PVOID WINUSB_INTERFACE_HANDLE
{ iInterface UCHAR } ;
TYPEDEF: USB_INTERFACE_DESCRIPTOR* PUSB_INTERFACE_DESCRIPTOR
-C-ENUM:
+C-ENUM: USBD_PIPE_TYPE
UsbdPipeTypeControl
UsbdPipeTypeIsochronous
UsbdPipeTypeBulk
UsbdPipeTypeInterrupt ;
-TYPEDEF: int USBD_PIPE_TYPE
STRUCT: WINUSB_PIPE_INFORMATION
{ PipeType USBD_PIPE_TYPE }
CONSTANT: D3D11_RETURN_TYPE_CONTINUED 8
TYPEDEF: int D3D11_RESOURCE_RETURN_TYPE
-C-ENUM: D3D11_CT_CBUFFER
- D3D11_CT_TBUFFER
- D3D11_CT_INTERFACE_POINTERS
- D3D11_CT_RESOURCE_BIND_INFO ;
-TYPEDEF: int D3D11_CBUFFER_TYPE
+C-ENUM: D3D11_CBUFFER_TYPE
+ D3D11_CT_CBUFFER
+ D3D11_CT_TBUFFER
+ D3D11_CT_INTERFACE_POINTERS
+ D3D11_CT_RESOURCE_BIND_INFO ;
TYPEDEF: D3D11_CBUFFER_TYPE* LPD3D11_CBUFFER_TYPE
STRUCT: D3D11_SIGNATURE_PARAMETER_DESC
CONSTANT: MAXD3DDECLUSAGEINDEX 15
CONSTANT: MAXD3DDECLLENGTH 64
-TYPEDEF: int D3DDECLMETHOD
-C-ENUM:
+C-ENUM: D3DDECLMETHOD
D3DDECLMETHOD_DEFAULT
D3DDECLMETHOD_PARTIALU
D3DDECLMETHOD_PARTIALV
CONSTANT: D3DVS_SWIZZLE_SHIFT 16
CONSTANT: D3DVS_SWIZZLE_MASK HEX: 00FF0000
-: D3DVS_X_X ( -- n ) 0 D3DVS_SWIZZLE_SHIFT shift ; inline
-: D3DVS_X_Y ( -- n ) 1 D3DVS_SWIZZLE_SHIFT shift ; inline
-: D3DVS_X_Z ( -- n ) 2 D3DVS_SWIZZLE_SHIFT shift ; inline
-: D3DVS_X_W ( -- n ) 3 D3DVS_SWIZZLE_SHIFT shift ; inline
+CONSTANT: D3DVS_X_X $[ 0 16 shift ]
+CONSTANT: D3DVS_X_Y $[ 1 16 shift ]
+CONSTANT: D3DVS_X_Z $[ 2 16 shift ]
+CONSTANT: D3DVS_X_W $[ 3 16 shift ]
-: D3DVS_Y_X ( -- n ) 0 D3DVS_SWIZZLE_SHIFT 2 + shift ; inline
-: D3DVS_Y_Y ( -- n ) 1 D3DVS_SWIZZLE_SHIFT 2 + shift ; inline
-: D3DVS_Y_Z ( -- n ) 2 D3DVS_SWIZZLE_SHIFT 2 + shift ; inline
-: D3DVS_Y_W ( -- n ) 3 D3DVS_SWIZZLE_SHIFT 2 + shift ; inline
+CONSTANT: D3DVS_Y_X $[ 0 16 2 + shift ]
+CONSTANT: D3DVS_Y_Y $[ 1 16 2 + shift ]
+CONSTANT: D3DVS_Y_Z $[ 2 16 2 + shift ]
+CONSTANT: D3DVS_Y_W $[ 3 16 2 + shift ]
-: D3DVS_Z_X ( -- n ) 0 D3DVS_SWIZZLE_SHIFT 4 + shift ; inline
-: D3DVS_Z_Y ( -- n ) 1 D3DVS_SWIZZLE_SHIFT 4 + shift ; inline
-: D3DVS_Z_Z ( -- n ) 2 D3DVS_SWIZZLE_SHIFT 4 + shift ; inline
-: D3DVS_Z_W ( -- n ) 3 D3DVS_SWIZZLE_SHIFT 4 + shift ; inline
+CONSTANT: D3DVS_Z_X $[ 0 16 4 + shift ]
+CONSTANT: D3DVS_Z_Y $[ 1 16 4 + shift ]
+CONSTANT: D3DVS_Z_Z $[ 2 16 4 + shift ]
+CONSTANT: D3DVS_Z_W $[ 3 16 4 + shift ]
-: D3DVS_W_X ( -- n ) 0 D3DVS_SWIZZLE_SHIFT 6 + shift ; inline
-: D3DVS_W_Y ( -- n ) 1 D3DVS_SWIZZLE_SHIFT 6 + shift ; inline
-: D3DVS_W_Z ( -- n ) 2 D3DVS_SWIZZLE_SHIFT 6 + shift ; inline
-: D3DVS_W_W ( -- n ) 3 D3DVS_SWIZZLE_SHIFT 6 + shift ; inline
+CONSTANT: D3DVS_W_X $[ 0 16 6 + shift ]
+CONSTANT: D3DVS_W_Y $[ 1 16 6 + shift ]
+CONSTANT: D3DVS_W_Z $[ 2 16 6 + shift ]
+CONSTANT: D3DVS_W_W $[ 3 16 6 + shift ]
CONSTANT: D3DVS_NOSWIZZLE flags{ D3DVS_X_X D3DVS_Y_Y D3DVS_Z_Z D3DVS_W_W }
CONSTANT: D3DSP_SRCMOD_MASK HEX: 0F000000
TYPEDEF: int D3DSHADER_PARAM_SRCMOD_TYPE
-: D3DSPSM_NONE ( -- n ) 0 D3DSP_SRCMOD_SHIFT shift ; inline
-: D3DSPSM_NEG ( -- n ) 1 D3DSP_SRCMOD_SHIFT shift ; inline
-: D3DSPSM_BIAS ( -- n ) 2 D3DSP_SRCMOD_SHIFT shift ; inline
-: D3DSPSM_BIASNEG ( -- n ) 3 D3DSP_SRCMOD_SHIFT shift ; inline
-: D3DSPSM_SIGN ( -- n ) 4 D3DSP_SRCMOD_SHIFT shift ; inline
-: D3DSPSM_SIGNNEG ( -- n ) 5 D3DSP_SRCMOD_SHIFT shift ; inline
-: D3DSPSM_COMP ( -- n ) 6 D3DSP_SRCMOD_SHIFT shift ; inline
-: D3DSPSM_X2 ( -- n ) 7 D3DSP_SRCMOD_SHIFT shift ; inline
-: D3DSPSM_X2NEG ( -- n ) 8 D3DSP_SRCMOD_SHIFT shift ; inline
-: D3DSPSM_DZ ( -- n ) 9 D3DSP_SRCMOD_SHIFT shift ; inline
-: D3DSPSM_DW ( -- n ) 10 D3DSP_SRCMOD_SHIFT shift ; inline
-: D3DSPSM_ABS ( -- n ) 11 D3DSP_SRCMOD_SHIFT shift ; inline
-: D3DSPSM_ABSNEG ( -- n ) 12 D3DSP_SRCMOD_SHIFT shift ; inline
-: D3DSPSM_NOT ( -- n ) 13 D3DSP_SRCMOD_SHIFT shift ; inline
+CONSTANT: D3DSPSM_NONE $[ 0 24 shift ]
+CONSTANT: D3DSPSM_NEG $[ 1 24 shift ]
+CONSTANT: D3DSPSM_BIAS $[ 2 24 shift ]
+CONSTANT: D3DSPSM_BIASNEG $[ 3 24 shift ]
+CONSTANT: D3DSPSM_SIGN $[ 4 24 shift ]
+CONSTANT: D3DSPSM_SIGNNEG $[ 5 24 shift ]
+CONSTANT: D3DSPSM_COMP $[ 6 24 shift ]
+CONSTANT: D3DSPSM_X2 $[ 7 24 shift ]
+CONSTANT: D3DSPSM_X2NEG $[ 8 24 shift ]
+CONSTANT: D3DSPSM_DZ $[ 9 24 shift ]
+CONSTANT: D3DSPSM_DW $[ 10 24 shift ]
+CONSTANT: D3DSPSM_ABS $[ 11 24 shift ]
+CONSTANT: D3DSPSM_ABSNEG $[ 12 24 shift ]
+CONSTANT: D3DSPSM_NOT $[ 13 24 shift ]
CONSTANT: D3DSPSM_FORCE_DWORD HEX: 7fffffff
: D3DPS_VERSION ( major minor -- n )
HRESULT ForwardTransform ( ID3D11UnorderedAccessView* pInputBuffer, ID3D11UnorderedAccessView** ppOutputBuffer )
HRESULT InverseTransform ( ID3D11UnorderedAccessView* pInputBuffer, ID3D11UnorderedAccessView** ppOutputBuffer ) ;
-C-ENUM:
+C-ENUM: D3DX11_FFT_DATA_TYPE
D3DX11_FFT_DATA_TYPE_REAL
D3DX11_FFT_DATA_TYPE_COMPLEX ;
-TYPEDEF: int D3DX11_FFT_DATA_TYPE
CONSTANT: D3DX11_FFT_DIM_MASK_1D 1
CONSTANT: D3DX11_FFT_DIM_MASK_2D 3
{ UsageIndex UINT } ;
TYPEDEF: D3DXSEMANTIC* LPD3DXSEMANTIC
-C-ENUM:
+C-ENUM: D3DXREGISTER_SET
D3DXRS_BOOL
D3DXRS_INT4
D3DXRS_FLOAT4
D3DXRS_SAMPLER ;
-TYPEDEF: int D3DXREGISTER_SET
TYPEDEF: D3DXREGISTER_SET* LPD3DXREGISTER_SET
-C-ENUM:
+C-ENUM: D3DXPARAMETER_CLASS
D3DXPC_SCALAR
D3DXPC_VECTOR
D3DXPC_MATRIX_ROWS
D3DXPC_MATRIX_COLUMNS
D3DXPC_OBJECT
D3DXPC_STRUCT ;
-TYPEDEF: int D3DXPARAMETER_CLASS
TYPEDEF: D3DXPARAMETER_CLASS* LPD3DXPARAMETER_CLASS
-C-ENUM:
+C-ENUM: D3DXPARAMETER_TYPE
D3DXPT_VOID
D3DXPT_BOOL
D3DXPT_INT
D3DXPT_PIXELFRAGMENT
D3DXPT_VERTEXFRAGMENT
D3DXPT_UNSUPPORTED ;
-TYPEDEF: int D3DXPARAMETER_TYPE
TYPEDEF: D3DXPARAMETER_TYPE* LPD3DXPARAMETER_TYPE
STRUCT: D3DXCONSTANTTABLE_DESC
HRESULT SetMatrixTransposeArray ( D3DXHANDLE hConstant, D3DXMATRIX* pMatrix, UINT Count )
HRESULT SetMatrixTransposePointerArray ( D3DXHANDLE hConstant, D3DXMATRIX** ppMatrix, UINT Count ) ;
-C-ENUM:
+C-ENUM: D3DXINCLUDE_TYPE
D3DXINC_LOCAL
D3DXINC_SYSTEM ;
-TYPEDEF: int D3DXINCLUDE_TYPE
TYPEDEF: D3DXINCLUDE_TYPE* LPD3DXINCLUDE_TYPE
C-TYPE: ID3DXInclude
USING: alien.c-types alien.syntax ;
IN: windows.directx.dcommon
-C-ENUM: DWRITE_MEASURING_MODE_NATURAL
- DWRITE_MEASURING_MODE_GDI_CLASSIC
- DWRITE_MEASURING_MODE_GDI_NATURAL ;
-TYPEDEF: int DWRITE_MEASURING_MODE
+C-ENUM: DWRITE_MEASURING_MODE
+ DWRITE_MEASURING_MODE_NATURAL
+ DWRITE_MEASURING_MODE_GDI_CLASSIC
+ DWRITE_MEASURING_MODE_GDI_NATURAL ;
LIBRARY: dwrite
-C-ENUM:
+C-ENUM: DWRITE_FONT_FILE_TYPE
DWRITE_FONT_FILE_TYPE_UNKNOWN
DWRITE_FONT_FILE_TYPE_CFF
DWRITE_FONT_FILE_TYPE_TRUETYPE
DWRITE_FONT_FILE_TYPE_TYPE1_PFB
DWRITE_FONT_FILE_TYPE_VECTOR
DWRITE_FONT_FILE_TYPE_BITMAP ;
-TYPEDEF: int DWRITE_FONT_FILE_TYPE
-C-ENUM:
+C-ENUM: DWRITE_FONT_FACE_TYPE
DWRITE_FONT_FACE_TYPE_CFF
DWRITE_FONT_FACE_TYPE_TRUETYPE
DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION
DWRITE_FONT_FACE_TYPE_VECTOR
DWRITE_FONT_FACE_TYPE_BITMAP
DWRITE_FONT_FACE_TYPE_UNKNOWN ;
-TYPEDEF: int DWRITE_FONT_FACE_TYPE
-
-CONSTANT: DWRITE_FONT_SIMULATIONS_NONE 0
-CONSTANT: DWRITE_FONT_SIMULATIONS_BOLD 1
-CONSTANT: DWRITE_FONT_SIMULATIONS_OBLIQUE 2
-TYPEDEF: int DWRITE_FONT_SIMULATIONS
-
-CONSTANT: DWRITE_FONT_WEIGHT_THIN 100
-CONSTANT: DWRITE_FONT_WEIGHT_EXTRA_LIGHT 200
-CONSTANT: DWRITE_FONT_WEIGHT_ULTRA_LIGHT 200
-CONSTANT: DWRITE_FONT_WEIGHT_LIGHT 300
-CONSTANT: DWRITE_FONT_WEIGHT_NORMAL 400
-CONSTANT: DWRITE_FONT_WEIGHT_REGULAR 400
-CONSTANT: DWRITE_FONT_WEIGHT_MEDIUM 500
-CONSTANT: DWRITE_FONT_WEIGHT_DEMI_BOLD 600
-CONSTANT: DWRITE_FONT_WEIGHT_SEMI_BOLD 600
-CONSTANT: DWRITE_FONT_WEIGHT_BOLD 700
-CONSTANT: DWRITE_FONT_WEIGHT_EXTRA_BOLD 800
-CONSTANT: DWRITE_FONT_WEIGHT_ULTRA_BOLD 800
-CONSTANT: DWRITE_FONT_WEIGHT_BLACK 900
-CONSTANT: DWRITE_FONT_WEIGHT_HEAVY 900
-CONSTANT: DWRITE_FONT_WEIGHT_EXTRA_BLACK 950
-CONSTANT: DWRITE_FONT_WEIGHT_ULTRA_BLACK 950
-TYPEDEF: int DWRITE_FONT_WEIGHT
-
-CONSTANT: DWRITE_FONT_STRETCH_UNDEFINED 0
-CONSTANT: DWRITE_FONT_STRETCH_ULTRA_CONDENSED 1
-CONSTANT: DWRITE_FONT_STRETCH_EXTRA_CONDENSED 2
-CONSTANT: DWRITE_FONT_STRETCH_CONDENSED 3
-CONSTANT: DWRITE_FONT_STRETCH_SEMI_CONDENSED 4
-CONSTANT: DWRITE_FONT_STRETCH_NORMAL 5
-CONSTANT: DWRITE_FONT_STRETCH_MEDIUM 5
-CONSTANT: DWRITE_FONT_STRETCH_SEMI_EXPANDED 6
-CONSTANT: DWRITE_FONT_STRETCH_EXPANDED 7
-CONSTANT: DWRITE_FONT_STRETCH_EXTRA_EXPANDED 8
-CONSTANT: DWRITE_FONT_STRETCH_ULTRA_EXPANDED 9
-TYPEDEF: int DWRITE_FONT_STRETCH
-
-C-ENUM:
+
+C-ENUM: DWRITE_FONT_SIMULATIONS
+ DWRITE_FONT_SIMULATIONS_NONE
+ DWRITE_FONT_SIMULATIONS_BOLD
+ DWRITE_FONT_SIMULATIONS_OBLIQUE ;
+
+C-ENUM: DWRITE_FONT_WEIGHT
+ { DWRITE_FONT_WEIGHT_THIN 100 }
+ { DWRITE_FONT_WEIGHT_EXTRA_LIGHT 200 }
+ { DWRITE_FONT_WEIGHT_ULTRA_LIGHT 200 }
+ { DWRITE_FONT_WEIGHT_LIGHT 300 }
+ { DWRITE_FONT_WEIGHT_NORMAL 400 }
+ { DWRITE_FONT_WEIGHT_REGULAR 400 }
+ { DWRITE_FONT_WEIGHT_MEDIUM 500 }
+ { DWRITE_FONT_WEIGHT_DEMI_BOLD 600 }
+ { DWRITE_FONT_WEIGHT_SEMI_BOLD 600 }
+ { DWRITE_FONT_WEIGHT_BOLD 700 }
+ { DWRITE_FONT_WEIGHT_EXTRA_BOLD 800 }
+ { DWRITE_FONT_WEIGHT_ULTRA_BOLD 800 }
+ { DWRITE_FONT_WEIGHT_BLACK 900 }
+ { DWRITE_FONT_WEIGHT_HEAVY 900 }
+ { DWRITE_FONT_WEIGHT_EXTRA_BLACK 950 }
+ { DWRITE_FONT_WEIGHT_ULTRA_BLACK 950 } ;
+
+C-ENUM: DWRITE_FONT_STRETCH
+ { DWRITE_FONT_STRETCH_UNDEFINED 0 }
+ { DWRITE_FONT_STRETCH_ULTRA_CONDENSED 1 }
+ { DWRITE_FONT_STRETCH_EXTRA_CONDENSED 2 }
+ { DWRITE_FONT_STRETCH_CONDENSED 3 }
+ { DWRITE_FONT_STRETCH_SEMI_CONDENSED 4 }
+ { DWRITE_FONT_STRETCH_NORMAL 5 }
+ { DWRITE_FONT_STRETCH_MEDIUM 5 }
+ { DWRITE_FONT_STRETCH_SEMI_EXPANDED 6 }
+ { DWRITE_FONT_STRETCH_EXPANDED 7 }
+ { DWRITE_FONT_STRETCH_EXTRA_EXPANDED 8 }
+ { DWRITE_FONT_STRETCH_ULTRA_EXPANDED 9 } ;
+
+C-ENUM: DWRITE_FONT_STYLE
DWRITE_FONT_STYLE_NORMAL
DWRITE_FONT_STYLE_OBLIQUE
DWRITE_FONT_STYLE_ITALIC ;
-TYPEDEF: int DWRITE_FONT_STYLE
-C-ENUM:
+C-ENUM: DWRITE_INFORMATIONAL_STRING_ID
DWRITE_INFORMATIONAL_STRING_NONE
DWRITE_INFORMATIONAL_STRING_COPYRIGHT_NOTICE
DWRITE_INFORMATIONAL_STRING_VERSION_STRINGS
DWRITE_INFORMATIONAL_STRING_PREFERRED_FAMILY_NAMES
DWRITE_INFORMATIONAL_STRING_PREFERRED_SUBFAMILY_NAMES
DWRITE_INFORMATIONAL_STRING_SAMPLE_TEXT ;
-TYPEDEF: int DWRITE_INFORMATIONAL_STRING_ID
STRUCT: DWRITE_FONT_METRICS
{ designUnitsPerEm USHORT }
{ advanceOffset FLOAT }
{ ascenderOffset FLOAT } ;
-C-ENUM:
+C-ENUM: DWRITE_FACTORY_TYPE
DWRITE_FACTORY_TYPE_SHARED
DWRITE_FACTORY_TYPE_ISOLATED ;
-TYPEDEF: int DWRITE_FACTORY_TYPE
C-TYPE: IDWriteFontFileStream
HRESULT GetLoader ( IDWriteFontFileLoader** fontFileLoader )
HRESULT Analyze ( BOOL* isSupportedFontType, DWRITE_FONT_FILE_TYPE* fontFileType, DWRITE_FONT_FACE_TYPE* fontFaceType, UINT32* numberOfFaces ) ;
-TYPEDEF: int DWRITE_PIXEL_GEOMETRY
-C-ENUM:
+C-ENUM: DWRITE_PIXEL_GEOMETRY
DWRITE_PIXEL_GEOMETRY_FLAT
DWRITE_PIXEL_GEOMETRY_RGB
DWRITE_PIXEL_GEOMETRY_BGR ;
-TYPEDEF: int DWRITE_RENDERING_MODE
-C-ENUM:
+C-ENUM: DWRITE_RENDERING_MODE
DWRITE_RENDERING_MODE_DEFAULT
DWRITE_RENDERING_MODE_ALIASED
DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC
HRESULT HasCharacter ( UINT32 unicodeValue, BOOL* exists )
HRESULT CreateFontFace ( IDWriteFontFace** fontFace ) ;
-TYPEDEF: int DWRITE_READING_DIRECTION
-C-ENUM:
+C-ENUM: DWRITE_READING_DIRECTION
DWRITE_READING_DIRECTION_LEFT_TO_RIGHT
DWRITE_READING_DIRECTION_RIGHT_TO_LEFT ;
-TYPEDEF: int DWRITE_FLOW_DIRECTION
-C-ENUM:
+C-ENUM: DWRITE_FLOW_DIRECTION
DWRITE_FLOW_DIRECTION_TOP_TO_BOTTOM ;
-TYPEDEF: int DWRITE_TEXT_ALIGNMENT
-C-ENUM:
+C-ENUM: DWRITE_TEXT_ALIGNMENT
DWRITE_TEXT_ALIGNMENT_LEADING
DWRITE_TEXT_ALIGNMENT_TRAILING
DWRITE_TEXT_ALIGNMENT_CENTER ;
-TYPEDEF: int DWRITE_PARAGRAPH_ALIGNMENT
-C-ENUM:
+C-ENUM: DWRITE_PARAGRAPH_ALIGNMENT
DWRITE_PARAGRAPH_ALIGNMENT_NEAR
DWRITE_PARAGRAPH_ALIGNMENT_FAR
DWRITE_PARAGRAPH_ALIGNMENT_CENTER ;
-TYPEDEF: int DWRITE_WORD_WRAPPING
-C-ENUM:
+C-ENUM: DWRITE_WORD_WRAPPING
DWRITE_WORD_WRAPPING_WRAP
DWRITE_WORD_WRAPPING_NO_WRAP ;
-TYPEDEF: int DWRITE_LINE_SPACING_METHOD
-C-ENUM:
+C-ENUM: DWRITE_LINE_SPACING_METHOD
DWRITE_LINE_SPACING_METHOD_DEFAULT
DWRITE_LINE_SPACING_METHOD_UNIFORM ;
-TYPEDEF: int DWRITE_TRIMMING_GRANULARITY
-C-ENUM:
+C-ENUM: DWRITE_TRIMMING_GRANULARITY
DWRITE_TRIMMING_GRANULARITY_NONE
DWRITE_TRIMMING_GRANULARITY_CHARACTER
DWRITE_TRIMMING_GRANULARITY_WORD ;
UINT32 GetFontFeatureCount ( )
HRESULT GetFontFeature ( UINT32 fontFeatureIndex, DWRITE_FONT_FEATURE* fontFeature ) ;
-CONSTANT: DWRITE_SCRIPT_SHAPES_DEFAULT 0
-CONSTANT: DWRITE_SCRIPT_SHAPES_NO_VISUAL 1
-TYPEDEF: int DWRITE_SCRIPT_SHAPES
+C-ENUM: DWRITE_SCRIPT_SHAPES
+ DWRITE_SCRIPT_SHAPES_DEFAULT
+ DWRITE_SCRIPT_SHAPES_NO_VISUAL ;
STRUCT: DWRITE_SCRIPT_ANALYSIS
{ script USHORT }
{ shapes DWRITE_SCRIPT_SHAPES } ;
-C-ENUM:
+C-ENUM: DWRITE_BREAK_CONDITION
DWRITE_BREAK_CONDITION_NEUTRAL
DWRITE_BREAK_CONDITION_CAN_BREAK
DWRITE_BREAK_CONDITION_MAY_NOT_BREAK
DWRITE_BREAK_CONDITION_MUST_BREAK ;
-TYPEDEF: int DWRITE_BREAK_CONDITION
STRUCT: DWRITE_LINE_BREAKPOINT
{ data BYTE } ;
-C-ENUM:
+C-ENUM: DWRITE_NUMBER_SUBSTITUTION_METHOD
DWRITE_NUMBER_SUBSTITUTION_METHOD_FROM_CULTURE
DWRITE_NUMBER_SUBSTITUTION_METHOD_CONTEXTUAL
DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE
DWRITE_NUMBER_SUBSTITUTION_METHOD_NATIONAL
DWRITE_NUMBER_SUBSTITUTION_METHOD_TRADITIONAL ;
-TYPEDEF: int DWRITE_NUMBER_SUBSTITUTION_METHOD
COM-INTERFACE: IDWriteNumberSubstitution IUnknown {14885CC9-BAB0-4f90-B6ED-5C366A2CD03D} ;
HRESULT CreateFontFaceFromHdc ( HDC hdc, IDWriteFontFace** fontFace )
HRESULT CreateBitmapRenderTarget ( HDC hdc, UINT32 width, UINT32 height, IDWriteBitmapRenderTarget** renderTarget ) ;
-C-ENUM: DWRITE_TEXTURE_ALIASED_1x1
- DWRITE_TEXTURE_CLEARTYPE_3x1 ;
-TYPEDEF: int DWRITE_TEXTURE_TYPE
+C-ENUM: DWRITE_TEXTURE_TYPE
+ DWRITE_TEXTURE_ALIASED_1x1
+ DWRITE_TEXTURE_CLEARTYPE_3x1 ;
CONSTANT: DWRITE_ALPHA_MAX 255
{ Numerator UINT }
{ Denominator UINT } ;
-C-ENUM: DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
- DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE
- DXGI_MODE_SCANLINE_ORDER_UPPER_FIELD_FIRST
- DXGI_MODE_SCANLINE_ORDER_LOWER_FIELD_FIRST ;
-TYPEDEF: int DXGI_MODE_SCANLINE_ORDER
+C-ENUM: DXGI_MODE_SCANLINE_ORDER
+ DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
+ DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE
+ DXGI_MODE_SCANLINE_ORDER_UPPER_FIELD_FIRST
+ DXGI_MODE_SCANLINE_ORDER_LOWER_FIELD_FIRST ;
-C-ENUM: DXGI_MODE_SCALING_UNSPECIFIED
- DXGI_MODE_SCALING_CENTERED
- DXGI_MODE_SCALING_STRETCHED ;
-TYPEDEF: int DXGI_MODE_SCALING
+C-ENUM: DXGI_MODE_SCALING
+ DXGI_MODE_SCALING_UNSPECIFIED
+ DXGI_MODE_SCALING_CENTERED
+ DXGI_MODE_SCALING_STRETCHED ;
-C-ENUM: DXGI_MODE_ROTATION_UNSPECIFIED
- DXGI_MODE_ROTATION_IDENTITY
- DXGI_MODE_ROTATION_ROTATE90
- DXGI_MODE_ROTATION_ROTATE180
- DXGI_MODE_ROTATION_ROTATE270 ;
-TYPEDEF: int DXGI_MODE_ROTATION
+C-ENUM: DXGI_MODE_ROTATION
+ DXGI_MODE_ROTATION_UNSPECIFIED
+ DXGI_MODE_ROTATION_IDENTITY
+ DXGI_MODE_ROTATION_ROTATE90
+ DXGI_MODE_ROTATION_ROTATE180
+ DXGI_MODE_ROTATION_ROTATE270 ;
STRUCT: DXGI_MODE_DESC
{ Width UINT }
{ pFormat WAVEFORMATEX* }
{ MaxFrameCount UINT32 } ;
-C-ENUM:
- XAPO_BUFFER_SILENT
- XAPO_BUFFER_VALID ;
-TYPEDEF: int XAPO_BUFFER_FLAGS
+C-ENUM: XAPO_BUFFER_FLAGS
+ XAPO_BUFFER_SILENT
+ XAPO_BUFFER_VALID ;
STRUCT: XAPO_PROCESS_BUFFER_PARAMETERS
{ pBuffer void* }
{ EffectCount UINT32 }
{ pEffectDescriptors XAUDIO2_EFFECT_DESCRIPTOR* } ;
-C-ENUM:
+C-ENUM: XAUDIO2_FILTER_TYPE
LowPassFilter
BandPassFilter
HighPassFilter
NotchFilter ;
-TYPEDEF: int XAUDIO2_FILTER_TYPE
STRUCT: XAUDIO2_FILTER_PARAMETERS
{ Type XAUDIO2_FILTER_TYPE }
! (c)2009 Joe Groff bsd license
-USING: alien.c-types alien.data alien.libraries alien.syntax
-classes.struct kernel math system-info.windows windows.types ;
+USING: alien alien.c-types alien.data alien.libraries
+alien.syntax classes.struct kernel math system-info.windows
+windows.types ;
IN: windows.dwmapi
STRUCT: MARGINS
: full-window-margins ( -- MARGINS )
-1 -1 -1 -1 <MARGINS> ; inline
-<< "dwmapi" "dwmapi.dll" "stdcall" add-library >>
+<< "dwmapi" "dwmapi.dll" stdcall add-library >>
LIBRARY: dwmapi
CONSTANT: THREAD_PRIORITY_NORMAL 0
CONSTANT: THREAD_PRIORITY_TIME_CRITICAL 15
-C-ENUM:
+C-ENUM: COMPUTER_NAME_FORMAT
ComputerNameNetBIOS
ComputerNameDnsHostname
ComputerNameDnsDomain
ComputerNamePhysicalDnsFullyQualified
ComputerNameMax ;
-TYPEDEF: uint COMPUTER_NAME_FORMAT
-
STRUCT: OVERLAPPED
{ internal UINT_PTR }
{ internal-high UINT_PTR }
USING: alien sequences alien.libraries ;
{
- { "advapi32" "advapi32.dll" "stdcall" }
- { "dinput" "dinput8.dll" "stdcall" }
- { "gdi32" "gdi32.dll" "stdcall" }
- { "user32" "user32.dll" "stdcall" }
- { "kernel32" "kernel32.dll" "stdcall" }
- { "winsock" "ws2_32.dll" "stdcall" }
- { "mswsock" "mswsock.dll" "stdcall" }
- { "shell32" "shell32.dll" "stdcall" }
- { "libc" "msvcrt.dll" "cdecl" }
- { "libm" "msvcrt.dll" "cdecl" }
- { "gl" "opengl32.dll" "stdcall" }
- { "glu" "glu32.dll" "stdcall" }
- { "ole32" "ole32.dll" "stdcall" }
- { "usp10" "usp10.dll" "stdcall" }
- { "psapi" "psapi.dll" "stdcall" }
- { "xinput" "xinput1_3.dll" "stdcall" }
- { "dxgi" "dxgi.dll" "stdcall" }
- { "d2d1" "d2d1.dll" "stdcall" }
- { "d3d9" "d3d9.dll" "stdcall" }
- { "d3d10" "d3d10.dll" "stdcall" }
- { "d3d10_1" "d3d10_1.dll" "stdcall" }
- { "d3d11" "d3d11.dll" "stdcall" }
- { "d3dcompiler" "d3dcompiler_42.dll" "stdcall" }
- { "d3dcsx" "d3dcsx_42.dll" "stdcall" }
- { "d3dx9" "d3dx9_42.dll" "stdcall" }
- { "d3dx10" "d3dx10_42.dll" "stdcall" }
- { "d3dx11" "d3dx11_42.dll" "stdcall" }
- { "dwrite" "dwrite.dll" "stdcall" }
- { "x3daudio" "x3daudio1_6.dll" "stdcall" }
- { "xactengine" "xactengine3_5.dll" "stdcall" }
- { "xapofx" "xapofx1_3.dll" "stdcall" }
- { "xaudio2" "xaudio2_5.dll" "stdcall" }
+ { "advapi32" "advapi32.dll" stdcall }
+ { "dinput" "dinput8.dll" stdcall }
+ { "gdi32" "gdi32.dll" stdcall }
+ { "user32" "user32.dll" stdcall }
+ { "kernel32" "kernel32.dll" stdcall }
+ { "winsock" "ws2_32.dll" stdcall }
+ { "mswsock" "mswsock.dll" stdcall }
+ { "shell32" "shell32.dll" stdcall }
+ { "libc" "msvcrt.dll" cdecl }
+ { "libm" "msvcrt.dll" cdecl }
+ { "gl" "opengl32.dll" stdcall }
+ { "glu" "glu32.dll" stdcall }
+ { "ole32" "ole32.dll" stdcall }
+ { "usp10" "usp10.dll" stdcall }
+ { "psapi" "psapi.dll" stdcall }
+ { "xinput" "xinput1_3.dll" stdcall }
+ { "dxgi" "dxgi.dll" stdcall }
+ { "d2d1" "d2d1.dll" stdcall }
+ { "d3d9" "d3d9.dll" stdcall }
+ { "d3d10" "d3d10.dll" stdcall }
+ { "d3d10_1" "d3d10_1.dll" stdcall }
+ { "d3d11" "d3d11.dll" stdcall }
+ { "d3dcompiler" "d3dcompiler_42.dll" stdcall }
+ { "d3dcsx" "d3dcsx_42.dll" stdcall }
+ { "d3dx9" "d3dx9_42.dll" stdcall }
+ { "d3dx10" "d3dx10_42.dll" stdcall }
+ { "d3dx11" "d3dx11_42.dll" stdcall }
+ { "dwrite" "dwrite.dll" stdcall }
+ { "x3daudio" "x3daudio1_6.dll" stdcall }
+ { "xactengine" "xactengine3_5.dll" stdcall }
+ { "xapofx" "xapofx1_3.dll" stdcall }
+ { "xaudio2" "xaudio2_5.dll" stdcall }
} [ first3 add-library ] each
int* piLogicalToVisual
) ;
-C-ENUM: SCRIPT_JUSTIFY_NONE
-SCRIPT_JUSTIFY_ARABIC_BLANK
-SCRIPT_JUSTIFY_CHARACTER
-SCRIPT_JUSTIFY_RESERVED1
-SCRIPT_JUSTIFY_BLANK
-SCRIPT_JUSTIFY_RESERVED2
-SCRIPT_JUSTIFY_RESERVED3
-SCRIPT_JUSTIFY_ARABIC_NORMAL
-SCRIPT_JUSTIFY_ARABIC_KASHIDA
-SCRIPT_JUSTIFY_ALEF
-SCRIPT_JUSTIFY_HA
-SCRIPT_JUSTIFY_RA
-SCRIPT_JUSTIFY_BA
-SCRIPT_JUSTIFY_BARA
-SCRIPT_JUSTIFY_SEEN
-SCRIPT_JUSTIFFY_RESERVED4 ;
+C-ENUM: f
+ SCRIPT_JUSTIFY_NONE
+ SCRIPT_JUSTIFY_ARABIC_BLANK
+ SCRIPT_JUSTIFY_CHARACTER
+ SCRIPT_JUSTIFY_RESERVED1
+ SCRIPT_JUSTIFY_BLANK
+ SCRIPT_JUSTIFY_RESERVED2
+ SCRIPT_JUSTIFY_RESERVED3
+ SCRIPT_JUSTIFY_ARABIC_NORMAL
+ SCRIPT_JUSTIFY_ARABIC_KASHIDA
+ SCRIPT_JUSTIFY_ALEF
+ SCRIPT_JUSTIFY_HA
+ SCRIPT_JUSTIFY_RA
+ SCRIPT_JUSTIFY_BA
+ SCRIPT_JUSTIFY_BARA
+ SCRIPT_JUSTIFY_SEEN
+ SCRIPT_JUSTIFFY_RESERVED4 ;
STRUCT: SCRIPT_VISATTR
{ flags WORD } ;
USING: alien alien.c-types alien.strings alien.syntax arrays
byte-arrays kernel literals math sequences windows.types
windows.kernel32 windows.errors math.bitwise io.encodings.utf16n
-classes.struct windows.com.syntax init literals ;
+classes.struct windows.com.syntax init ;
FROM: alien.c-types => short ;
IN: windows.winsock
! * EXTENDED WINDOW MANAGER HINTS
! *****************************************************************
-C-ENUM: _NET_WM_STATE_REMOVE _NET_WM_STATE_ADD _NET_WM_STATE_TOGGLE ;
+C-ENUM: f _NET_WM_STATE_REMOVE _NET_WM_STATE_ADD _NET_WM_STATE_TOGGLE ;
IN: x11.syntax
SYNTAX: X-FUNCTION:
- (FUNCTION:)
+ (FUNCTION:) make-function
[ \ awaken-event-loop suffix ] dip
- define-declared ;
\ No newline at end of file
+ define-declared ;
sequences ;
IN: alien
+HELP: cdecl
+{ $description "This symbol is passed as the " { $snippet "abi" } " argument to " { $link alien-indirect } ", " { $link alien-callback } ", " { $link alien-assembly } ", and " { $link add-library } " to indicate that the standard C calling convention should be used, where the caller cleans up the stack frame after calling the function. This symbol only has meaning on 32-bit x86 platforms." } ;
+
+HELP: stdcall
+{ $description "This symbol is passed as the " { $snippet "abi" } " argument to " { $link alien-indirect } ", " { $link alien-callback } ", " { $link alien-assembly } ", and " { $link add-library } " to indicate that the Windows API calling convention should be used, where the called function cleans up its own stack frame before returning to the caller. This symbol only has meaning on 32-bit x86 platforms." } ;
+
+HELP: fastcall
+{ $warning "In the current implementation this ABI only works for functions that take only integer and pointer arguments." }
+{ $description "This symbol is passed as the " { $snippet "abi" } " argument to " { $link alien-indirect } ", " { $link alien-callback } ", " { $link alien-assembly } ", and " { $link add-library } " to indicate that the \"fast call\" calling convention should be used, where the first two integer or pointer arguments are passed in registers and the function cleans up its own stack frame before returning to the caller. This symbol only has meaning on 32-bit x86 platforms." } ;
+
+HELP: thiscall
+{ $description "This symbol is passed as the " { $snippet "abi" } " argument to " { $link alien-indirect } ", " { $link alien-callback } ", " { $link alien-assembly } ", and " { $link add-library } " to indicate that Microsoft Visual C++ calling convention should be used, where the first argument (which must be a \"this\" pointer) is passed in a register and the function cleans up its own stack frame before returning to the caller. This symbol only has meaning on 32-bit x86 platforms." } ;
+
+{ cdecl stdcall fastcall thiscall } related-words
+
HELP: >c-ptr
{ $values { "obj" object } { "c-ptr" c-ptr } }
{ $contract "Outputs a pointer to the binary data of this object." } ;
} ;
HELP: alien-indirect
-{ $values { "args..." "zero or more objects passed to the C function" } { "funcptr" "a C function pointer" } { "return" "a C return type" } { "parameters" "a sequence of C parameter types" } { "abi" "one of " { $snippet "\"cdecl\"" } " or " { $snippet "\"stdcall\"" } } { "return..." "the return value of the function, if not " { $link void } } }
+{ $values { "args..." "zero or more objects passed to the C function" } { "funcptr" "a C function pointer" } { "return" "a C return type" } { "parameters" "a sequence of C parameter types" } { "abi" "one of " { $link cdecl } " or " { $link stdcall } } { "return..." "the return value of the function, if not " { $link void } } }
{ $description
"Invokes a C function pointer passed on the data stack. Input parameters are taken from the data stack following the function pointer, and the return value is pushed on the data stack after the function returns. A return type of " { $link void } " indicates that no value is to be expected."
}
} ;
HELP: alien-callback
-{ $values { "return" "a C return type" } { "parameters" "a sequence of C parameter types" } { "abi" "one of " { $snippet "\"cdecl\"" } " or " { $snippet "\"stdcall\"" } } { "quot" quotation } { "alien" alien } }
+{ $values { "return" "a C return type" } { "parameters" "a sequence of C parameter types" } { "abi" "one of " { $link cdecl } " or " { $link stdcall } } { "quot" quotation } { "alien" alien } }
{ $description
"Defines a callback from C to Factor which accepts the given set of parameters from the C caller, pushes them on the data stack, calls the quotation, and passes a return value back to the C caller. A return type of " { $snippet "void" } " indicates that no value is to be returned."
$nl
"A simple example, showing a C function which returns the difference of two given integers:"
{ $code
": difference-callback ( -- alien )"
- " int { int int } \"cdecl\" [ - ] alien-callback ;"
+ " int { int int } cdecl [ - ] alien-callback ;"
}
}
{ $errors "Throws an " { $link alien-callback-error } " if the word calling " { $link alien-callback } " is not compiled." } ;
} ;
HELP: alien-assembly
-{ $values { "args..." "zero or more objects passed to the C function" } { "return" "a C return type" } { "parameters" "a sequence of C parameter types" } { "abi" "one of " { $snippet "\"cdecl\"" } " or " { $snippet "\"stdcall\"" } } { "quot" quotation } { "return..." "the return value of the function, if not " { $link void } } }
+{ $values { "args..." "zero or more objects passed to the C function" } { "return" "a C return type" } { "parameters" "a sequence of C parameter types" } { "abi" "one of " { $link cdecl } " or " { $link stdcall } } { "quot" quotation } { "return..." "the return value of the function, if not " { $link void } } }
{ $description
"Invokes arbitrary machine code, generated at compile-time by the quotation. Input parameters are taken from the data stack, and the return value is pushed on the data stack after the function returns. A return type of " { $link void } " indicates that no value is to be expected."
}
{ $subsections
POSTPONE: LIBRARY:
POSTPONE: FUNCTION:
+ POSTPONE: FUNCTION-ALIAS:
}
"The above parsing words create word definitions which call a lower-level word; you can use it directly, too:"
{ $subsections alien-invoke }
M: pinned-alien hashcode*
nip dup expired>> [ drop 1234 ] [ alien-address ] if ;
+SINGLETONS: stdcall thiscall fastcall cdecl mingw ;
+
+UNION: abi stdcall thiscall fastcall cdecl mingw ;
+
+: callee-cleanup? ( abi -- ? )
+ { stdcall fastcall thiscall } member? ;
+
ERROR: alien-callback-error ;
: alien-callback ( return parameters abi quot -- alien )
{ $contract "Creates a new assoc of the same size as " { $snippet "exemplar" } " which can hold " { $snippet "capacity" } " entries before growing." } ;
HELP: assoc-find
-{ $values { "assoc" assoc } { "quot" { $quotation "( key value -- ? )" } } { "key" "the successful key, or f" } { "value" "the successful value, or f" } { "?" "a boolean" } }
+{ $values { "assoc" assoc } { "quot" { $quotation "( ... key value -- ... ? )" } } { "key" "the successful key, or f" } { "value" "the successful value, or f" } { "?" "a boolean" } }
{ $description "Applies a predicate quotation to each entry in the assoc. Returns the key and value that the quotation succeeds on, or " { $link f } " for both if the quotation fails. It also returns a boolean describing whether there was anything found; this can be used to distinguish between a key and a value equal to " { $link f } ", or nothing being found." } ;
HELP: clear-assoc
{ $description "Looks up the value associated with a key. If the key was not present, an error can be thrown without extra stack shuffling. This word handles assocs that store " { $link f } "." } ;
HELP: assoc-each
-{ $values { "assoc" assoc } { "quot" { $quotation "( key value -- )" } } }
+{ $values { "assoc" assoc } { "quot" { $quotation "( ... key value -- ... )" } } }
{ $description "Applies a quotation to each entry in the assoc." }
{ $examples
{ $example
} ;
HELP: assoc-map
-{ $values { "assoc" assoc } { "quot" { $quotation "( key value -- newkey newvalue )" } } { "newassoc" "a new assoc" } }
+{ $values { "assoc" assoc } { "quot" { $quotation "( ... key value -- ... newkey newvalue )" } } { "newassoc" "a new assoc" } }
{ $description "Applies the quotation to each entry in the input assoc and collects the results in a new assoc of the same type as the input." }
{ $examples
{ $unchecked-example
{ assoc-map assoc-map-as } related-words
HELP: assoc-filter
-{ $values { "assoc" assoc } { "quot" { $quotation "( key value -- ? )" } } { "subassoc" "a new assoc" } }
+{ $values { "assoc" assoc } { "quot" { $quotation "( ... key value -- ... ? )" } } { "subassoc" "a new assoc" } }
{ $description "Outputs an assoc of the same type as " { $snippet "assoc" } " consisting of all entries for which the predicate quotation yields true." } ;
HELP: assoc-filter-as
-{ $values { "assoc" assoc } { "quot" { $quotation "( key value -- ? )" } } { "exemplar" assoc } { "subassoc" "a new assoc" } }
+{ $values { "assoc" assoc } { "quot" { $quotation "( ... key value -- ... ? )" } } { "exemplar" assoc } { "subassoc" "a new assoc" } }
{ $description "Outputs an assoc of the same type as " { $snippet "exemplar" } " consisting of all entries for which the predicate quotation yields true." } ;
HELP: assoc-filter!
-{ $values { "assoc" assoc } { "quot" { $quotation "( key value -- ? )" } } }
+{ $values { "assoc" assoc } { "quot" { $quotation "( ... key value -- ... ? )" } } }
{ $description "Removes all entries for which the predicate quotation yields true." }
{ $side-effects "assoc" } ;
{ $description "Calls a predicate quotation on each key of the input assoc. If the test yields true, the key/value pair is added to " { $snippet "true-assoc" } "; if false, it's added to " { $snippet "false-assoc" } "." } ;
HELP: assoc-any?
-{ $values { "assoc" assoc } { "quot" { $quotation "( key value -- ? )" } } { "?" "a boolean" } }
+{ $values { "assoc" assoc } { "quot" { $quotation "( ... key value -- ... ? )" } } { "?" "a boolean" } }
{ $description "Tests if the assoc contains an entry satisfying a predicate by applying the quotation to each entry in turn. Iteration stops if an entry is found for which the quotation outputs a true value." } ;
HELP: assoc-all?
-{ $values { "assoc" assoc } { "quot" { $quotation "( key value -- ? )" } } { "?" "a boolean" } }
+{ $values { "assoc" assoc } { "quot" { $quotation "( ... key value -- ... ? )" } } { "?" "a boolean" } }
{ $description "Tests if all entries in the assoc satisfy a predicate by applying the quotation to each entry in turn. a predicate quotation to entry in the assoc. Iteration stops if an entry is found for which the quotation outputs " { $link f } ". If the assoc is empty, always outputs " { $link t } "." } ;
HELP: assoc-subset?
{ $description "Creates a new sequence where elements of " { $snippet "seq" } " which appear as keys in " { $snippet "assoc" } " are replaced by the corresponding values, and all other elements are unchanged." } ;
HELP: cache
-{ $values { "key" "a key" } { "assoc" assoc } { "quot" { $quotation "( key -- value )" } } { "value" "a previously-retained or freshly-computed value" } }
+{ $values { "key" "a key" } { "assoc" assoc } { "quot" { $quotation "( ... key -- ... value )" } } { "value" "a previously-retained or freshly-computed value" } }
{ $description "If the key is present in the assoc, outputs the associated value, otherwise calls the quotation to produce a value and stores the key/value pair into the assoc. Returns a value either looked up or newly stored in the assoc." }
{ $side-effects "assoc" } ;
HELP: 2cache
-{ $values { "key1" "a key" } { "key2" "a key" } { "assoc" assoc } { "quot" { $quotation "( key1 key2 -- value )" } } { "value" "a previously-retained or freshly-computed value" } }
+{ $values { "key1" "a key" } { "key2" "a key" } { "assoc" assoc } { "quot" { $quotation "( ... key1 key2 -- ... value )" } } { "value" "a previously-retained or freshly-computed value" } }
{ $description "If a single key composed of the input keys is present in the assoc, outputs the associated value, otherwise calls the quotation to produce a value and stores the keys/value pair into the assoc. Returns the value stored in the assoc. Returns a value either looked up or newly stored in the assoc." }
{ $side-effects "assoc" } ;
HELP: map>assoc
-{ $values { "seq" "a sequence" } { "quot" { $quotation "( elt -- key value )" } } { "exemplar" assoc } { "assoc" "a new assoc" } }
+{ $values { "seq" "a sequence" } { "quot" { $quotation "( ... elt -- ... key value )" } } { "exemplar" assoc } { "assoc" "a new assoc" } }
{ $description "Applies the quotation to each element of the sequence, and collects the keys and values into a new assoc having the same type as " { $snippet "exemplar" } "." } ;
HELP: assoc>map
-{ $values { "assoc" assoc } { "quot" { $quotation "( key value -- elt )" } } { "exemplar" "a sequence" } { "seq" "a new sequence" } }
+{ $values { "assoc" assoc } { "quot" { $quotation "( ... key value -- ... elt )" } } { "exemplar" "a sequence" } { "seq" "a new sequence" } }
{ $description "Applies the quotation to each entry of the assoc and collects the results into a new sequence of the same type as the exemplar." } ;
HELP: change-at
-{ $values { "key" object } { "assoc" assoc } { "quot" { $quotation "( value -- newvalue )" } } }
+{ $values { "key" object } { "assoc" assoc } { "quot" { $quotation "( ..a value -- ..b newvalue )" } } }
{ $description "Applies the quotation to the value associated with " { $snippet "key" } ", storing the new value back in the assoc." }
{ $side-effects "assoc" } ;
HELP: assoc-map-as
{ $values
- { "assoc" assoc } { "quot" { $quotation "( key value -- newkey newvalue )" } } { "exemplar" assoc }
+ { "assoc" assoc } { "quot" { $quotation "( ... key value -- ... newkey newvalue )" } } { "exemplar" assoc }
{ "newassoc" assoc } }
{ $description "Applies the quotation to each entry in the input assoc and collects the results in a new assoc of the stame type as the exemplar." }
{ $examples { $example "USING: prettyprint assocs hashtables math ;" " H{ { 1 2 } { 3 4 } } [ sq ] { } assoc-map-as ." "{ { 1 4 } { 3 16 } }" } } ;
PRIVATE>
-: assoc-find ( assoc quot -- key value ? )
+: assoc-find ( ... assoc quot: ( ... key value -- ... ? ) -- ... key value ? )
(assoc-each) find swap [ first2 t ] [ drop f f f ] if ; inline
: key? ( key assoc -- ? ) at* nip ; inline
-: assoc-each ( assoc quot -- )
+: assoc-each ( ... assoc quot: ( ... key value -- ... ) -- ... )
(assoc-each) each ; inline
-: assoc>map ( assoc quot exemplar -- seq )
+: assoc>map ( ... assoc quot: ( ... key value -- ... elt ) exemplar -- ... seq )
[ collector-for [ assoc-each ] dip ] [ like ] bi ; inline
-: assoc-map-as ( assoc quot exemplar -- newassoc )
+: assoc-map-as ( ... assoc quot: ( ... key value -- ... newkey newvalue ) exemplar -- ... newassoc )
[ [ 2array ] compose V{ } assoc>map ] dip assoc-like ; inline
-: assoc-map ( assoc quot -- newassoc )
+: assoc-map ( ... assoc quot: ( ... key value -- ... newkey newvalue ) -- ... newassoc )
over assoc-map-as ; inline
-: assoc-filter-as ( assoc quot exemplar -- subassoc )
+: assoc-filter-as ( ... assoc quot: ( ... key value -- ... ? ) exemplar -- ... subassoc )
[ (assoc-each) filter ] dip assoc-like ; inline
-: assoc-filter ( assoc quot -- subassoc )
+: assoc-filter ( ... assoc quot: ( ... key value -- ... ? ) -- ... subassoc )
over assoc-filter-as ; inline
-: assoc-filter! ( assoc quot -- assoc )
+: assoc-filter! ( ... assoc quot: ( ... key value -- ... ? ) -- ... assoc )
[
over [ [ [ drop ] 2bi ] dip [ delete-at ] 2curry unless ] 2curry
assoc-each
] [ drop ] 2bi ; inline
-: assoc-partition ( assoc quot -- true-assoc false-assoc )
+: assoc-partition ( ... assoc quot: ( ... key value -- ... ? ) -- ... true-assoc false-assoc )
[ (assoc-each) partition ] [ drop ] 2bi
[ assoc-like ] curry bi@ ; inline
-: assoc-any? ( assoc quot -- ? )
+: assoc-any? ( ... assoc quot: ( ... key value -- ... ? ) -- ... ? )
assoc-find 2nip ; inline
-: assoc-all? ( assoc quot -- ? )
+: assoc-all? ( ... assoc quot: ( ... key value -- ... ? ) -- ... ? )
[ not ] compose assoc-any? not ; inline
: at ( key assoc -- value/f )
: substitute ( seq assoc -- newseq )
substituter map ;
-: cache ( key assoc quot -- value )
+: cache ( ... key assoc quot: ( ... key -- ... value ) -- ... value )
[ [ at* ] 2keep ] dip
[ [ nip call dup ] [ drop ] 3bi set-at ] 3curry
[ drop ] prepose
unless ; inline
-: 2cache ( key1 key2 assoc quot -- value )
+: 2cache ( ... key1 key2 assoc quot: ( ... key1 key2 -- ... value ) -- ... value )
[ 2array ] 2dip [ first2 ] prepose cache ; inline
-: change-at ( key assoc quot -- )
+: change-at ( ..a key assoc quot: ( ..a value -- ..b newvalue ) -- ..b )
[ [ at ] dip call ] [ drop ] 3bi set-at ; inline
: at+ ( n key assoc -- ) [ 0 or + ] change-at ; inline
: inc-at ( key assoc -- ) [ 1 ] 2dip at+ ; inline
-: map>assoc ( seq quot exemplar -- assoc )
+: map>assoc ( ... seq quot: ( ... elt -- ... key value ) exemplar -- ... assoc )
[ [ 2array ] compose { } map-as ] dip assoc-like ; inline
: extract-keys ( seq assoc -- subassoc )
{ "byte-array>bignum" "math" "primitive_byte_array_to_bignum" (( x -- y )) }
{ "double>bits" "math" "primitive_double_bits" (( x -- n )) }
{ "float>bits" "math" "primitive_float_bits" (( x -- n )) }
- { "(float>string)" "math.parser.private" "primitive_float_to_str" (( n -- str )) }
+ { "(format-float)" "math.parser.private" "primitive_format_float" (( n format -- byte-array )) }
{ "bignum*" "math.private" "primitive_bignum_multiply" (( x y -- z )) }
{ "bignum+" "math.private" "primitive_bignum_add" (( x y -- z )) }
{ "bignum-" "math.private" "primitive_bignum_subtract" (( x y -- z )) }
"read-only"
"call("
"execute("
+ "<<<<<<"
+ "======"
+ ">>>>>>"
+ "<<<<<<<"
+ "======="
+ ">>>>>>>"
} [ "syntax" create drop ] each
"t" "syntax" lookup define-symbol
[ 7 ] [ 1 3 [ 2 * ] [ + ] compose compile-call(-test-1 ] unit-test
[ 4 ] [ 1 3 [ { + } [ ] like call ] compile-call(-test-1 ] unit-test
+[ [ ] call( -- * ) ] must-fail
+
+: compile-call(-test-2 ( -- ) [ ] call( -- * ) ;
+
+[ compile-call(-test-2 ] [ wrong-values? ] must-fail-with
+
+: compile-call(-test-3 ( quot -- ) call( -- * ) ;
+
+[ [ ] compile-call(-test-3 ] [ wrong-values? ] must-fail-with
+
+: compile-execute(-test-3 ( a -- ) \ . execute( value -- * ) ;
+
+[ 10 compile-execute(-test-3 ] [ wrong-values? ] must-fail-with
+
+: compile-execute(-test-4 ( a word -- ) execute( value -- * ) ;
+
+[ 10 \ . compile-execute(-test-4 ] [ wrong-values? ] must-fail-with
+
! Compiled
: cond-test-1 ( obj -- str )
{
! We can't USE: effects here so we forward reference slots instead
SLOT: in
SLOT: out
+SLOT: terminated?
: call-effect ( quot effect -- )
! Don't use fancy combinators here, since this word always
! runs unoptimized
- [ datastack ] 2dip
2dup [
- [ dip ] dip
- dup in>> length swap out>> length
- check-datastack
+ [ [ datastack ] dip dip ] dip
+ dup terminated?>> [ 2drop f ] [
+ dup in>> length swap out>> length
+ check-datastack
+ ] if
] 2dip rot
[ 2drop ] [ wrong-values ] if ;
M: hash-set adjoin table>> dupd set-at ; inline
M: hash-set delete table>> delete-at ; inline
M: hash-set members table>> keys ; inline
-M: hash-set set-like
- drop dup hash-set? [ members <hash-set> ] unless ;
-M: hash-set clone
- table>> clone hash-set boa ;
+M: hash-set set-like drop dup hash-set? [ members <hash-set> ] unless ;
+M: hash-set clone table>> clone hash-set boa ;
M: sequence fast-set <hash-set> ;
M: f fast-set drop H{ } clone hash-set boa ;
M: sequence duplicates
f fast-set [ [ in? ] [ adjoin ] 2bi ] curry filter ;
+
+<PRIVATE
+
+: (all-unique?) ( elt hash -- ? )
+ 2dup in? [ 2drop f ] [ adjoin t ] if ; inline
+
+PRIVATE>
+
+M: sequence all-unique?
+ dup length <hashtable> hash-set boa
+ [ (all-unique?) ] curry all? ;
io.encodings.8-bit.latin1 io.encodings.ascii
io.encodings.binary io.encodings.string io.files
io.files.private io.files.temp io.files.unique kernel make math
-sequences specialized-arrays system threads tools.test ;
+sequences specialized-arrays system threads tools.test vocabs
+compiler.units ;
+FROM: specialized-arrays.private => specialized-array-vocab ;
SPECIALIZED-ARRAY: int
IN: io.files.tests
pt-array-1 rest-slice sequence=
] unit-test
+[ ] [
+ [
+ pt specialized-array-vocab forget-vocab
+ ] with-compilation-unit
+] unit-test
+
! Writing strings to binary streams should fail
[
"test.txt" temp-file binary [
{ $values { "?" "a generalized boolean" } { "true" quotation } { "false" quotation } }
{ $description "If " { $snippet "cond" } " is " { $link f } ", calls the " { $snippet "false" } " quotation. Otherwise calls the " { $snippet "true" } " quotation."
$nl
-"The " { $snippet "cond" } " value is removed from the stack before either quotation is called." } ;
+"The " { $snippet "cond" } " value is removed from the stack before either quotation is called." }
+{ $examples
+ { $example
+ "USING: io kernel math ;"
+ "10 3 < [ \"Math is broken\" print ] [ \"Math is good\" print ] if"
+ "Math is good"
+ }
+} ;
HELP: when
{ $values { "?" "a generalized boolean" } { "true" quotation } }
{ $description "If " { $snippet "cond" } " is not " { $link f } ", calls the " { $snippet "true" } " quotation."
$nl
-"The " { $snippet "cond" } " value is removed from the stack before the quotation is called." } ;
+"The " { $snippet "cond" } " value is removed from the stack before the quotation is called." }
+{ $examples
+ { $example
+ "USING: kernel math prettyprint ;"
+ "-5 dup 0 < [ 3 + ] when ."
+ "-2"
+ }
+} ;
HELP: unless
{ $values { "?" "a generalized boolean" } { "false" quotation } }
{ $description "If " { $snippet "cond" } " is " { $link f } ", calls the " { $snippet "false" } " quotation."
$nl
-"The " { $snippet "cond" } " value is removed from the stack before the quotation is called." } ;
+"The " { $snippet "cond" } " value is removed from the stack before the quotation is called." }
+{ $examples
+ { $example
+ "USING: kernel math prettyprint sequences ;"
+ "IN: scratchpad"
+ ""
+ "CONSTANT: american-cities {"
+ " \"San Francisco\""
+ " \"Los Angeles\""
+ " \"New York\""
+ "}"
+ ""
+ ": add-tax ( price city -- price' )"
+ " american-cities member? [ 1.1 * ] unless ;"
+ ""
+ "123 \"Ottawa\" add-tax ."
+ "135.3"
+ }
+} ;
HELP: if*
{ $values { "?" "a generalized boolean" } { "true" { $quotation "( ..a ? -- ..b )" } } { "false" { $quotation "( ..a -- ..b )" } } }
"If the condition is true, it is retained on the stack before the " { $snippet "true" } " quotation is called. Otherwise, the condition is removed from the stack and the " { $snippet "false" } " quotation is called."
$nl
"The following two lines are equivalent:"
-{ $code "X [ Y ] [ Z ] if*" "X dup [ Y ] [ drop Z ] if" } } ;
+{ $code "X [ Y ] [ Z ] if*" "X dup [ Y ] [ drop Z ] if" } }
+{ $examples
+ "Notice how in this example, the same value is tested by the conditional, and then used in the true branch; the false branch does not need to drop the value because of how " { $link if* } " works:"
+ { $example
+ "USING: assocs io kernel math.parser ;"
+ "IN: scratchpad"
+ ""
+ ": curry-price ( meat -- price )
+ {
+ { \"Beef\" 10 }
+ { \"Chicken\" 12 }
+ { \"Lamb\" 13 }
+ } at ;
+
+: order-curry ( meat -- )
+ curry-price [
+ \"Your order will be \" write
+ number>string write
+ \" dollars.\" write
+ ] [ \"Invalid order.\" print ] if* ;"
+ ""
+ "\"Deer\" order-curry"
+ "Invalid order."
+ }
+} ;
HELP: when*
{ $values { "?" "a generalized boolean" } { "true" { $quotation "( cond -- ... )" } } }
! (c)2009 Joe Groff bsd license
-USING: accessors combinators kernel kernel.private math
-namespaces sequences sequences.private splitting strings make ;
+USING: accessors byte-arrays combinators kernel kernel.private
+math namespaces sequences sequences.private splitting strings
+make ;
IN: math.parser
: digit> ( ch -- n )
mantissa-expt [ float>hex-value ] [ float>hex-expt ] bi*
] bi 3append ;
-: float>decimal ( n -- str )
- (float>string)
- [ 0 = ] trim-tail >string
+: format-float ( n format -- string )
+ 0 suffix >byte-array (format-float)
+ dup [ 0 = ] find drop head >string
fix-float ;
: float>base ( n base -- str )
{
{ 16 [ float>hex ] }
- [ drop float>decimal ]
+ [ drop "%.16g" format-float ]
} case ; inline
PRIVATE>
: ?run-file ( path -- )
dup exists? [ run-file ] [ drop ] if ;
+
+ERROR: version-control-merge-conflict ;
HELP: accumulate
{ $values { "seq" sequence } { "identity" object } { "quot" { $quotation "( ... prev elt -- ... next )" } } { "final" "the final result" } { "newseq" "a new array" } }
-{ $description "Combines successive elements of the sequence using a binary operation, and outputs an array of intermediate results, together with the final result."
+{ $description "Combines successive elements of the sequence using a binary operation, and outputs a sequence of intermediate results, together with the final result."
$nl
"The first element of the new sequence is " { $snippet "identity" } ". Then, on the first iteration, the two inputs to the quotation are " { $snippet "identity" } ", and the first element of the old sequence. On successive iterations, the first input is the result of the previous iteration, and the second input is the corresponding element of the old sequence."
$nl
[ 5040 { 1 1 2 6 24 120 720 } ]
[ { 1 2 3 4 5 6 7 } 1 [ * ] accumulate ] unit-test
+[ 64 B{ 1 2 4 16 } ]
+[ B{ 2 2 4 4 } 1 [ * ] accumulate ] unit-test
+
[ 5040 { 1 1 2 6 24 120 720 } ]
[ { 1 2 3 4 5 6 7 } 1 [ * ] accumulate! ] unit-test
[ (accumulate) ] dip map-as ; inline
: accumulate ( ... seq identity quot: ( ... prev elt -- ... next ) -- ... final newseq )
- { } accumulate-as ; inline
+ pick accumulate-as ; inline
: accumulate! ( ... seq identity quot: ( ... prev elt -- ... next ) -- ... final seq )
(accumulate) map! ; inline
M: sequence members
[ pruned ] keep like ;
-M: sequence all-unique?
- dup pruned sequence= ;
-
: combine ( sets -- set )
[ f ]
[ [ [ members ] map concat ] [ first ] bi set-like ]
"call(" [ \ call-effect parse-call( ] define-core-syntax
"execute(" [ \ execute-effect parse-call( ] define-core-syntax
+
+ "<<<<<<<" [ version-control-merge-conflict ] define-core-syntax
+ "=======" [ version-control-merge-conflict ] define-core-syntax
+ ">>>>>>>" [ version-control-merge-conflict ] define-core-syntax
+
+ "<<<<<<" [ version-control-merge-conflict ] define-core-syntax
+ "======" [ version-control-merge-conflict ] define-core-syntax
+ ">>>>>>" [ version-control-merge-conflict ] define-core-syntax
] with-compilation-unit
--- /dev/null
+! (c)2010 Joe Groff bsd license
+USING: alien kernel ;
+IN: alien.cxx
+
+SINGLETONS: g++ visual-c++ ;
+UNION: c++-abi
+ g++ visual-c++ ;
+
+GENERIC: c++>c-abi ( c++-abi -- c-abi )
+
+M: g++ c++>c-abi drop cdecl ;
+M: visual-c++ c++>c-abi drop thiscall ;
--- /dev/null
+! (c)2010 Joe Groff bsd license
+USING: alien.cxx kernel ;
+QUALIFIED-WITH: alien.cxx.demangle.libstdcxx libstdcxx
+IN: alien.cxx.demangle
+
+GENERIC: c++-symbol? ( mangled-name abi -- ? )
+GENERIC: demangle ( mangled-name abi -- c++-name )
+
+M: g++ c++-symbol?
+ drop libstdcxx:mangled-name? ;
+M: g++ demangle
+ drop libstdcxx:demangle ;
--- /dev/null
+! (c)2010 Joe Groff bsd license
+USING: alien alien.c-types alien.libraries alien.strings
+alien.syntax combinators destructors io.encodings.ascii kernel
+libc locals sequences system ;
+IN: alien.cxx.demangle.libstdcxx
+
+FUNCTION: char* __cxa_demangle ( char* mangled_name, char* output_buffer, size_t* length, int* status ) ;
+
+ERROR: demangle-memory-allocation-failure ;
+ERROR: invalid-mangled-name name ;
+ERROR: invalid-demangle-args name ;
+
+: demangle-error ( name status -- )
+ {
+ { 0 [ drop ] }
+ { -1 [ drop demangle-memory-allocation-failure ] }
+ { -2 [ invalid-mangled-name ] }
+ { -3 [ invalid-demangle-args ] }
+ } case ;
+
+: mangled-name? ( name -- ? )
+ "_Z" head? ;
+
+:: demangle ( mangled-name -- c++-name )
+ 0 <ulong> :> length
+ 0 <int> :> status [
+ mangled-name ascii string>alien f length status __cxa_demangle &(free) :> demangled-buf
+ mangled-name status *int demangle-error
+ demangled-buf ascii alien>string
+ ] with-destructors ;
--- /dev/null
+! (c)2010 Joe Groff bsd license
+USING: alien.cxx.demangle assocs combinators fry io.pathnames
+kernel macho sequences ;
+IN: alien.cxx.scaffold
+
+: library-symbols ( file -- symbols )
+ dup file-extension {
+ { "dylib" [ dylib-exports ] }
+ { f [ dylib-exports ] }
+ } case ;
+
+: c++-library-symbols ( file abi -- symbols )
+ [ library-symbols ] dip
+ [ '[ _ c++-symbol? ] filter ]
+ [ '[ dup _ demangle ] H{ } map>assoc ] bi ;
--- /dev/null
+namespace Namespace {
+ int namespaced(int x, int y) { return x + y; }
+}
+
+double toplevel(double x, double y) { return x + y; }
+double toplevel(double x, double y, double z) { return x + y + z; }
+
+class Class
+{
+ unsigned x;
+
+ Class();
+ Class(unsigned _x);
+
+ unsigned member(unsigned y);
+ unsigned member(unsigned y) const;
+
+ unsigned static_member(unsigned x, unsigned y);
+};
+
+Class::Class() : x(42) { }
+Class::Class(unsigned _x) : x(_x) { }
+unsigned Class::member(unsigned y) { return x += y; }
+unsigned Class::member(unsigned y) const { return x + y; }
+unsigned Class::static_member(unsigned x, unsigned y) { return Class(x).member(y); }
+
+template<typename T>
+T templated(T x, T y) { return x + y; }
+
+template int templated<int>(int x, int y);
+template double templated<double>(double x, double y);
! Based on http://shootout.alioth.debian.org/gp4/benchmark.php?test=fasta&lang=java&id=2
-USING: alien.c-types math kernel io io.files locals multiline
-assocs sequences sequences.private benchmark.reverse-complement
-hints io.encodings.ascii byte-arrays specialized-arrays ;
-SPECIALIZED-ARRAY: double
+USING: assocs benchmark.reverse-complement byte-arrays fry io
+io.encodings.ascii io.files locals kernel math sequences
+sequences.private specialized-arrays strings typed ;
+QUALIFIED-WITH: alien.c-types c
+SPECIALIZED-ARRAY: c:double
IN: benchmark.fasta
CONSTANT: IM 139968
CONSTANT: initial-seed 42
CONSTANT: line-length 60
-: random ( seed -- n seed )
- >float IA * IC + IM mod [ IM /f ] keep ; inline
-
-HINTS: random fixnum ;
+: random ( seed -- seed n )
+ >float IA * IC + IM mod dup IM /f ; inline
CONSTANT: ALU "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA"
{ CHAR: t 0.3015094502008 }
}
-: make-cumulative ( freq -- chars floats )
+TYPED: make-cumulative ( freq -- chars: byte-array floats: double-array )
[ keys >byte-array ]
- [ values >double-array ] bi unclip [ + ] accumulate swap suffix ;
+ [ values >double-array unclip [ + ] accumulate swap suffix ] bi ;
:: select-random ( seed chars floats -- seed elt )
- floats seed random -rot
- [ >= ] curry find drop
- chars nth-unsafe ; inline
+ seed random floats [ <= ] with find drop chars nth-unsafe ; inline
-: make-random-fasta ( seed len chars floats -- seed )
- [ iota ] 2dip [ [ drop ] 2dip select-random ] 2curry "" map-as print ; inline
+TYPED: make-random-fasta ( seed: fixnum len: fixnum chars: byte-array floats: double-array -- seed: fixnum )
+ '[ _ _ select-random ] "" replicate-as print ;
: write-description ( desc id -- )
- ">" write write bl print ; inline
+ ">" write write bl print ;
:: split-lines ( n quot -- )
n line-length /mod
[ [ line-length quot call ] times ] dip
quot unless-zero ; inline
-: write-random-fasta ( seed n chars floats desc id -- seed )
+TYPED: write-random-fasta ( seed: fixnum n: fixnum chars: byte-array floats: double-array desc id -- seed: fixnum )
write-description
- [ make-random-fasta ] 2curry split-lines ; inline
+ '[ _ _ make-random-fasta ] split-lines ;
-:: make-repeat-fasta ( k len alu -- k' )
+TYPED:: make-repeat-fasta ( k: fixnum len: fixnum alu: string -- k': fixnum )
alu length :> kn
len iota [ k + kn mod alu nth-unsafe ] "" map-as print
- k len + ; inline
+ k len + ;
: write-repeat-fasta ( n alu desc id -- )
write-description
:> alu
0 :> k!
[| len | k len alu make-repeat-fasta k! ] split-lines
- ] ; inline
+ ] ;
: fasta ( n out -- )
homo-sapiens make-cumulative
IN: benchmark.fib6\r
\r
: fib ( x -- y )\r
- int { int } "cdecl" [\r
+ int { int } cdecl [\r
dup 1 <= [ drop 1 ] [\r
1 - dup fib swap 1 - fib +\r
] if\r
] alien-callback\r
- int { int } "cdecl" alien-indirect ;\r
+ int { int } cdecl alien-indirect ;\r
\r
: fib-main ( -- ) 32 fib drop ;\r
\r
-USING: kernel locals io io.files splitting strings io.encodings.ascii
- hashtables sequences assocs math namespaces prettyprint
- math.parser combinators arrays sorting unicode.case ;
-
+USING: ascii kernel io io.files splitting strings
+io.encodings.ascii hashtables sequences assocs math
+math.statistics namespaces prettyprint math.parser combinators
+arrays sorting formatting grouping fry ;
IN: benchmark.knucleotide
-: float>string ( float places -- string )
- swap >float number>string
- "." split1 rot
- over length over <
- [ CHAR: 0 pad-tail ]
- [ head ] if "." glue ;
-
: discard-lines ( -- )
readln
[ ">THREE" head? [ discard-lines ] unless ] when* ;
">" read-until drop
CHAR: \n swap remove >upper ;
-: tally ( x exemplar -- b )
- clone [ [ inc-at ] curry each ] keep ;
-
-: small-groups ( x n -- b )
- swap
- [ length swap - 1 + iota ] 2keep
- [ [ over + ] dip subseq ] 2curry map ;
-
: handle-table ( inputs n -- )
- small-groups
- [ length ] keep
- H{ } tally >alist
- sort-values reverse
- [
- dup first write bl
- second 100 * over / 3 float>string print
- ] each
- drop ;
+ <clumps>
+ [ histogram >alist sort-values reverse ] [ length ] bi
+ '[
+ [ first write bl ]
+ [ second 100 * _ /f "%.3f" printf nl ] bi
+ ] each ;
-:: handle-n ( inputs x -- )
- inputs x length small-groups :> groups
- groups H{ } tally :> b
- x b at [ 0 ] unless*
- number>string 8 CHAR: \s pad-tail write ;
+: handle-n ( input x -- )
+ [ nip ] [ length <clumps> histogram ] 2bi at 0 or "%d\t" printf ;
: process-input ( input -- )
- dup 1 handle-table nl
- dup 2 handle-table nl
- { "GGT" "GGTA" "GGTATT" "GGTATTTTAATT" "GGTATTTTAATTTATAGT" }
- [ [ dupd handle-n ] keep print ] each
- drop ;
+ [ 1 handle-table nl ]
+ [ 2 handle-table nl ]
+ [
+ { "GGT" "GGTA" "GGTATT" "GGTATTTTAATT" "GGTATTTTAATTTATAGT" }
+ [ [ handle-n ] keep print ] with each
+ ]
+ tri ;
: knucleotide ( -- )
"resource:extra/benchmark/knucleotide/knucleotide-input.txt"
! Factor port of
! http://shootout.alioth.debian.org/gp4/benchmark.php?test=spectralnorm&lang=all
USING: alien.c-types specialized-arrays kernel math
-math.functions math.vectors sequences prettyprint words hints
-locals ;
+math.functions math.vectors sequences sequences.private
+prettyprint words typed locals ;
SPECIALIZED-ARRAY: double
IN: benchmark.spectral-norm
+ 1 + recip ; inline
: (eval-A-times-u) ( u i j -- x )
- [ swap nth ] [ eval-A ] bi-curry bi* * ; inline
+ [ swap nth-unsafe ] [ eval-A ] bi-curry bi* * ; inline
: eval-A-times-u ( n u -- seq )
[ (eval-A-times-u) ] inner-loop ; inline
: (eval-At-times-u) ( u i j -- x )
- [ swap nth ] [ swap eval-A ] bi-curry bi* * ; inline
+ [ swap nth-unsafe ] [ swap eval-A ] bi-curry bi* * ; inline
: eval-At-times-u ( u n -- seq )
[ (eval-At-times-u) ] inner-loop ; inline
[ n eval-AtA-times-u ] keep
] times ; inline
-: spectral-norm ( n -- norm )
+TYPED: spectral-norm ( n: fixnum -- norm )
u/v [ v. ] [ norm-sq ] bi /f sqrt ;
-HINTS: spectral-norm fixnum ;
-
: spectral-norm-main ( -- )
2000 spectral-norm . ;
--- /dev/null
+Slava Pestov
--- /dev/null
+! Copyright (C) 2010 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: assocs http.client json.reader kernel namespaces urls ;
+IN: bit.ly
+
+SYMBOLS: login api-key ;
+
+<PRIVATE
+
+: of ( assoc key -- value ) swap at ;
+
+: make-request ( long-url -- request )
+ "http://api.bit.ly/v3/shorten" >url
+ login get "login" set-query-param
+ api-key get "apiKey" set-query-param
+ "json" "format" set-query-param
+ swap "longUrl" set-query-param ;
+
+ERROR: bad-response json status ;
+
+: check-response ( json -- json )
+ dup "status_code" of 200 = [
+ dup "status_txt" of
+ bad-response
+ ] unless ;
+
+: parse-response ( response data -- short-url )
+ nip json> check-response "data" of "url" of ;
+
+PRIVATE>
+
+: shorten-url ( long-url -- short-url )
+ make-request http-get parse-response ;
--- /dev/null
+Wrapper for bit.ly URL shortening web service
--- /dev/null
+web services
! Copyright (C) 2010 Erik Charlebois
! See http:// factorcode.org/license.txt for BSD license.
-USING: accessors alien.c-types alien.syntax classes.struct combinators
-combinators.short-circuit kernel math math.order sequences
-typed specialized-arrays locals system alien.libraries ;
+USING: accessors alien alien.c-types alien.libraries
+alien.syntax classes.struct combinators combinators.short-circuit
+kernel math math.order sequences typed specialized-arrays locals
+system ;
SPECIALIZED-ARRAY: void*
IN: chipmunk.ffi
{ [ os windows? ] [ "chipmunk.dll" ] }
{ [ os macosx? ] [ "libchipmunk.dylib" ] }
{ [ os unix? ] [ "libchipmunk.so" ] }
-} cond "cdecl" add-library
+} cond cdecl add-library
"chipmunk" deploy-library
>>
{ t cpFloat }
{ n cpVect } ;
-C-ENUM:
+C-ENUM: cpShapeType
CP_CIRCLE_SHAPE
CP_SEGMENT_SHAPE
CP_POLY_SHAPE
CP_NUM_SHAPES ;
-TYPEDEF: int cpShapeType
CALLBACK: cpBB cacheData_cb ( cpShape* shape, cpVect p, cpVect rot ) ;
CALLBACK: void destroy_cb ( cpShape* shape ) ;
FUNCTION: cpContact* cpContactInit ( cpContact* con, cpVect p, cpVect n, cpFloat dist, cpHashValue hash ) ;
-C-ENUM:
+C-ENUM: cpArbiterState
cpArbiterStateNormal
cpArbiterStateFirstColl
cpArbiterStateIgnore ;
-TYPEDEF: int cpArbiterState
STRUCT: cpArbiter
{ numContacts int }
! (c)2009 Joe Groff bsd license
USING: accessors alien.c-types classes.struct classes.struct.vectored
-kernel sequences specialized-arrays tools.test ;
+kernel sequences specialized-arrays tools.test vocabs compiler.units ;
+FROM: specialized-arrays.private => specialized-array-vocab ;
SPECIALIZED-ARRAYS: int ushort float ;
IN: classes.struct.vectored.tests
{ w ushort-array{ 15 25 35 45 } }
} third vectored-element>
] unit-test
+
+[ ] [
+ [
+ foo specialized-array-vocab forget-vocab
+ ] with-compilation-unit
+] unit-test
--- /dev/null
+Doug Coleman
--- /dev/null
+! Copyright (C) 2010 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: cuda kernel tools.test ;
+IN: cuda.tests
+
+! [ ] [ [ 0 0 [ drop ] with-cuda-context ] with-cuda ] unit-test
+! [ ] [ 100 cuda-malloc cuda-free ] unit-test
--- /dev/null
+! Copyright (C) 2010 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors alien alien.c-types alien.data alien.parser
+alien.strings arrays assocs byte-arrays classes.struct
+combinators continuations cuda.ffi destructors fry io
+io.backend io.encodings.string io.encodings.utf8 kernel lexer
+locals math math.parser namespaces opengl.gl.extensions
+prettyprint quotations sequences ;
+IN: cuda
+
+SYMBOL: cuda-device
+SYMBOL: cuda-context
+SYMBOL: cuda-module
+SYMBOL: cuda-function
+SYMBOL: cuda-launcher
+SYMBOL: cuda-memory-hashtable
+
+ERROR: throw-cuda-error n ;
+
+: cuda-error ( n -- )
+ dup CUDA_SUCCESS = [ drop ] [ throw-cuda-error ] if ;
+
+: cuda-version ( -- n )
+ int <c-object> [ cuDriverGetVersion cuda-error ] keep *int ;
+
+: init-cuda ( -- )
+ 0 cuInit cuda-error ;
+
+TUPLE: launcher
+{ device integer initial: 0 }
+{ device-flags initial: 0 }
+path block-shape shared-size grid ;
+
+: with-cuda-context ( flags device quot -- )
+ [
+ [ CUcontext <c-object> ] 2dip
+ [ cuCtxCreate cuda-error ] 3keep 2drop *void*
+ ] dip
+ [ '[ _ @ ] ]
+ [ drop '[ _ cuCtxDestroy cuda-error ] ] 2bi
+ [ ] cleanup ; inline
+
+: with-cuda-module ( path quot -- )
+ [
+ normalize-path
+ [ CUmodule <c-object> ] dip
+ [ cuModuleLoad cuda-error ] 2keep drop *void*
+ ] dip
+ [ '[ _ @ ] ]
+ [ drop '[ _ cuModuleUnload cuda-error ] ] 2bi
+ [ ] cleanup ; inline
+
+: with-cuda-program ( flags device path quot -- )
+ [ dup cuda-device set ] 2dip
+ '[
+ cuda-context set
+ _ [
+ cuda-module set
+ _ call
+ ] with-cuda-module
+ ] with-cuda-context ; inline
+
+: with-cuda ( launcher quot -- )
+ [
+ init-cuda
+ H{ } clone cuda-memory-hashtable
+ ] 2dip '[
+ _
+ [ cuda-launcher set ]
+ [ [ device>> ] [ device-flags>> ] [ path>> ] tri ] bi
+ _ with-cuda-program
+ ] with-variable ; inline
+
+<PRIVATE
+
+: #cuda-devices ( -- n )
+ int <c-object> [ cuDeviceGetCount cuda-error ] keep *int ;
+
+: n>cuda-device ( n -- device )
+ [ CUdevice <c-object> ] dip [ cuDeviceGet cuda-error ] 2keep drop *int ;
+
+: enumerate-cuda-devices ( -- devices )
+ #cuda-devices iota [ n>cuda-device ] map ;
+
+: cuda-device-properties ( device -- properties )
+ [ CUdevprop <c-object> ] dip
+ [ cuDeviceGetProperties cuda-error ] 2keep drop
+ CUdevprop memory>struct ;
+
+PRIVATE>
+
+: cuda-devices ( -- assoc )
+ enumerate-cuda-devices [ dup cuda-device-properties ] { } map>assoc ;
+
+: cuda-device-name ( n -- string )
+ [ 256 [ <byte-array> ] keep ] dip
+ [ cuDeviceGetName cuda-error ]
+ [ 2drop utf8 alien>string ] 3bi ;
+
+: cuda-device-capability ( n -- pair )
+ [ int <c-object> int <c-object> ] dip
+ [ cuDeviceComputeCapability cuda-error ]
+ [ drop [ *int ] bi@ ] 3bi 2array ;
+
+: cuda-device-memory ( n -- bytes )
+ [ uint <c-object> ] dip
+ [ cuDeviceTotalMem cuda-error ]
+ [ drop *uint ] 2bi ;
+
+: get-cuda-function* ( module string -- function )
+ [ CUfunction <c-object> ] 2dip
+ [ cuModuleGetFunction cuda-error ] 3keep 2drop *void* ;
+
+: get-cuda-function ( string -- function )
+ [ cuda-module get ] dip get-cuda-function* ;
+
+: with-cuda-function ( string quot -- )
+ [
+ get-cuda-function cuda-function set
+ ] dip call ; inline
+
+: launch-function* ( function -- ) cuLaunch cuda-error ;
+
+: launch-function ( -- ) cuda-function get cuLaunch cuda-error ;
+
+: launch-function-grid* ( function width height -- )
+ cuLaunchGrid cuda-error ;
+
+: launch-function-grid ( width height -- )
+ [ cuda-function get ] 2dip
+ cuLaunchGrid cuda-error ;
+
+TUPLE: cuda-memory < disposable ptr length ;
+
+: <cuda-memory> ( ptr length -- obj )
+ cuda-memory new-disposable
+ swap >>length
+ swap >>ptr ;
+
+: add-cuda-memory ( obj -- obj )
+ dup dup ptr>> cuda-memory-hashtable get set-at ;
+
+: delete-cuda-memory ( obj -- )
+ cuda-memory-hashtable delete-at ;
+
+ERROR: invalid-cuda-memory ptr ;
+
+: cuda-memory-length ( cuda-memory -- n )
+ ptr>> cuda-memory-hashtable get ?at [
+ length>>
+ ] [
+ invalid-cuda-memory
+ ] if ;
+
+M: cuda-memory byte-length length>> ;
+
+: cuda-malloc ( n -- ptr )
+ [ CUdeviceptr <c-object> ] dip
+ [ cuMemAlloc cuda-error ] 2keep
+ [ *int ] dip <cuda-memory> add-cuda-memory ;
+
+: cuda-free* ( ptr -- )
+ cuMemFree cuda-error ;
+
+M: cuda-memory dispose ( ptr -- )
+ ptr>> cuda-free* ;
+
+: host>device ( dest-ptr src-ptr -- )
+ [ ptr>> ] dip dup length cuMemcpyHtoD cuda-error ;
+
+:: device>host ( ptr -- seq )
+ ptr byte-length <byte-array>
+ [ ptr [ ptr>> ] [ byte-length ] bi cuMemcpyDtoH cuda-error ] keep ;
+
+: memcpy-device>device ( dest-ptr src-ptr count -- )
+ cuMemcpyDtoD cuda-error ;
+
+: memcpy-device>array ( dest-array dest-index src-ptr count -- )
+ cuMemcpyDtoA cuda-error ;
+
+: memcpy-array>device ( dest-ptr src-array src-index count -- )
+ cuMemcpyAtoD cuda-error ;
+
+: memcpy-array>host ( dest-ptr src-array src-index count -- )
+ cuMemcpyAtoH cuda-error ;
+
+: memcpy-host>array ( dest-array dest-index src-ptr count -- )
+ cuMemcpyHtoA cuda-error ;
+
+: memcpy-array>array ( dest-array dest-index src-array src-ptr count -- )
+ cuMemcpyAtoA cuda-error ;
+
+: cuda-int* ( function offset value -- )
+ cuParamSeti cuda-error ;
+
+: cuda-int ( offset value -- )
+ [ cuda-function get ] 2dip cuda-int* ;
+
+: cuda-float* ( function offset value -- )
+ cuParamSetf cuda-error ;
+
+: cuda-float ( offset value -- )
+ [ cuda-function get ] 2dip cuda-float* ;
+
+: cuda-vector* ( function offset ptr n -- )
+ cuParamSetv cuda-error ;
+
+: cuda-vector ( offset ptr n -- )
+ [ cuda-function get ] 3dip cuda-vector* ;
+
+: param-size* ( function n -- )
+ cuParamSetSize cuda-error ;
+
+: param-size ( n -- )
+ [ cuda-function get ] dip param-size* ;
+
+: malloc-device-string ( string -- n )
+ utf8 encode
+ [ length cuda-malloc ] keep
+ [ host>device ] [ drop ] 2bi ;
+
+ERROR: bad-cuda-parameter parameter ;
+
+:: set-parameters ( seq -- )
+ cuda-function get :> function
+ 0 :> offset!
+ seq [
+ [ offset ] dip
+ {
+ { [ dup cuda-memory? ] [ ptr>> cuda-int ] }
+ { [ dup float? ] [ cuda-float ] }
+ { [ dup integer? ] [ cuda-int ] }
+ [ bad-cuda-parameter ]
+ } cond
+ offset 4 + offset!
+ ] each
+ offset param-size ;
+
+: cuda-device-attribute ( attribute dev -- n )
+ [ int <c-object> ] 2dip
+ [ cuDeviceGetAttribute cuda-error ]
+ [ 2drop *int ] 3bi ;
+
+: function-block-shape* ( function x y z -- )
+ cuFuncSetBlockShape cuda-error ;
+
+: function-block-shape ( x y z -- )
+ [ cuda-function get ] 3dip
+ cuFuncSetBlockShape cuda-error ;
+
+: function-shared-size* ( function n -- )
+ cuFuncSetSharedSize cuda-error ;
+
+: function-shared-size ( n -- )
+ [ cuda-function get ] dip
+ cuFuncSetSharedSize cuda-error ;
+
+: launch ( -- )
+ cuda-launcher get {
+ [ block-shape>> first3 function-block-shape ]
+ [ shared-size>> function-shared-size ]
+ [
+ grid>> [
+ launch-function
+ ] [
+ first2 launch-function-grid
+ ] if-empty
+ ]
+ } cleave ;
+
+: cuda-device. ( n -- )
+ {
+ [ "Device: " write number>string print ]
+ [ "Name: " write cuda-device-name print ]
+ [ "Memory: " write cuda-device-memory number>string print ]
+ [
+ "Capability: " write
+ cuda-device-capability [ number>string ] map " " join print
+ ]
+ [ "Properties: " write cuda-device-properties . ]
+ [
+ "CU_DEVICE_ATTRIBUTE_GPU_OVERLAP: " write
+ CU_DEVICE_ATTRIBUTE_GPU_OVERLAP swap
+ cuda-device-attribute number>string print
+ ]
+ } cleave ;
+
+: cuda. ( -- )
+ "CUDA Version: " write cuda-version number>string print nl
+ #cuda-devices iota [ nl ] [ cuda-device. ] interleave ;
+
+
+: test-cuda0 ( -- )
+ T{ launcher
+ { path "vocab:cuda/hello.ptx" }
+ { block-shape { 6 6 6 } }
+ { shared-size 2 }
+ { grid { 2 6 } }
+ } [
+ "helloWorld" [
+ "Hello World!" [ - ] map-index
+ malloc-device-string &dispose
+
+ [ 1array set-parameters ]
+ [ drop launch ]
+ [ device>host utf8 alien>string . ] tri
+ ] with-cuda-function
+ ] with-cuda ;
--- /dev/null
+! (c)2010 Joe Groff bsd license
+USING: accessors alien alien.c-types alien.libraries alien.syntax
+classes.struct combinators kernel system ;
+IN: cuda.ffi
+
+<<
+"cuda" {
+ { [ os windows? ] [ "nvcuda.dll" stdcall ] }
+ { [ os macosx? ] [ "/usr/local/cuda/lib/libcuda.dylib" cdecl ] }
+ { [ os unix? ] [ "libcuda.so" cdecl ] }
+} cond add-library
+>>
+
+LIBRARY: cuda
+
+TYPEDEF: uint CUdeviceptr
+TYPEDEF: int CUdevice
+TYPEDEF: void* CUcontext
+TYPEDEF: void* CUmodule
+TYPEDEF: void* CUfunction
+TYPEDEF: void* CUarray
+TYPEDEF: void* CUtexref
+TYPEDEF: void* CUevent
+TYPEDEF: void* CUstream
+TYPEDEF: void* CUgraphicsResource
+
+! versions of double and longlong that always 8-byte align
+
+SYMBOLS: CUdouble CUlonglong CUulonglong ;
+
+: >cuda-param-type ( c-type -- c-type' )
+ {
+ { CUdeviceptr [ void* ] }
+ { double [ CUdouble ] }
+ { longlong [ CUlonglong ] }
+ { ulonglong [ CUulonglong ] }
+ [ ]
+ } case ;
+
+<<
+: always-8-byte-align ( c-type -- c-type )
+ 8 >>align 8 >>align-first ;
+
+longlong c-type clone always-8-byte-align \ CUlonglong typedef
+ulonglong c-type clone always-8-byte-align \ CUulonglong typedef
+double c-type clone always-8-byte-align \ CUdouble typedef
+>>
+
+STRUCT: CUuuid
+ { bytes char[16] } ;
+
+C-ENUM: CUctx_flags
+ { CU_CTX_SCHED_AUTO 0 }
+ { CU_CTX_SCHED_SPIN 1 }
+ { CU_CTX_SCHED_YIELD 2 }
+ { CU_CTX_SCHED_MASK 3 }
+ { CU_CTX_BLOCKING_SYNC 4 }
+ { CU_CTX_MAP_HOST 8 }
+ { CU_CTX_LMEM_RESIZE_TO_MAX 16 }
+ { CU_CTX_FLAGS_MASK HEX: 1f } ;
+
+C-ENUM: CUevent_flags
+ { CU_EVENT_DEFAULT 0 }
+ { CU_EVENT_BLOCKING_SYNC 1 } ;
+
+C-ENUM: CUarray_format
+ { CU_AD_FORMAT_UNSIGNED_INT8 HEX: 01 }
+ { CU_AD_FORMAT_UNSIGNED_INT16 HEX: 02 }
+ { CU_AD_FORMAT_UNSIGNED_INT32 HEX: 03 }
+ { CU_AD_FORMAT_SIGNED_INT8 HEX: 08 }
+ { CU_AD_FORMAT_SIGNED_INT16 HEX: 09 }
+ { CU_AD_FORMAT_SIGNED_INT32 HEX: 0a }
+ { CU_AD_FORMAT_HALF HEX: 10 }
+ { CU_AD_FORMAT_FLOAT HEX: 20 } ;
+
+C-ENUM: CUaddress_mode
+ { CU_TR_ADDRESS_MODE_WRAP 0 }
+ { CU_TR_ADDRESS_MODE_CLAMP 1 }
+ { CU_TR_ADDRESS_MODE_MIRROR 2 } ;
+
+C-ENUM: CUfilter_mode
+ { CU_TR_FILTER_MODE_POINT 0 }
+ { CU_TR_FILTER_MODE_LINEAR 1 } ;
+
+C-ENUM: CUdevice_attribute
+ { CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK 1 }
+ { CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_X 2 }
+ { CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_Y 3 }
+ { CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_Z 4 }
+ { CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_X 5 }
+ { CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_Y 6 }
+ { CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_Z 7 }
+ { CU_DEVICE_ATTRIBUTE_MAX_SHARED_MEMORY_PER_BLOCK 8 }
+ { CU_DEVICE_ATTRIBUTE_SHARED_MEMORY_PER_BLOCK 8 }
+ { CU_DEVICE_ATTRIBUTE_TOTAL_CONSTANT_MEMORY 9 }
+ { CU_DEVICE_ATTRIBUTE_WARP_SIZE 10 }
+ { CU_DEVICE_ATTRIBUTE_MAX_PITCH 11 }
+ { CU_DEVICE_ATTRIBUTE_MAX_REGISTERS_PER_BLOCK 12 }
+ { CU_DEVICE_ATTRIBUTE_REGISTERS_PER_BLOCK 12 }
+ { CU_DEVICE_ATTRIBUTE_CLOCK_RATE 13 }
+ { CU_DEVICE_ATTRIBUTE_TEXTURE_ALIGNMENT 14 }
+
+ { CU_DEVICE_ATTRIBUTE_GPU_OVERLAP 15 }
+ { CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT 16 }
+ { CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT 17 }
+ { CU_DEVICE_ATTRIBUTE_INTEGRATED 18 }
+ { CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY 19 }
+ { CU_DEVICE_ATTRIBUTE_COMPUTE_MODE 20 }
+ { CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE1D_WIDTH 21 }
+ { CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_WIDTH 22 }
+ { CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_HEIGHT 23 }
+ { CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_WIDTH 24 }
+ { CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_HEIGHT 25 }
+ { CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_DEPTH 26 }
+ { CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_ARRAY_WIDTH 27 }
+ { CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_ARRAY_HEIGHT 28 }
+ { CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_ARRAY_NUMSLICES 29 }
+ { CU_DEVICE_ATTRIBUTE_SURFACE_ALIGNMENT 30 }
+ { CU_DEVICE_ATTRIBUTE_CONCURRENT_KERNELS 31 }
+ { CU_DEVICE_ATTRIBUTE_ECC_ENABLED 32 } ;
+
+STRUCT: CUdevprop
+ { maxThreadsPerBlock int }
+ { maxThreadsDim int[3] }
+ { maxGridSize int[3] }
+ { sharedMemPerBlock int }
+ { totalConstantMemory int }
+ { SIMDWidth int }
+ { memPitch int }
+ { regsPerBlock int }
+ { clockRate int }
+ { textureAlign int } ;
+
+C-ENUM: CUfunction_attribute
+ { CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK 0 }
+ { CU_FUNC_ATTRIBUTE_SHARED_SIZE_BYTES 1 }
+ { CU_FUNC_ATTRIBUTE_CONST_SIZE_BYTES 2 }
+ { CU_FUNC_ATTRIBUTE_LOCAL_SIZE_BYTES 3 }
+ { CU_FUNC_ATTRIBUTE_NUM_REGS 4 }
+ { CU_FUNC_ATTRIBUTE_PTX_VERSION 5 }
+ { CU_FUNC_ATTRIBUTE_BINARY_VERSION 6 }
+ CU_FUNC_ATTRIBUTE_MAX ;
+
+C-ENUM: CUfunc_cache
+ { CU_FUNC_CACHE_PREFER_NONE HEX: 00 }
+ { CU_FUNC_CACHE_PREFER_SHARED HEX: 01 }
+ { CU_FUNC_CACHE_PREFER_L1 HEX: 02 } ;
+
+C-ENUM: CUmemorytype
+ { CU_MEMORYTYPE_HOST HEX: 01 }
+ { CU_MEMORYTYPE_DEVICE HEX: 02 }
+ { CU_MEMORYTYPE_ARRAY HEX: 03 } ;
+
+C-ENUM: CUcomputemode
+ { CU_COMPUTEMODE_DEFAULT 0 }
+ { CU_COMPUTEMODE_EXCLUSIVE 1 }
+ { CU_COMPUTEMODE_PROHIBITED 2 } ;
+
+C-ENUM: CUjit_option
+ { CU_JIT_MAX_REGISTERS 0 }
+ CU_JIT_THREADS_PER_BLOCK
+ CU_JIT_WALL_TIME
+ CU_JIT_INFO_LOG_BUFFER
+ CU_JIT_INFO_LOG_BUFFER_SIZE_BYTES
+ CU_JIT_ERROR_LOG_BUFFER
+ CU_JIT_ERROR_LOG_BUFFER_SIZE_BYTES
+ CU_JIT_OPTIMIZATION_LEVEL
+ CU_JIT_TARGET_FROM_CUCONTEXT
+ CU_JIT_TARGET
+ CU_JIT_FALLBACK_STRATEGY ;
+
+C-ENUM: CUjit_target
+ { CU_TARGET_COMPUTE_10 0 }
+ CU_TARGET_COMPUTE_11
+ CU_TARGET_COMPUTE_12
+ CU_TARGET_COMPUTE_13
+ CU_TARGET_COMPUTE_20 ;
+
+C-ENUM: CUjit_fallback
+ { CU_PREFER_PTX 0 }
+ CU_PREFER_BINARY ;
+
+C-ENUM: CUgraphicsRegisterFlags
+ { CU_GRAPHICS_REGISTER_FLAGS_NONE 0 } ;
+
+C-ENUM: CUgraphicsMapResourceFlags
+ { CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE HEX: 00 }
+ { CU_GRAPHICS_MAP_RESOURCE_FLAGS_READ_ONLY HEX: 01 }
+ { CU_GRAPHICS_MAP_RESOURCE_FLAGS_WRITE_DISCARD HEX: 02 } ;
+
+C-ENUM: CUarray_cubemap_face
+ { CU_CUBEMAP_FACE_POSITIVE_X HEX: 00 }
+ { CU_CUBEMAP_FACE_NEGATIVE_X HEX: 01 }
+ { CU_CUBEMAP_FACE_POSITIVE_Y HEX: 02 }
+ { CU_CUBEMAP_FACE_NEGATIVE_Y HEX: 03 }
+ { CU_CUBEMAP_FACE_POSITIVE_Z HEX: 04 }
+ { CU_CUBEMAP_FACE_NEGATIVE_Z HEX: 05 } ;
+
+C-ENUM: CUresult
+ { CUDA_SUCCESS 0 }
+ { CUDA_ERROR_INVALID_VALUE 1 }
+ { CUDA_ERROR_OUT_OF_MEMORY 2 }
+ { CUDA_ERROR_NOT_INITIALIZED 3 }
+ { CUDA_ERROR_DEINITIALIZED 4 }
+
+ { CUDA_ERROR_NO_DEVICE 100 }
+ { CUDA_ERROR_INVALID_DEVICE 101 }
+
+ { CUDA_ERROR_INVALID_IMAGE 200 }
+ { CUDA_ERROR_INVALID_CONTEXT 201 }
+ { CUDA_ERROR_CONTEXT_ALREADY_CURRENT 202 }
+ { CUDA_ERROR_MAP_FAILED 205 }
+ { CUDA_ERROR_UNMAP_FAILED 206 }
+ { CUDA_ERROR_ARRAY_IS_MAPPED 207 }
+ { CUDA_ERROR_ALREADY_MAPPED 208 }
+ { CUDA_ERROR_NO_BINARY_FOR_GPU 209 }
+ { CUDA_ERROR_ALREADY_ACQUIRED 210 }
+ { CUDA_ERROR_NOT_MAPPED 211 }
+ { CUDA_ERROR_NOT_MAPPED_AS_ARRAY 212 }
+ { CUDA_ERROR_NOT_MAPPED_AS_POINTER 213 }
+ { CUDA_ERROR_ECC_UNCORRECTABLE 214 }
+
+ { CUDA_ERROR_INVALID_SOURCE 300 }
+ { CUDA_ERROR_FILE_NOT_FOUND 301 }
+
+ { CUDA_ERROR_INVALID_HANDLE 400 }
+
+ { CUDA_ERROR_NOT_FOUND 500 }
+
+ { CUDA_ERROR_NOT_READY 600 }
+
+ { CUDA_ERROR_LAUNCH_FAILED 700 }
+ { CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES 701 }
+ { CUDA_ERROR_LAUNCH_TIMEOUT 702 }
+ { CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING 703 }
+
+ { CUDA_ERROR_POINTER_IS_64BIT 800 }
+ { CUDA_ERROR_SIZE_IS_64BIT 801 }
+
+ { CUDA_ERROR_UNKNOWN 999 } ;
+
+CONSTANT: CU_MEMHOSTALLOC_PORTABLE HEX: 01
+CONSTANT: CU_MEMHOSTALLOC_DEVICEMAP HEX: 02
+CONSTANT: CU_MEMHOSTALLOC_WRITECOMBINED HEX: 04
+
+STRUCT: CUDA_MEMCPY2D
+ { srcXInBytes uint }
+ { srcY uint }
+ { srcMemoryType CUmemorytype }
+ { srcHost void* }
+ { srcDevice CUdeviceptr }
+ { srcArray CUarray }
+ { srcPitch uint }
+ { dstXInBytes uint }
+ { dstY uint }
+ { dstMemoryType CUmemorytype }
+ { dstHost void* }
+ { dstDevice CUdeviceptr }
+ { dstArray CUarray }
+ { dstPitch uint }
+ { WidthInBytes uint }
+ { Height uint } ;
+
+STRUCT: CUDA_MEMCPY3D
+ { srcXInBytes uint }
+ { srcY uint }
+ { srcZ uint }
+ { srcLOD uint }
+ { srcMemoryType CUmemorytype }
+ { srcHost void* }
+ { srcDevice CUdeviceptr }
+ { srcArray CUarray }
+ { reserved0 void* }
+ { srcPitch uint }
+ { srcHeight uint }
+ { dstXInBytes uint }
+ { dstY uint }
+ { dstZ uint }
+ { dstLOD uint }
+ { dstMemoryType CUmemorytype }
+ { dstHost void* }
+ { dstDevice CUdeviceptr }
+ { dstArray CUarray }
+ { reserved1 void* }
+ { dstPitch uint }
+ { dstHeight uint }
+ { WidthInBytes uint }
+ { Height uint }
+ { Depth uint } ;
+
+STRUCT: CUDA_ARRAY_DESCRIPTOR
+ { Width uint }
+ { Height uint }
+ { Format CUarray_format }
+ { NumChannels uint } ;
+
+STRUCT: CUDA_ARRAY3D_DESCRIPTOR
+ { Width uint }
+ { Height uint }
+ { Depth uint }
+ { Format CUarray_format }
+ { NumChannels uint }
+ { Flags uint } ;
+
+CONSTANT: CUDA_ARRAY3D_2DARRAY HEX: 01
+CONSTANT: CU_TRSA_OVERRIDE_FORMAT HEX: 01
+CONSTANT: CU_TRSF_READ_AS_INTEGER HEX: 01
+CONSTANT: CU_TRSF_NORMALIZED_COORDINATES HEX: 02
+CONSTANT: CU_PARAM_TR_DEFAULT -1
+
+FUNCTION: CUresult cuInit ( uint Flags ) ;
+
+FUNCTION: CUresult cuDriverGetVersion ( int* driverVersion ) ;
+
+FUNCTION: CUresult cuDeviceGet ( CUdevice* device, int ordinal ) ;
+FUNCTION: CUresult cuDeviceGetCount ( int* count ) ;
+FUNCTION: CUresult cuDeviceGetName ( char* name, int len, CUdevice dev ) ;
+FUNCTION: CUresult cuDeviceComputeCapability ( int* major, int* minor, CUdevice dev ) ;
+FUNCTION: CUresult cuDeviceTotalMem ( uint* bytes, CUdevice dev ) ;
+FUNCTION: CUresult cuDeviceGetProperties ( CUdevprop* prop, CUdevice dev ) ;
+FUNCTION: CUresult cuDeviceGetAttribute ( int* pi, CUdevice_attribute attrib, CUdevice dev ) ;
+
+FUNCTION: CUresult cuCtxCreate ( CUcontext* pctx, uint flags, CUdevice dev ) ;
+FUNCTION: CUresult cuCtxDestroy ( CUcontext ctx ) ;
+FUNCTION: CUresult cuCtxAttach ( CUcontext* pctx, uint flags ) ;
+FUNCTION: CUresult cuCtxDetach ( CUcontext ctx ) ;
+FUNCTION: CUresult cuCtxPushCurrent ( CUcontext ctx ) ;
+FUNCTION: CUresult cuCtxPopCurrent ( CUcontext* pctx ) ;
+FUNCTION: CUresult cuCtxGetDevice ( CUdevice* device ) ;
+FUNCTION: CUresult cuCtxSynchronize ( ) ;
+
+FUNCTION: CUresult cuModuleLoad ( CUmodule* module, c-string fname ) ;
+FUNCTION: CUresult cuModuleLoadData ( CUmodule* module, void* image ) ;
+FUNCTION: CUresult cuModuleLoadDataEx ( CUmodule* module, void* image, uint numOptions, CUjit_option* options, void** optionValues ) ;
+FUNCTION: CUresult cuModuleLoadFatBinary ( CUmodule* module, void* fatCubin ) ;
+FUNCTION: CUresult cuModuleUnload ( CUmodule hmod ) ;
+FUNCTION: CUresult cuModuleGetFunction ( CUfunction* hfunc, CUmodule hmod, c-string name ) ;
+FUNCTION: CUresult cuModuleGetGlobal ( CUdeviceptr* dptr, uint* bytes, CUmodule hmod, char* name ) ;
+FUNCTION: CUresult cuModuleGetTexRef ( CUtexref* pTexRef, CUmodule hmod, char* name ) ;
+
+FUNCTION: CUresult cuMemGetInfo ( uint* free, uint* total ) ;
+
+FUNCTION: CUresult cuMemAlloc ( CUdeviceptr* dptr, uint bytesize ) ;
+FUNCTION: CUresult cuMemAllocPitch ( CUdeviceptr* dptr,
+ uint* pPitch,
+ uint WidthInBytes,
+ uint Height,
+ uint ElementSizeBytes
+ ) ;
+FUNCTION: CUresult cuMemFree ( CUdeviceptr dptr ) ;
+FUNCTION: CUresult cuMemGetAddressRange ( CUdeviceptr* pbase, uint* psize, CUdeviceptr dptr ) ;
+
+FUNCTION: CUresult cuMemAllocHost ( void** pp, uint bytesize ) ;
+FUNCTION: CUresult cuMemFreeHost ( void* p ) ;
+
+FUNCTION: CUresult cuMemHostAlloc ( void** pp, size_t bytesize, uint Flags ) ;
+
+FUNCTION: CUresult cuMemHostGetDevicePointer ( CUdeviceptr* pdptr, void* p, uint Flags ) ;
+FUNCTION: CUresult cuMemHostGetFlags ( uint* pFlags, void* p ) ;
+
+FUNCTION: CUresult cuMemcpyHtoD ( CUdeviceptr dstDevice, void* srcHost, uint ByteCount ) ;
+FUNCTION: CUresult cuMemcpyDtoH ( void* dstHost, CUdeviceptr srcDevice, uint ByteCount ) ;
+
+FUNCTION: CUresult cuMemcpyDtoD ( CUdeviceptr dstDevice, CUdeviceptr srcDevice, uint ByteCount ) ;
+
+FUNCTION: CUresult cuMemcpyDtoA ( CUarray dstArray, uint dstIndex, CUdeviceptr srcDevice, uint ByteCount ) ;
+FUNCTION: CUresult cuMemcpyAtoD ( CUdeviceptr dstDevice, CUarray hSrc, uint SrcIndex, uint ByteCount ) ;
+
+FUNCTION: CUresult cuMemcpyHtoA ( CUarray dstArray, uint dstIndex, void* pSrc, uint ByteCount ) ;
+FUNCTION: CUresult cuMemcpyAtoH ( void* dstHost, CUarray srcArray, uint srcIndex, uint ByteCount ) ;
+
+FUNCTION: CUresult cuMemcpyAtoA ( CUarray dstArray, uint dstIndex, CUarray srcArray, uint srcIndex, uint ByteCount ) ;
+
+FUNCTION: CUresult cuMemcpy2D ( CUDA_MEMCPY2D* pCopy ) ;
+FUNCTION: CUresult cuMemcpy2DUnaligned ( CUDA_MEMCPY2D* pCopy ) ;
+
+FUNCTION: CUresult cuMemcpy3D ( CUDA_MEMCPY3D* pCopy ) ;
+
+FUNCTION: CUresult cuMemcpyHtoDAsync ( CUdeviceptr dstDevice,
+ void* srcHost, uint ByteCount, CUstream hStream ) ;
+FUNCTION: CUresult cuMemcpyDtoHAsync ( void* dstHost,
+ CUdeviceptr srcDevice, uint ByteCount, CUstream hStream ) ;
+
+FUNCTION: CUresult cuMemcpyDtoDAsync ( CUdeviceptr dstDevice,
+ CUdeviceptr srcDevice, uint ByteCount, CUstream hStream ) ;
+
+FUNCTION: CUresult cuMemcpyHtoAAsync ( CUarray dstArray, uint dstIndex,
+ void* pSrc, uint ByteCount, CUstream hStream ) ;
+FUNCTION: CUresult cuMemcpyAtoHAsync ( void* dstHost, CUarray srcArray, uint srcIndex,
+ uint ByteCount, CUstream hStream ) ;
+
+FUNCTION: CUresult cuMemcpy2DAsync ( CUDA_MEMCPY2D* pCopy, CUstream hStream ) ;
+FUNCTION: CUresult cuMemcpy3DAsync ( CUDA_MEMCPY3D* pCopy, CUstream hStream ) ;
+
+FUNCTION: CUresult cuMemsetD8 ( CUdeviceptr dstDevice, uchar uc, uint N ) ;
+FUNCTION: CUresult cuMemsetD16 ( CUdeviceptr dstDevice, ushort us, uint N ) ;
+FUNCTION: CUresult cuMemsetD32 ( CUdeviceptr dstDevice, uint ui, uint N ) ;
+
+FUNCTION: CUresult cuMemsetD2D8 ( CUdeviceptr dstDevice, uint dstPitch, uchar uc, uint Width, uint Height ) ;
+FUNCTION: CUresult cuMemsetD2D16 ( CUdeviceptr dstDevice, uint dstPitch, ushort us, uint Width, uint Height ) ;
+FUNCTION: CUresult cuMemsetD2D32 ( CUdeviceptr dstDevice, uint dstPitch, uint ui, uint Width, uint Height ) ;
+
+FUNCTION: CUresult cuFuncSetBlockShape ( CUfunction hfunc, int x, int y, int z ) ;
+FUNCTION: CUresult cuFuncSetSharedSize ( CUfunction hfunc, uint bytes ) ;
+FUNCTION: CUresult cuFuncGetAttribute ( int* pi, CUfunction_attribute attrib, CUfunction hfunc ) ;
+FUNCTION: CUresult cuFuncSetCacheConfig ( CUfunction hfunc, CUfunc_cache config ) ;
+
+FUNCTION: CUresult cuArrayCreate ( CUarray* pHandle, CUDA_ARRAY_DESCRIPTOR* pAllocateArray ) ;
+FUNCTION: CUresult cuArrayGetDescriptor ( CUDA_ARRAY_DESCRIPTOR* pArrayDescriptor, CUarray hArray ) ;
+FUNCTION: CUresult cuArrayDestroy ( CUarray hArray ) ;
+
+FUNCTION: CUresult cuArray3DCreate ( CUarray* pHandle, CUDA_ARRAY3D_DESCRIPTOR* pAllocateArray ) ;
+FUNCTION: CUresult cuArray3DGetDescriptor ( CUDA_ARRAY3D_DESCRIPTOR* pArrayDescriptor, CUarray hArray ) ;
+
+FUNCTION: CUresult cuTexRefCreate ( CUtexref* pTexRef ) ;
+FUNCTION: CUresult cuTexRefDestroy ( CUtexref hTexRef ) ;
+
+FUNCTION: CUresult cuTexRefSetArray ( CUtexref hTexRef, CUarray hArray, uint Flags ) ;
+FUNCTION: CUresult cuTexRefSetAddress ( uint* ByteOffset, CUtexref hTexRef, CUdeviceptr dptr, uint bytes ) ;
+FUNCTION: CUresult cuTexRefSetAddress2D ( CUtexref hTexRef, CUDA_ARRAY_DESCRIPTOR* desc, CUdeviceptr dptr, uint Pitch ) ;
+FUNCTION: CUresult cuTexRefSetFormat ( CUtexref hTexRef, CUarray_format fmt, int NumPackedComponents ) ;
+FUNCTION: CUresult cuTexRefSetAddressMode ( CUtexref hTexRef, int dim, CUaddress_mode am ) ;
+FUNCTION: CUresult cuTexRefSetFilterMode ( CUtexref hTexRef, CUfilter_mode fm ) ;
+FUNCTION: CUresult cuTexRefSetFlags ( CUtexref hTexRef, uint Flags ) ;
+
+FUNCTION: CUresult cuTexRefGetAddress ( CUdeviceptr* pdptr, CUtexref hTexRef ) ;
+FUNCTION: CUresult cuTexRefGetArray ( CUarray* phArray, CUtexref hTexRef ) ;
+FUNCTION: CUresult cuTexRefGetAddressMode ( CUaddress_mode* pam, CUtexref hTexRef, int dim ) ;
+FUNCTION: CUresult cuTexRefGetFilterMode ( CUfilter_mode* pfm, CUtexref hTexRef ) ;
+FUNCTION: CUresult cuTexRefGetFormat ( CUarray_format* pFormat, int* pNumChannels, CUtexref hTexRef ) ;
+FUNCTION: CUresult cuTexRefGetFlags ( uint* pFlags, CUtexref hTexRef ) ;
+
+FUNCTION: CUresult cuParamSetSize ( CUfunction hfunc, uint numbytes ) ;
+FUNCTION: CUresult cuParamSeti ( CUfunction hfunc, int offset, uint value ) ;
+FUNCTION: CUresult cuParamSetf ( CUfunction hfunc, int offset, float value ) ;
+FUNCTION: CUresult cuParamSetv ( CUfunction hfunc, int offset, void* ptr, uint numbytes ) ;
+FUNCTION: CUresult cuParamSetTexRef ( CUfunction hfunc, int texunit, CUtexref hTexRef ) ;
+
+FUNCTION: CUresult cuLaunch ( CUfunction f ) ;
+FUNCTION: CUresult cuLaunchGrid ( CUfunction f, int grid_width, int grid_height ) ;
+FUNCTION: CUresult cuLaunchGridAsync ( CUfunction f, int grid_width, int grid_height, CUstream hStream ) ;
+
+FUNCTION: CUresult cuEventCreate ( CUevent* phEvent, uint Flags ) ;
+FUNCTION: CUresult cuEventRecord ( CUevent hEvent, CUstream hStream ) ;
+FUNCTION: CUresult cuEventQuery ( CUevent hEvent ) ;
+FUNCTION: CUresult cuEventSynchronize ( CUevent hEvent ) ;
+FUNCTION: CUresult cuEventDestroy ( CUevent hEvent ) ;
+FUNCTION: CUresult cuEventElapsedTime ( float* pMilliseconds, CUevent hStart, CUevent hEnd ) ;
+
+FUNCTION: CUresult cuStreamCreate ( CUstream* phStream, uint Flags ) ;
+FUNCTION: CUresult cuStreamQuery ( CUstream hStream ) ;
+FUNCTION: CUresult cuStreamSynchronize ( CUstream hStream ) ;
+FUNCTION: CUresult cuStreamDestroy ( CUstream hStream ) ;
+
+FUNCTION: CUresult cuGraphicsUnregisterResource ( CUgraphicsResource resource ) ;
+FUNCTION: CUresult cuGraphicsSubResourceGetMappedArray ( CUarray* pArray, CUgraphicsResource resource, uint arrayIndex, uint mipLevel ) ;
+FUNCTION: CUresult cuGraphicsResourceGetMappedPointer ( CUdeviceptr* pDevPtr, uint* pSize, CUgraphicsResource resource ) ;
+FUNCTION: CUresult cuGraphicsResourceSetMapFlags ( CUgraphicsResource resource, uint flags ) ;
+FUNCTION: CUresult cuGraphicsMapResources ( uint count, CUgraphicsResource* resources, CUstream hStream ) ;
+FUNCTION: CUresult cuGraphicsUnmapResources ( uint count, CUgraphicsResource* resources, CUstream hStream ) ;
+
+FUNCTION: CUresult cuGetExportTable ( void** ppExportTable, CUuuid* pExportTableId ) ;
+
--- /dev/null
+not tested
+bindings
--- /dev/null
+/*
+ World using CUDA
+**
+** The string "Hello World!" is mangled then restored using a common CUDA idiom
+**
+** Byron Galbraith
+** 2009-02-18
+*/
+#include <cuda.h>
+#include <stdio.h>
+
+// Prototypes
+extern "C" __global__ void helloWorld(char*);
+
+// Host function
+int
+main(int argc, char** argv)
+{
+ int i;
+
+ // desired output
+ char str[] = "Hello World!";
+
+ // mangle contents of output
+ // the null character is left intact for simplicity
+ for(i = 0; i < 12; i++)
+ str[i] -= i;
+
+ // allocate memory on the device
+ char *d_str;
+ size_t size = sizeof(str);
+ cudaMalloc((void**)&d_str, size);
+
+ // copy the string to the device
+ cudaMemcpy(d_str, str, size, cudaMemcpyHostToDevice);
+
+ // set the grid and block sizes
+ dim3 dimGrid(2); // one block per word
+ dim3 dimBlock(6); // one thread per character
+
+ // invoke the kernel
+ helloWorld<<< dimGrid, dimBlock >>>(d_str);
+
+ // retrieve the results from the device
+ cudaMemcpy(str, d_str, size, cudaMemcpyDeviceToHost);
+
+ // free up the allocated memory on the device
+ cudaFree(d_str);
+
+ // everyone's favorite part
+ printf("%s\n", str);
+
+ return 0;
+}
+
+// Device kernel
+__global__ void
+helloWorld(char* str)
+{
+ // determine where in the thread grid we are
+ int idx = blockIdx.x * blockDim.x + threadIdx.x;
+
+ // unmangle output
+ str[idx] += idx;
+}
--- /dev/null
+ .version 1.4
+ .target sm_10, map_f64_to_f32
+ // compiled with /usr/local/cuda/bin/../open64/lib//be
+ // nvopencc 3.0 built on 2010-03-11
+
+ //-----------------------------------------------------------
+ // Compiling /tmp/tmpxft_00000eab_00000000-7_hello.cpp3.i (/var/folders/KD/KDnx4D80Eh0fsORqNrFWBE+++TI/-Tmp-/ccBI#.AYqbdQ)
+ //-----------------------------------------------------------
+
+ //-----------------------------------------------------------
+ // Options:
+ //-----------------------------------------------------------
+ // Target:ptx, ISA:sm_10, Endian:little, Pointer Size:32
+ // -O3 (Optimization level)
+ // -g0 (Debug level)
+ // -m2 (Report advisories)
+ //-----------------------------------------------------------
+
+ .file 1 "<command-line>"
+ .file 2 "/tmp/tmpxft_00000eab_00000000-6_hello.cudafe2.gpu"
+ .file 3 "/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/stddef.h"
+ .file 4 "/usr/local/cuda/bin/../include/crt/device_runtime.h"
+ .file 5 "/usr/local/cuda/bin/../include/host_defines.h"
+ .file 6 "/usr/local/cuda/bin/../include/builtin_types.h"
+ .file 7 "/usr/local/cuda/bin/../include/device_types.h"
+ .file 8 "/usr/local/cuda/bin/../include/driver_types.h"
+ .file 9 "/usr/local/cuda/bin/../include/texture_types.h"
+ .file 10 "/usr/local/cuda/bin/../include/vector_types.h"
+ .file 11 "/usr/local/cuda/bin/../include/device_launch_parameters.h"
+ .file 12 "/usr/local/cuda/bin/../include/crt/storage_class.h"
+ .file 13 "/usr/include/i386/_types.h"
+ .file 14 "/usr/include/time.h"
+ .file 15 "/usr/local/cuda/bin/../include/texture_fetch_functions.h"
+ .file 16 "/usr/local/cuda/bin/../include/common_functions.h"
+ .file 17 "/usr/local/cuda/bin/../include/crt/func_macro.h"
+ .file 18 "/usr/local/cuda/bin/../include/math_functions.h"
+ .file 19 "/usr/local/cuda/bin/../include/device_functions.h"
+ .file 20 "/usr/local/cuda/bin/../include/math_constants.h"
+ .file 21 "/usr/local/cuda/bin/../include/sm_11_atomic_functions.h"
+ .file 22 "/usr/local/cuda/bin/../include/sm_12_atomic_functions.h"
+ .file 23 "/usr/local/cuda/bin/../include/sm_13_double_functions.h"
+ .file 24 "/usr/local/cuda/bin/../include/common_types.h"
+ .file 25 "/usr/local/cuda/bin/../include/sm_20_atomic_functions.h"
+ .file 26 "/usr/local/cuda/bin/../include/sm_20_intrinsics.h"
+ .file 27 "/usr/local/cuda/bin/../include/math_functions_dbl_ptx1.h"
+ .file 28 "hello.cu"
+
+
+ .entry helloWorld (
+ .param .u32 __cudaparm_helloWorld_str)
+ {
+ .reg .u16 %rh<4>;
+ .reg .u32 %r<9>;
+ .loc 28 58 0
+$LBB1_helloWorld:
+ .loc 28 64 0
+ mov.u16 %rh1, %ctaid.x;
+ mov.u16 %rh2, %ntid.x;
+ mul.wide.u16 %r1, %rh1, %rh2;
+ cvt.u32.u16 %r2, %tid.x;
+ add.u32 %r3, %r2, %r1;
+ ld.param.u32 %r4, [__cudaparm_helloWorld_str];
+ add.u32 %r5, %r4, %r3;
+ ld.global.s8 %r6, [%r5+0];
+ add.s32 %r7, %r6, %r3;
+ st.global.s8 [%r5+0], %r7;
+ .loc 28 65 0
+ exit;
+$LDWend_helloWorld:
+ } // helloWorld
+
--- /dev/null
+not tested
{ [ os winnt? ] [ "libcurses.dll" ] }
{ [ os macosx? ] [ "libcurses.dylib" ] }
{ [ os unix? ] [ "libcurses.so" ] }
-} cond "cdecl" add-library >>
+} cond cdecl add-library >>
C-TYPE: WINDOW
C-TYPE: SCREEN
! (c)2010 Joe Groff bsd license
-USING: accessors cursors make math sequences sorting tools.test ;
+USING: accessors cursors kernel make math sequences sorting tools.test ;
FROM: cursors => each map assoc-each assoc>map ;
IN: cursors.tests
T{ linear-cursor f 1 1 } T{ linear-cursor f 5 1 } [ value>> 3 mod zero? ] -find
] unit-test
+[ T{ linear-cursor f 5 1 } ] [
+ T{ linear-cursor f 1 1 } T{ linear-cursor f 5 1 } [ value>> 6 = ] -find
+] unit-test
+
[ { 1 3 } ] [
[ T{ linear-cursor f 1 2 } T{ linear-cursor f 5 2 } [ value>> , ] -each ]
{ } make
[ B{ } ] [ [ { } [ , ] each ] B{ } make ] unit-test
[ { 2 4 6 8 10 } ] [ { 1 2 3 4 5 } [ 2 * ] map ] unit-test
-[ { "roses: lutefisk" "tulips: lox" } ]
-[
- [
- { { "roses" "lutefisk" } { "tulips" "lox" } }
- [ ": " glue , ] assoc-each
- ] { } make
-] unit-test
-
-[ { "roses: lutefisk" "tulips: lox" } ]
-[
- { { "roses" "lutefisk" } { "tulips" "lox" } }
- [ ": " glue ] { } assoc>map
-] unit-test
-
[ { "roses: lutefisk" "tulips: lox" } ]
[
[
[ { 2 4 6 8 10 } ] [ { 1 2 3 4 5 } compile-test-map ] unit-test
[ { "roses: lutefisk" "tulips: lox" } ]
-[ [ { { "roses" "lutefisk" } { "tulips" "lox" } } compile-test-assoc-each ] { } make ] unit-test
+[
+ [ H{ { "roses" "lutefisk" } { "tulips" "lox" } } compile-test-assoc-each ]
+ { } make natural-sort
+] unit-test
[ { "roses: lutefisk" "tulips: lox" } ]
-[ { { "roses" "lutefisk" } { "tulips" "lox" } } compile-test-assoc>map ] unit-test
+[
+ H{ { "roses" "lutefisk" } { "tulips" "lox" } } compile-test-assoc>map
+ natural-sort
+] unit-test
MIXIN: input-cursor
-GENERIC: cursor-value ( cursor -- value )
+GENERIC: cursor-key-value ( cursor -- key value )
<PRIVATE
-GENERIC: cursor-value-unsafe ( cursor -- value )
+GENERIC: cursor-key-value-unsafe ( cursor -- key value )
PRIVATE>
-M: input-cursor cursor-value-unsafe cursor-value ; inline
-M: input-cursor cursor-value
- dup cursor-valid? [ cursor-value-unsafe ] [ invalid-cursor ] if ; inline
+M: input-cursor cursor-key-value-unsafe cursor-key-value ; inline
+M: input-cursor cursor-key-value
+ dup cursor-valid? [ cursor-key-value-unsafe ] [ invalid-cursor ] if ; inline
+
+: cursor-key ( cursor -- key ) cursor-key-value drop ;
+: cursor-value ( cursor -- key ) cursor-key-value nip ;
+
+: cursor-key-unsafe ( cursor -- key ) cursor-key-value-unsafe drop ;
+: cursor-value-unsafe ( cursor -- key ) cursor-key-value-unsafe nip ;
!
! output cursors
INSTANCE: numeric-cursor input-cursor
-M: numeric-cursor cursor-value value>> ; inline
+M: numeric-cursor cursor-key-value value>> dup ; inline
!
! linear cursor
INSTANCE: sequence-cursor input-cursor
-M: sequence-cursor cursor-value-unsafe [ n>> ] [ seq>> ] bi nth-unsafe ; inline
-M: sequence-cursor cursor-value [ n>> ] [ seq>> ] bi nth ; inline
+M: sequence-cursor cursor-key-value-unsafe [ n>> dup ] [ seq>> ] bi nth-unsafe ; inline
+M: sequence-cursor cursor-key-value [ n>> dup ] [ seq>> ] bi nth ; inline
INSTANCE: sequence-cursor output-cursor
over map-as ; inline
!
-! assoc cursors
+! assoc combinators
!
-MIXIN: assoc-cursor
-
-GENERIC: cursor-key-value ( cursor -- key value )
-
: -assoc- ( quot -- quot' )
'[ cursor-key-value @ ] ; inline
: assoc>map ( ... assoc quot: ( ... k v -- ... newx ) exemplar -- ... newcontainer )
[ assoc- ] dip -map-as ; inline
-INSTANCE: input-cursor assoc-cursor
-
-M: input-cursor cursor-key-value
- cursor-value-unsafe first2 ; inline
-
!
! hashtable cursor
!
[ hashtable>> dup array>> ] [ n>> 2 + ] bi
(inc-hashtable-cursor) <hashtable-cursor> ; inline
-INSTANCE: hashtable-cursor assoc-cursor
-
-M: hashtable-cursor cursor-key-value
- [ n>> ] [ hashtable>> array>> ] bi
- [ nth-unsafe ] [ [ 1 + ] dip nth-unsafe ] 2bi ; inline
-
INSTANCE: hashtable-cursor input-cursor
-M: hashtable-cursor cursor-value-unsafe
- cursor-key-value 2array ; inline
+M: hashtable-cursor cursor-key-value-unsafe
+ [ n>> ] [ hashtable>> array>> ] bi
+ [ nth-unsafe ] [ [ 1 + ] dip nth-unsafe ] 2bi ; inline
INSTANCE: hashtable container
M: zip-cursor inc-cursor ( cursor -- cursor' )
[ keys>> inc-cursor ] [ values>> inc-cursor ] bi <zip-cursor> ; inline
-INSTANCE: zip-cursor assoc-cursor
+INSTANCE: zip-cursor input-cursor
M: zip-cursor cursor-key-value
[ keys>> cursor-value-unsafe ] [ values>> cursor-value-unsafe ] bi ; inline
--- /dev/null
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors byte-arrays elf kernel sequences tools.test ;
+IN: elf.tests
+
+{
+ {
+ ""
+ ".interp"
+ ".note.ABI-tag"
+ ".note.gnu.build-id"
+ ".hash"
+ ".gnu.hash"
+ ".dynsym"
+ ".dynstr"
+ ".gnu.version"
+ ".gnu.version_r"
+ ".rela.dyn"
+ ".rela.plt"
+ ".init"
+ ".plt"
+ ".text"
+ ".fini"
+ ".rodata"
+ ".eh_frame_hdr"
+ ".eh_frame"
+ ".ctors"
+ ".dtors"
+ ".jcr"
+ ".dynamic"
+ ".got"
+ ".got.plt"
+ ".data"
+ ".bss"
+ ".comment"
+ ".debug_aranges"
+ ".debug_pubnames"
+ ".debug_info"
+ ".debug_abbrev"
+ ".debug_line"
+ ".debug_str"
+ ".shstrtab"
+ ".symtab"
+ ".strtab"
+ }
+}
+[
+ "resource:extra/elf/a.elf" [
+ sections [ name>> ] map
+ ] with-mapped-elf
+]
+unit-test
+
+{
+ {
+ ".interp"
+ ".note.ABI-tag"
+ ".note.gnu.build-id"
+ ".hash"
+ ".gnu.hash"
+ ".dynsym"
+ ".dynstr"
+ ".gnu.version"
+ ".gnu.version_r"
+ ".rela.dyn"
+ ".rela.plt"
+ ".init"
+ ".plt"
+ ".text"
+ ".fini"
+ ".rodata"
+ ".eh_frame_hdr"
+ ".eh_frame"
+ }
+}
+[
+ "resource:extra/elf/a.elf" [
+ segments [ program-header>> p_type>> PT_LOAD = ] find nip
+ sections [ name>> ] map
+ ] with-mapped-elf
+]
+unit-test
+
+{
+ {
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ "init.c"
+ "call_gmon_start"
+ "crtstuff.c"
+ "__CTOR_LIST__"
+ "__DTOR_LIST__"
+ "__JCR_LIST__"
+ "__do_global_dtors_aux"
+ "completed.7342"
+ "dtor_idx.7344"
+ "frame_dummy"
+ "crtstuff.c"
+ "__CTOR_END__"
+ "__FRAME_END__"
+ "__JCR_END__"
+ "__do_global_ctors_aux"
+ "test.c"
+ "_GLOBAL_OFFSET_TABLE_"
+ "__init_array_end"
+ "__init_array_start"
+ "_DYNAMIC"
+ "data_start"
+ "printf@@GLIBC_2.2.5"
+ "__libc_csu_fini"
+ "_start"
+ "__gmon_start__"
+ "_Jv_RegisterClasses"
+ "_fini"
+ "__libc_start_main@@GLIBC_2.2.5"
+ "_IO_stdin_used"
+ "__data_start"
+ "__dso_handle"
+ "__DTOR_END__"
+ "__libc_csu_init"
+ "__bss_start"
+ "_end"
+ "_edata"
+ "main"
+ "_init"
+ }
+}
+[
+ "resource:extra/elf/a.elf" [
+ sections ".symtab" find-section symbols
+ [ name>> ] map
+ ] with-mapped-elf
+]
+unit-test
+
+{
+ B{
+ 85 72 137 229 184 44 6 64 0 72 137 199 184 0 0 0 0 232 222
+ 254 255 255 201 195
+ }
+}
+[
+ "resource:extra/elf/a.elf" [
+ sections ".symtab" "main" find-section-symbol
+ symbol-data >byte-array
+ ] with-mapped-elf
+]
+unit-test
! Copyright (C) 2010 Erik Charlebois.
! See http://factorcode.org/license.txt for BSD license.
-USING: alien.c-types alien.syntax classes.struct ;
+USING: accessors alien alien.c-types alien.strings alien.syntax arrays
+classes.struct fry io.encodings.ascii io.mmap kernel locals math
+math.intervals sequences specialized-arrays strings typed ;
IN: elf
+! FFI data
CONSTANT: EI_NIDENT 16
CONSTANT: EI_MAG0 0
CONSTANT: EI_MAG1 1
STRUCT: Elf64_Dyn
{ d_tag Elf64_Sxword }
{ d_val Elf64_Xword } ;
+
+! Low-level interface
+SPECIALIZED-ARRAYS: Elf32_Shdr Elf64_Shdr Elf32_Sym Elf64_Sym Elf32_Phdr Elf64_Phdr uchar ;
+UNION: Elf32/64_Ehdr Elf32_Ehdr Elf64_Ehdr ;
+UNION: Elf32/64_Shdr Elf32_Shdr Elf64_Shdr ;
+UNION: Elf32/64_Shdr-array Elf32_Shdr-array Elf64_Shdr-array ;
+UNION: Elf32/64_Sym Elf32_Sym Elf64_Sym ;
+UNION: Elf32/64_Sym-array Elf32_Sym-array Elf64_Sym-array ;
+UNION: Elf32/64_Phdr Elf32_Phdr Elf64_Phdr ;
+UNION: Elf32/64_Phdr-array Elf32_Phdr-array Elf64_Phdr-array ;
+
+TYPED: 64-bit? ( elf: Elf32/64_Ehdr -- ? )
+ e_ident>> EI_CLASS swap nth ELFCLASS64 = ;
+
+TYPED: elf-header ( c-ptr -- elf: Elf32/64_Ehdr )
+ [ Elf64_Ehdr memory>struct 64-bit? ] keep swap
+ [ Elf64_Ehdr memory>struct ]
+ [ Elf32_Ehdr memory>struct ] if ;
+
+TYPED:: elf-section-headers ( elf: Elf32/64_Ehdr -- headers: Elf32/64_Shdr-array )
+ elf [ e_shoff>> ] [ e_shnum>> ] bi :> ( off num )
+ off elf >c-ptr <displaced-alien> num
+ elf 64-bit?
+ [ <direct-Elf64_Shdr-array> ]
+ [ <direct-Elf32_Shdr-array> ] if ;
+
+TYPED:: elf-program-headers ( elf: Elf32/64_Ehdr -- headers: Elf32/64_Phdr-array )
+ elf [ e_phoff>> ] [ e_phnum>> ] bi :> ( off num )
+ off elf >c-ptr <displaced-alien> num
+ elf 64-bit?
+ [ <direct-Elf64_Phdr-array> ]
+ [ <direct-Elf32_Phdr-array> ] if ;
+
+TYPED: elf-loadable-segments ( headers: Elf32/64_Phdr-array -- headers: Elf32/64_Phdr-array )
+ [ p_type>> PT_LOAD = ] filter ;
+
+TYPED:: elf-segment-sections ( segment: Elf32/64_Phdr sections: Elf32/64_Shdr-array -- sections )
+ segment [ p_offset>> dup ] [ p_filesz>> + ] bi [a,b) :> segment-interval
+ sections [ dup [ sh_offset>> dup ] [ sh_size>> + ] bi [a,b) 2array ] { } map-as :> section-intervals
+ section-intervals [ second segment-interval interval-intersect empty-interval = not ]
+ filter [ first ] map ;
+
+TYPED:: virtual-address-segment ( elf: Elf32/64_Ehdr address -- program-header/f )
+ elf elf-program-headers elf-loadable-segments [
+ [ p_vaddr>> dup ] [ p_memsz>> + ] bi [a,b)
+ address swap interval-contains?
+ ] filter [ f ] [ first ] if-empty ;
+
+TYPED:: virtual-address-section ( elf: Elf32/64_Ehdr address -- section-header/f )
+ elf address virtual-address-segment :> segment
+ segment elf elf-section-headers elf-segment-sections :> sections
+ address segment p_vaddr>> - segment p_offset>> + :> faddress
+ sections [
+ [ sh_offset>> dup ] [ sh_size>> + ] bi [a,b)
+ faddress swap interval-contains?
+ ] filter [ f ] [ first ] if-empty ;
+
+TYPED:: elf-segment-data ( elf: Elf32/64_Ehdr header: Elf32/64_Phdr -- uchar-array/f )
+ header [ p_offset>> elf >c-ptr <displaced-alien> ] [ p_filesz>> ] bi <direct-uchar-array> ;
+
+TYPED:: elf-section-data ( elf: Elf32/64_Ehdr header: Elf32/64_Shdr -- uchar-array/f )
+ header [ sh_offset>> elf >c-ptr <displaced-alien> ] [ sh_size>> ] bi <direct-uchar-array> ;
+
+TYPED:: elf-section-data-by-index ( elf: Elf32/64_Ehdr index -- header/f uchar-array/f )
+ elf elf-section-headers :> sections
+ index sections nth :> header
+ elf header elf-section-data :> data
+ header data ;
+
+TYPED:: elf-section-name ( elf: Elf32/64_Ehdr header: Elf32/64_Shdr -- name: string )
+ elf elf e_shstrndx>> elf-section-data-by-index nip >c-ptr :> section-names
+ header sh_name>> section-names <displaced-alien> ascii alien>string ;
+
+TYPED:: elf-section-data-by-name ( elf: Elf32/64_Ehdr name: string -- header/f uchar-array/f )
+ elf elf-section-headers :> sections
+ elf e_shstrndx>> :> ndx
+ elf ndx sections nth elf-section-data >c-ptr :> section-names
+ sections 1 tail [
+ sh_name>> section-names <displaced-alien> ascii alien>string name =
+ ] find nip
+ [ dup elf swap elf-section-data ]
+ [ f f ] if* ;
+
+TYPED:: elf-sections ( elf: Elf32/64_Ehdr -- sections )
+ elf elf-section-headers :> sections
+ elf elf e_shstrndx>> elf-section-data-by-index nip >c-ptr :> section-names
+ sections [
+ [ sh_name>> section-names <displaced-alien>
+ ascii alien>string ] keep 2array
+ ] { } map-as ;
+
+TYPED:: elf-symbols ( elf: Elf32/64_Ehdr section-data: uchar-array -- symbols )
+ elf ".strtab" elf-section-data-by-name nip >c-ptr :> strings
+ section-data [ >c-ptr ] [ length ] bi
+ elf 64-bit?
+ [ Elf64_Sym heap-size / <direct-Elf64_Sym-array> ]
+ [ Elf32_Sym heap-size / <direct-Elf32_Sym-array> ] if
+ [ [ st_name>> strings <displaced-alien> ascii alien>string ] keep 2array ] { } map-as ;
+
+! High level interface
+TUPLE: elf elf-header ;
+TUPLE: section name elf-header section-header data ;
+TUPLE: segment elf-header program-header data ;
+TUPLE: symbol name elf-header sym data ;
+
+GENERIC: sections ( obj -- sections )
+
+: <elf> ( c-ptr -- elf )
+ elf-header elf boa ;
+
+M:: elf sections ( elf -- sections )
+ elf elf-header>> elf-sections
+ [
+ first2 :> ( name header )
+ elf elf-header>> header elf-section-data :> data
+ name elf elf-header>> header data section boa
+ ] { } map-as ;
+
+:: segments ( elf -- segments )
+ elf elf-header>> elf-program-headers
+ [| header |
+ elf elf-header>> header elf-segment-data :> data
+ elf elf-header>> header data segment boa
+ ] { } map-as ;
+
+M:: segment sections ( segment -- sections )
+ segment program-header>>
+ segment elf-header>> elf-section-headers
+ elf-segment-sections
+
+ [| header |
+ segment elf-header>> header elf-section-name :> name
+ segment elf-header>> header elf-section-data :> data
+ name segment elf-header>> header data section boa
+ ] { } map-as ;
+
+:: symbols ( section -- symbols )
+ section elf-header>>
+ section data>>
+ elf-symbols
+ [
+ first2 :> ( name sym )
+ name section elf-header>> sym f symbol boa
+ ] { } map-as ;
+
+:: symbol-data ( symbol -- data )
+ symbol [ elf-header>> ] [ sym>> st_value>> ] bi virtual-address-segment :> segment
+ symbol sym>> st_value>> segment p_vaddr>> - segment p_offset>> + :> faddress
+ faddress symbol elf-header>> >c-ptr <displaced-alien>
+ symbol sym>> st_size>> <direct-uchar-array> ;
+
+: find-section ( sections name -- section/f )
+ '[ name>> _ = ] find nip ; inline
+
+: find-symbol ( symbols name -- symbol/f )
+ '[ name>> _ = ] find nip ; inline
+
+: find-section-symbol ( sections section symbol -- symbol/f )
+ [ find-section ] dip over [
+ [ symbols ] dip find-symbol ] [ 2drop f ] if ;
+
+: with-mapped-elf ( path quot -- )
+ '[
+ address>> <elf> @
+ ] with-mapped-file ; inline
--- /dev/null
+Erik Charlebois
--- /dev/null
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: elf help.markup help.syntax ;
+IN: elf.nm
+
+HELP: elf-nm
+{ $values
+ { "path" "a pathname string" }
+}
+{ $description "Prints information about the symbols in the ELF object at the given path." } ;
+
+HELP: print-symbol
+{ $values
+ { "sections" "sequence of section" } { "symbol" symbol }
+}
+{ $description "Prints the value, section and name of the given symbol." } ;
+
+ARTICLE: "elf.nm" "ELF nm"
+"The " { $vocab-link "elf.nm" } " vocab prints the values, sections and names of the symbols in a given ELF file. In an ELF executable or shared library, the symbol values are typically their virtual addresses. In a relocatable ELF object, they are section-relative offsets."
+{ $subsections elf-nm }
+;
+
+ABOUT: "elf.nm"
--- /dev/null
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: elf.nm io io.streams.string kernel multiline strings tools.test
+literals ;
+IN: elf.nm.tests
+
+STRING: validation-output
+0000000000000000 absolute init.c
+000000000040046c .text call_gmon_start
+0000000000000000 absolute crtstuff.c
+0000000000600e18 .ctors __CTOR_LIST__
+0000000000600e28 .dtors __DTOR_LIST__
+0000000000600e38 .jcr __JCR_LIST__
+0000000000400490 .text __do_global_dtors_aux
+0000000000601020 .bss completed.7342
+0000000000601028 .bss dtor_idx.7344
+0000000000400500 .text frame_dummy
+0000000000000000 absolute crtstuff.c
+0000000000600e20 .ctors __CTOR_END__
+00000000004006d8 .eh_frame __FRAME_END__
+0000000000600e38 .jcr __JCR_END__
+00000000004005e0 .text __do_global_ctors_aux
+0000000000000000 absolute test.c
+0000000000600fe8 .got.plt _GLOBAL_OFFSET_TABLE_
+0000000000600e14 .ctors __init_array_end
+0000000000600e14 .ctors __init_array_start
+0000000000600e40 .dynamic _DYNAMIC
+0000000000601010 .data data_start
+0000000000000000 undefined printf@@GLIBC_2.2.5
+0000000000400540 .text __libc_csu_fini
+0000000000400440 .text _start
+0000000000000000 undefined __gmon_start__
+0000000000000000 undefined _Jv_RegisterClasses
+0000000000400618 .fini _fini
+0000000000000000 undefined __libc_start_main@@GLIBC_2.2.5
+0000000000400628 .rodata _IO_stdin_used
+0000000000601010 .data __data_start
+0000000000601018 .data __dso_handle
+0000000000600e30 .dtors __DTOR_END__
+0000000000400550 .text __libc_csu_init
+0000000000601020 absolute __bss_start
+0000000000601030 absolute _end
+0000000000601020 absolute _edata
+0000000000400524 .text main
+00000000004003f0 .init _init
+
+;
+
+{ $ validation-output }
+[ <string-writer> dup [ "resource:extra/elf/a.elf" elf-nm ] with-output-stream >string ]
+unit-test
--- /dev/null
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors combinators elf formatting io.mmap kernel sequences ;
+IN: elf.nm
+
+: print-symbol ( sections symbol -- )
+ [ sym>> st_value>> "%016x " printf ]
+ [
+ sym>> st_shndx>>
+ {
+ { SHN_UNDEF [ drop "undefined" ] }
+ { SHN_ABS [ drop "absolute" ] }
+ { SHN_COMMON [ drop "common" ] }
+ [ swap nth name>> ]
+ } case "%-16s " printf
+ ]
+ [ name>> "%s\n" printf ] tri ;
+
+: elf-nm ( path -- )
+ [
+ sections dup ".symtab" find-section
+ symbols [ name>> empty? not ] filter
+ [ print-symbol ] with each
+ ] with-mapped-elf ;
--- /dev/null
+UNIX nm-like utility.
--- /dev/null
+Erik Charlebois
--- /dev/null
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays classes.struct destructors game.loop
+game.worlds gpu gpu.buffers gpu.effects.blur gpu.framebuffers
+gpu.render gpu.shaders gpu.state gpu.textures gpu.util images
+images.loader kernel literals locals make math math.rectangles
+math.vectors namespaces opengl.gl sequences specialized-arrays
+ui.gadgets.worlds ui.gestures ui.pixel-formats gpu.effects.step
+images.pgm images.ppm ;
+FROM: alien.c-types => float ;
+SPECIALIZED-ARRAY: float
+IN: fluids
+
+STRUCT: particle_t
+ { p float[2] }
+ { v float[2] }
+ { m float } ;
+SPECIALIZED-ARRAY: particle_t
+
+CONSTANT: gravity { 0.0 -0.1 }
+
+:: verlet-integrate-particle ( particle dt -- particle' )
+ particle [ p>> ] [ v>> ] bi dt v*n v+
+ gravity dt dt * particle m>> 2 * / v*n v+ :> p'
+ p' particle p>> v- dt v/n :> v'
+ p' v' particle m>> particle_t <struct-boa> ; inline
+
+CONSTANT: initial-particles
+particle_t-array{
+ S{ particle_t f float-array{ 0.5 0.6 } float-array{ 0 0.1 } 1.0 }
+ S{ particle_t f float-array{ 0.5 0.6 } float-array{ 0.1 0 } 3.0 }
+
+ S{ particle_t f float-array{ 0.5 0.5 } float-array{ 0.1 0.1 } 2.0 }
+ S{ particle_t f float-array{ 0.5 0.6 } float-array{ -0.1 0 } 1.0 }
+ S{ particle_t f float-array{ 0.6 0.5 } float-array{ 0 -0.1 } 3.0 }
+ S{ particle_t f float-array{ 0.7 0.5 } float-array{ 0.1 0.1 } 1.0 }
+ S{ particle_t f float-array{ 0.1 0.5 } float-array{ -0.1 -0.1 } 5.0 }
+ S{ particle_t f float-array{ 0.2 0.5 } float-array{ 0 0 } 1.0 }
+ S{ particle_t f float-array{ 0.3 0.3 } float-array{ 0 0 } 4.0 }
+ S{ particle_t f float-array{ 0.5 0.15 } float-array{ 0 0 } 1.0 }
+ S{ particle_t f float-array{ 0.5 0.1 } float-array{ 0 0 } 9.0 }
+}
+
+: integrate-particles! ( particles dt -- particles )
+ [ verlet-integrate-particle ] curry map! ;
+
+TUPLE: fluids-world < game-world
+ particles texture ramp { paused boolean initial: f } ;
+
+: make-texture ( pathname -- texture )
+ load-image
+ [
+ [ component-order>> ]
+ [ component-type>> ] bi
+ T{ texture-parameters
+ { wrap clamp-texcoord-to-edge }
+ { min-filter filter-nearest }
+ { mag-filter filter-nearest }
+ { min-mipmap-filter f } }
+ <texture-2d>
+ ]
+ [
+ 0 swap [ allocate-texture-image ] 3keep 2drop
+ ] bi ;
+
+SYMBOL: fluid
+
+: integrate ( world -- )
+ particles>> $[ 60 fps 1000000 /f ] integrate-particles! drop ;
+
+: pause ( -- )
+ fluid get [ not ] change-paused drop ;
+
+: step ( -- )
+ fluid get paused>> [ fluid get integrate ] when ;
+
+M: fluids-world begin-game-world
+ dup fluid set
+ init-gpu
+ initial-particles clone >>particles
+ "resource:extra/fluids/particle2.pgm" make-texture >>texture
+ "resource:extra/fluids/colors.ppm" make-texture >>ramp
+ drop ;
+
+M: fluids-world end-game-world
+ drop ;
+
+M: fluids-world tick-game-world
+ dup paused>> [ drop ] [ integrate ] if ;
+
+M:: fluids-world draw-world* ( world -- )
+ world particles>> [
+ [ p>> [ first , ] [ second , ] bi ] each
+ ] curry float-array{ } make :> verts
+
+ [
+ verts world texture>> 30.0 world dim>> { 4 4 } v/
+ blended-point-sprite-batch &dispose
+ blend-state new set-gpu-state
+ gaussian-blur &dispose
+ world ramp>> world dim>> step-texture &dispose
+ world dim>> draw-texture
+ ] with-destructors ;
+
+GAME: fluids {
+ { world-class fluids-world }
+ { title "Fluids Test" }
+ { pixel-format-attributes {
+ windowed double-buffered T{ depth-bits { value 24 } } } }
+ { pref-dim { 1024 768 } }
+ { tick-interval-micros $[ 60 fps ] }
+} ;
+
+fluids-world H{
+ { T{ button-down } [ [
+ hand-loc get >float-array
+ world get dim>> >float-array v/ 2 v*n 1 v-n { 1 -1 } v*
+ float-array{ 0 0.2 } 2.0 particle_t <struct-boa> suffix
+ ] change-particles drop ] }
+} set-gestures
IN: freetype
<< "freetype" {
- { [ os macosx? ] [ "/usr/X11R6/lib/libfreetype.6.dylib" "cdecl" add-library ] }
- { [ os windows? ] [ "freetype6.dll" "cdecl" add-library ] }
+ { [ os macosx? ] [ "/usr/X11R6/lib/libfreetype.6.dylib" cdecl add-library ] }
+ { [ os windows? ] [ "freetype6.dll" cdecl add-library ] }
{ [ t ] [ drop ] }
} cond >>
FUNCTION: FT_Error FT_Load_Char ( face* face, FT_ULong charcode, FT_Int32 load_flags ) ;
-C-ENUM:
+C-ENUM: f
FT_RENDER_MODE_NORMAL
FT_RENDER_MODE_LIGHT
FT_RENDER_MODE_MONO
FT_RENDER_MODE_LCD
FT_RENDER_MODE_LCD_V ;
-C-ENUM:
+C-ENUM: f
FT_PIXEL_MODE_NONE
FT_PIXEL_MODE_MONO
FT_PIXEL_MODE_GRAY
GLSL-SHADER-FILE: sobel-fragment-shader fragment-shader "sobel.f.glsl"
GLSL-PROGRAM: sobel-program
window-vertex-shader sobel-fragment-shader
- window-vertex ;
+ window-vertex-format ;
GLSL-SHADER-FILE: loading-fragment-shader fragment-shader "loading.f.glsl"
GLSL-PROGRAM: loading-program
window-vertex-shader loading-fragment-shader
- window-vertex ;
+ window-vertex-format ;
TUPLE: bunny-state
vertexes
GLSL-SHADER-FILE: raytrace-fragment-shader fragment-shader "raytrace.f.glsl"
GLSL-PROGRAM: raytrace-program
raytrace-vertex-shader raytrace-fragment-shader
- window-vertex ;
+ window-vertex-format ;
UNIFORM-TUPLE: sphere-uniforms
{ "center" vec3-uniform f }
--- /dev/null
+Erik Charlebois
--- /dev/null
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: arrays destructors fry gpu.framebuffers gpu.render gpu.shaders
+gpu.state gpu.textures gpu.util images kernel locals math
+math.rectangles sequences ;
+IN: gpu.effects.blur
+
+GLSL-SHADER: blur-fragment-shader fragment-shader
+uniform sampler2D texture;
+uniform bool horizontal;
+uniform float blurSize;
+varying vec2 texcoord;
+void main()
+{
+ vec4 col = 0.16 * texture2D(texture, texcoord);
+ if (horizontal)
+ {
+ vec2 blurX1 = vec2(blurSize, 0.0);
+ vec2 blurX2 = vec2(blurSize * 2.0, 0.0);
+ vec2 blurX3 = vec2(blurSize * 3.0, 0.0);
+ vec2 blurX4 = vec2(blurSize * 4.0, 0.0);
+ col += 0.15 * ( texture2D(texture, texcoord - blurX1)
+ + texture2D(texture, texcoord + blurX1));
+ col += 0.12 * ( texture2D(texture, texcoord - blurX2)
+ + texture2D(texture, texcoord + blurX2));
+ col += 0.09 * ( texture2D(texture, texcoord - blurX3)
+ + texture2D(texture, texcoord + blurX3));
+ col += 0.05 * ( texture2D(texture, texcoord - blurX4)
+ + texture2D(texture, texcoord + blurX4));
+ }
+ else
+ {
+ vec2 blurY1 = vec2(0.0, blurSize);
+ vec2 blurY2 = vec2(0.0, blurSize * 2.0);
+ vec2 blurY3 = vec2(0.0, blurSize * 3.0);
+ vec2 blurY4 = vec2(0.0, blurSize * 4.0);
+ col += 0.15 * ( texture2D(texture, texcoord - blurY1)
+ + texture2D(texture, texcoord + blurY1));
+ col += 0.12 * ( texture2D(texture, texcoord - blurY2)
+ + texture2D(texture, texcoord + blurY2));
+ col += 0.09 * ( texture2D(texture, texcoord - blurY3)
+ + texture2D(texture, texcoord + blurY3));
+ col += 0.05 * ( texture2D(texture, texcoord - blurY4)
+ + texture2D(texture, texcoord + blurY4));
+ }
+ gl_FragColor = col;
+}
+;
+
+UNIFORM-TUPLE: blur-uniforms
+ { "texture" texture-uniform f }
+ { "horizontal" bool-uniform f }
+ { "blurSize" float-uniform f } ;
+
+GLSL-PROGRAM: blur-program window-vertex-shader blur-fragment-shader window-vertex-format ;
+
+:: (blur) ( texture horizontal? framebuffer dim -- )
+ { 0 0 } dim <rect> <viewport-state> set-gpu-state
+ texture horizontal? 1.0 dim horizontal? [ first ] [ second ] if / blur-uniforms boa framebuffer {
+ { "primitive-mode" [ 2drop triangle-strip-mode ] }
+ { "uniforms" [ drop ] }
+ { "vertex-array" [ 2drop blur-program <program-instance> <window-vertex-array> &dispose ] }
+ { "indexes" [ 2drop T{ index-range f 0 4 } ] }
+ { "framebuffer" [ nip ] }
+ } 2<render-set> render ;
+
+:: blur ( texture horizontal? -- texture )
+ texture 0 texture-dim :> dim
+ dim RGB float-components <2d-render-texture> :> ( target-framebuffer target-texture )
+ texture horizontal? target-framebuffer dim (blur)
+ target-framebuffer dispose
+ target-texture ;
+
+: horizontal-blur ( texture -- texture ) t blur ; inline
+
+: vertical-blur ( texture -- texture ) f blur ; inline
+
+: discompose ( quot1 quot2 -- compose )
+ '[ @ &dispose @ ] with-destructors ; inline
+
+: gaussian-blur ( texture -- texture )
+ [ horizontal-blur ] [ vertical-blur ] discompose ;
--- /dev/null
+Blur effects for textures.
--- /dev/null
+Erik Charlebois
--- /dev/null
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: destructors gpu.render gpu.shaders gpu.state gpu.textures
+gpu.util images kernel locals math.rectangles ;
+IN: gpu.effects.step
+
+GLSL-SHADER: step-fragment-shader fragment-shader
+const vec4 luminance = vec4(0.3, 0.59, 0.11, 0.0);
+uniform sampler2D texture;
+uniform sampler2D ramp;
+varying vec2 texcoord;
+void main()
+{
+ vec4 col = texture2D(texture, texcoord);
+ float l = dot(col, luminance);
+ gl_FragColor = texture2D(ramp, vec2(l, 0.0));
+}
+;
+
+UNIFORM-TUPLE: step-uniforms
+ { "texture" texture-uniform f }
+ { "ramp" texture-uniform f } ;
+
+GLSL-PROGRAM: step-program window-vertex-shader step-fragment-shader window-vertex-format ;
+
+: (step-texture) ( texture ramp texture dim -- )
+ { 0 0 } swap <rect> <viewport-state> set-gpu-state
+ [ step-uniforms boa ] dip {
+ { "primitive-mode" [ 2drop triangle-strip-mode ] }
+ { "uniforms" [ drop ] }
+ { "vertex-array" [ 2drop <window-vertex-buffer> step-program <program-instance> <vertex-array> ] }
+ { "indexes" [ 2drop T{ index-range f 0 4 } ] }
+ { "framebuffer" [ nip ] }
+ } 2<render-set> render ;
+
+:: step-texture ( texture ramp dim -- texture )
+ dim RGB float-components <2d-render-texture> :> ( target-framebuffer target-texture )
+ texture ramp target-framebuffer dim (step-texture)
+ target-framebuffer dispose
+ target-texture ;
--- /dev/null
+Render a quad with a step texture.
dup 1 = [ drop ] [ 2array ] if ;
SYMBOL: padding-no
-padding-no [ 0 ] initialize
: padding-name ( -- name )
"padding-"
- padding-no get number>string append
- "(" ")" surround
- padding-no inc ;
+ padding-no counter number>string append
+ "(" ")" surround ;
: vertex-attribute>struct-slot ( vertex-attribute -- struct-slot-spec )
[ name>> [ padding-name ] unless* ]
! (c)2009 Joe Groff bsd license
-USING: gpu.buffers gpu.render gpu.shaders gpu.textures images kernel
-specialized-arrays ;
+USING: arrays destructors gpu.buffers gpu.framebuffers gpu.render
+gpu.shaders gpu.state gpu.textures images kernel locals math
+math.rectangles opengl.gl sequences specialized-arrays ;
FROM: alien.c-types => float ;
SPECIALIZED-ARRAY: float
IN: gpu.util
{ 0.0 0.0 0.0 1.0 }
} }
}
+
+GLSL-SHADER: window-vertex-shader vertex-shader
+attribute vec2 vertex;
+varying vec2 texcoord;
+void main()
+{
+ texcoord = vertex * vec2(0.5) + vec2(0.5);
+ gl_Position = vec4(vertex, 0.0, 1.0);
+}
+;
-VERTEX-FORMAT: window-vertex
+GLSL-SHADER: window-fragment-shader fragment-shader
+uniform sampler2D texture;
+varying vec2 texcoord;
+void main()
+{
+ gl_FragColor = texture2D(texture, texcoord);
+}
+;
+
+VERTEX-FORMAT: window-vertex-format
{ "vertex" float-components 2 f } ;
+UNIFORM-TUPLE: window-uniforms
+ { "texture" texture-uniform f } ;
+
+GLSL-PROGRAM: window-program window-vertex-shader window-fragment-shader window-vertex-format ;
+
+GLSL-SHADER: window-point-vertex-shader vertex-shader
+uniform float point_size;
+attribute vec2 vertex;
+void main()
+{
+ gl_Position = vec4(vertex, 0.0, 1.0);
+ gl_PointSize = point_size;
+}
+;
+
+GLSL-SHADER: window-point-fragment-shader fragment-shader
+#version 120
+uniform sampler2D texture;
+void main()
+{
+ gl_FragColor = texture2D(texture, gl_PointCoord);
+}
+;
+
+UNIFORM-TUPLE: window-point-uniforms
+ { "texture" texture-uniform f }
+ { "point_size" float-uniform f } ;
+
+GLSL-PROGRAM: window-point-program window-point-vertex-shader window-point-fragment-shader window-vertex-format ;
+
CONSTANT: window-vertexes
float-array{
-1.0 -1.0
byte-array>buffer ; inline
: <window-vertex-array> ( program-instance -- vertex-array )
- [ <window-vertex-buffer> ] dip window-vertex <vertex-array*> ; inline
+ [ <window-vertex-buffer> ] dip window-vertex-format <vertex-array*> ; inline
+
+:: <2d-render-texture> ( dim order type -- renderbuffer texture )
+ order type
+ T{ texture-parameters
+ { wrap clamp-texcoord-to-edge }
+ { min-filter filter-linear }
+ { min-mipmap-filter f } }
+ <texture-2d> [
+ 0 <texture-2d-attachment> 1array f f dim <framebuffer>
+ dup { { default-attachment { 0 0 0 } } } clear-framebuffer
+ ] keep ;
+
+: draw-texture ( texture dim -- )
+ { 0 0 } swap <rect> <viewport-state> set-gpu-state
+ {
+ { "primitive-mode" [ drop triangle-strip-mode ] }
+ { "uniforms" [ window-uniforms boa ] }
+ { "vertex-array" [ drop window-program <program-instance> <window-vertex-array> &dispose ] }
+ { "indexes" [ drop T{ index-range f 0 4 } ] }
+ } <render-set> render ;
+
+:: <streamed-vertex-array> ( verts program-instance -- vertex-array )
+ verts stream-upload draw-usage vertex-buffer byte-array>buffer &dispose
+ program-instance <vertex-array> &dispose ;
+
+: (blended-point-sprite-batch) ( verts framebuffer texture point-size dim -- )
+ f eq-add func-one func-one <blend-mode> dup <blend-state> set-gpu-state
+ f origin-upper-left 1.0 <point-state> set-gpu-state
+ GL_POINT_SPRITE glEnable
+ { 0 0 } swap <rect> <viewport-state> set-gpu-state
+ window-point-uniforms boa {
+ { "primitive-mode" [ 3drop points-mode ] }
+ { "uniforms" [ 2nip ] }
+ { "vertex-array" [ 2drop window-point-program <program-instance> <streamed-vertex-array> ] }
+ { "indexes" [ 2drop length 2 / 0 swap <index-range> ] }
+ { "framebuffer" [ drop nip ] }
+ } 3<render-set> render ;
+
+:: blended-point-sprite-batch ( verts texture point-size dim -- texture )
+ dim RGB float-components <2d-render-texture> :> ( target-framebuffer target-texture )
+ verts target-framebuffer texture point-size dim (blended-point-sprite-batch)
+ target-framebuffer dispose
+ target-texture ;
--- /dev/null
+P1
+# CREATOR: GIMP PNM Filter Version 1.1
+160 160
+1111111100000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000111111111111111100000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000011111111111111111000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000111111111111111111
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0111111111111111111000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000111111111111111110000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000001111111111111111100000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000011111111
+1111111110000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000111111101111110000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001011111001010000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000101000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000001111
+1111111111111111111111010000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000011111111111111111111111111111111000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001111111111111111111111111111111111100
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000111111111111111111
+1111111111111111111000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0111111111111111111111111111111111111111000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001111111111111111111111111111111111111110000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000011111111111111111111111111111
+1111111111000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000001111111111
+1111111111111111111111111111110000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000111111111111111111111111111111111111111100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000011111111111111111111111111111111111111111
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000111111111111111111111
+1111111111111111111100000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001
+1111111111111111111111111111111111111111000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000111111111111000000000000000001111111111110000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000001111111111110000000000000000011
+1111111111000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000011111111111
+1000000000000000001111111111110000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000001111111111110000000000000000011111111111100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000011111111111100000000000000000111111111111
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000111111111111000000000
+0000000011111111111100000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001
+1111111111100000000000000000111111111111000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000111111111111000000000000000001111111111110000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000001111111111110000000000000000011
+1111111111000000000000000000000000000000000000000000000000000000000000
+0000000000011110100000000000000000000000000000000000000000011111111111
+1000000000000000001111111111110000000000000000000000000000000000000000
+0000000000000000000000000000111111111110000000000000000000000000000000
+0000000001111111111110000000000000000011111111111100000000000000000000
+0000000000000000000000000000000000000000000000111111111111110000000000
+0000000000000000000000000000011111111111100000000000000000111111111111
+0000000000000000000000000000000000000000000000000000000000000001111111
+1111111111100000000000000000000000000000000000000111111111111000000000
+0000000111111111111100000000000000000000000000000000000000000000000000
+0000000000111111111111111111111100000000000000000000000000000000000001
+1111111111100000000000000001111111111110000000000000000000000000000000
+0000000000000000000000000000011111111111111111111111000000000000000000
+0000000000000000001111111111111000000000000000011111111111100000000000
+0000000000000000000000000000000000000000000000011111111111111111111111
+1110000000000000000000000000000000000001111111111100000000000000000111
+1111111110000000000000000000000000000000000000000000000000000000001111
+1111111111111111111111100000000000000000000000000000000000111111111111
+0000000000000000011111111111100000000000000000000000000000000000000000
+0000000000000011111111111111111111111111111000000000000000000000000000
+0000000011111111111100000000000000000111111111110000000000000000000000
+0000000000000000000000000000000011111111111111111111111111111110000000
+0000000000000000000000000000111111111111000000000000000011111111111100
+0000000000000000000000000000000000000000000000000001111111111111111111
+1111111111111000000000000000000000000000000000001111111111110000000000
+0000001111111111110000000000000000000000000000000000000000000000000000
+1111111111111111111111111111111110000000000000000000000000000000000011
+1111111111000000000000000011111111111100000000000000000000000000000000
+0000000000000000000111111111111111111111111111111111110000000000000000
+0000000000000000001111111111110000000000000000111111111111000000000000
+0000000000000000000000000000000000000001111111111111111111111011111111
+1111000000000000000000000000000000000111111111111100000000000000001111
+1111111100000000000000000000000000000000000000000000000000011111111111
+1111110000001111111111110000000000000000000000000000000011111111111110
+0000000000000000111111111111000000000000000000000000000000000000000000
+0000000011111111111111111000000011111111111110000000000000000000000000
+0000011111111111111000000000000000001111111111110000000000000000000000
+0000000000000000000000000000111111111111111000000000011111111111000000
+0000000000000000000000000111111111111110000000000000000011111111111100
+0000000000000000000000000000000000000000000000001111111111111100000000
+0001111111111110000000000000000000000000000011111111111111000000000000
+0000001111111111110000000000000000000000000000000000000000000000000011
+1111111111000000000000011111111111100000000000000000000000000011111111
+1111111100000000000000000011111111111100000000000000000000000000000000
+0000000000000000001111111111100000000000000111111111111000000000000000
+0000000000001111111111111110000000000000000000111111111111000000000000
+0000000000000000000000000000000000000111111111111000000000000001111111
+1111100000000000000000000000000111111111111111000000000000000000001111
+1111111100000000000000000000000000000000000000000000000001111111111110
+0000000000000111111111111000000000000000000000000011111111111111110000
+0000000000000000111111111111000000000000000000000000000000000000000000
+0000000111111111111000000000000001111111111110000000000000000000000001
+1111111111111110000000000000000000001111111111110000000000000000000000
+0000000000000000000000000001111111111110000000000000011111111111110000
+0000000000000000000111111111111111000000000000000000000011111111111100
+0000000000000000000000000000000000000000000000011111111111100000000000
+0000111111111111000000000000000000000111111111111111100000000000000000
+0000001111111111110000000000000000000000000000000000000000000000000111
+1111111110000000000000001111111111110000000000000000000011111111111111
+1100000000000000000000000011111111111100000000000000000000000000000000
+0000000000000000011111111111100000000000000011111111111110000000000000
+0000011111111111111110000000000000000000000000111111111111000000000000
+0000000000000000000000000000000000000111111111111000000000000000011111
+1111111000000000000000000111111111111111100000000000000000000000001111
+1111111100000000000000000000000000000000000000000000000001111111111110
+0000000000000001111111111110000000000000000111111111111111100000000000
+0000000000000000111111111110000000000000000000000000000000000000000000
+0000000111111111111000000000000000011111111111100000000000000001111111
+1111111110000000000000000000000000011111111111110000000000000000000000
+0000000000000000000000000001111111111110000000000000000111111111111000
+0000000000001111111111111111000000000000000000000000000111111111111000
+0000000000000000000000000000000000000000000000011111111111100000000000
+0000011111111111110000000000000111111111111111100000000000000000000000
+0000011111111111100000000000000000000000000000000000000000000000000111
+1111111110000000000000000011111111111100000000000011111111111111110000
+0000000000000000000000000111111111111000000000000000000000000000000000
+0000000000000000011111111111100000000000000000111111111111000000000001
+1111111111111100000000000000000000000000000001111111111110000000000000
+0000000000000000000000000000000000000111111111111000000000000000001111
+1111111110000000001111111111111111000000000000000000000000000000011111
+1111111000000000000000000000000000000000000000000000000001111111111110
+0000000000000000011111111111100000000111111111111111100000000000000000
+0000000000000001111111111110000000000000000000000000000000000000000000
+0000000111111111111000000000000000000111111111111000000111111111111111
+1100000000000000000000000000000000011111111111100000000000000000000000
+0000000000000000000000000001111111111110000000000000000001111111111110
+0000011111111111111110000000000000000000000000000000000111111111111000
+0000000000000000000000000000000000000000000000011111111111100000000000
+0000000111111111111000011111111111111111000000000000000000000000000000
+0000011111111111100000000000000000000000000000000000000000000000000111
+1111111110000000000000000000111111111111001111111111111111110000000000
+0000000000000000000000000111111111111000000000000000000000000000000000
+0000000000000000011111111111100000000000000000001111111111110111111111
+1111111100000000000000000000000000000000000001111111111110000000000000
+0000000000000000000000000000000000000111111111111000000000000000000011
+1111111111111111111111111111000000000000000000000000000000000000011111
+1111111000000000000000000000000000000000000000000000000001111111111110
+0000000000000000001111111111111111111111111111000000000000000000000000
+0000000000000001111111111110000000000000000000000000000000000000000000
+0000000111111111111000000000000000000001111111111111111111111111100000
+0000000000000000000000000000000000011111111111100000000000000000000000
+0000000000000000000000000001111111111110000000000000000000011111111111
+1111111111111100000000000000000000000000000000000000001111111111110000
+0000000000000000000000000000000000000000000000011111111111100000000000
+0000000001111111111111111111111110000000000000000000000000000000000000
+0000111111111111000000000000000000000000000000000000000000000000000111
+1111111110000000000000000000011111111111111111111111000000000000000000
+0000000000000000000000001111111111110000000000000000000000000000000000
+0000000000000000011111111111100000000000000000000111111111111111111111
+0000000000000000000000000000000000000000000011111111111100000000000000
+0000000000000000000000000000000000000111111111111000000000000000000001
+1111111111111111111000000000000000000000000000000000000000000000111111
+1111110000000000000000000000000000000000000000000000000001111111111110
+0000000000000000000111111111111111111100000000000000000000000000000000
+0000000000000011111111111100000000000000000000000000000000000000000000
+0000000111111111111000000000000000000000111111111111111110000000000000
+0000000000000000000000000000000000111111111111000000000000000000000000
+0000000000000000000000000001111111111110000000000000000000001111111111
+1111111000000000000000000000000000000000000000000000001111111111110000
+0000000000000000000000000000000000000000000000011111111111100000000000
+0000000000111111111111111000000000000000000000000000000000000000000000
+0000111111111111000000000000000000000000000000000000000000000000000111
+1111111110000000000000000000001111111111111000000000000000000000000000
+0000000000000000000000001111111111110000000000000000000000000000000000
+0000000000000000011111111111100000000000000000000001111111111110000000
+0000000000000000000000000000000000000000000011111111111100000000000000
+0000000000000000000000000000000000000111111111111000000000000000000000
+0011111111110000000000000000000000000000000000000000000000000000111111
+1111110000000000000000000000000000000000000000000000000001111111111110
+0000000000000000000000011111110000001011111111111110100000000000000000
+0000000000000011111111111100000000000000000000000000000000000000000000
+0000000111111111111000000000000000000000000000101010111111111111111111
+1111111111000000000000000000000000111111111111000000000000000000000000
+0000000000000000000000000001111111111110000000000000000000000000001111
+1111111111111111111111111111111100000000000000000000001111111111110000
+0000000000000000000000000000000000000000000000011111111111100000000000
+0000000101111111111111111111111111111111111111111111100000000000000000
+0000111111111111000000000000000000000000000000000000000000000000000111
+1111111110000000000000101111111111111111111111111111111111111111111111
+1110000000000000000000001111111111110000000000000000000000000000000000
+0000000000000000011111111111100000101111111111111111111111111111111111
+1111111111111111111111110000000000000000000011111111111100000000000000
+0000000000000000000000000000000000000111111111111000111111111111111111
+1111111111111111111111111111111111111111111100000000000000000000111111
+1111110000000000000000000000000000000000000000000000000001111111111110
+0011111111111111111111111111111111111111111111111111111111111111000000
+0000000000000011111111111100000000000000000000000000000000000000000000
+0000000111111111111111111111111111111111111111111111111111111111111111
+1111111111111100000000000000000000111111111111000000000000000000000000
+0000000000000000000000000001111111111111111111111111111111111111111111
+1111111111111111111111111111111110000000000000000000011111111111110000
+0000000000000000000000000000000000000000000000011111111111111111111111
+1111111111111111111111111111111111111111111111111111100000000000000000
+0001111111111110000000000000000000000000000000000000000000000000000111
+1111111111111111111111111111111111111111111111111111111111111111111111
+1100000000000000000000011111111111100000000000000000000000000000000000
+0000000000000000011111111111111111111111111111111111111111111111111111
+1111111111111111111100000000000000000000000111111111111000000000000000
+0000000000000000000000000000000000000111111111111111111111111111111111
+1111111111111111111111111111111111111000000000000000000000000011111111
+1111100000000000000000000000000000000000000000000000000001111111111111
+1111111111111111111111111111111111111111111111111111110000000000000000
+0000000000011111111111110000000000000000000000000000000000000000000000
+0000000111111111111111111111111111110100000000111111111111111111111111
+1100000000000000000000000000000111111111111100000000000000000000000000
+0000000000000000000000000001111111111111111111111111010000000000011111
+1111111111111111111000000000000000000000000000000111111111111111000000
+0000000000000000000000000000000000000000000000111111111111111111111000
+0000000000000111111111111111111111111000000000000000000000000000000001
+1111111111111000000000000000000000000000000000000000000000000000001111
+1111111111111110000000000000000111111111111111111111111000000000000000
+0000000000000000011111111111111110000000000000000000000000000000000000
+0000000000000000111111111111111100000000000000000111111111111111111111
+1111000000000000000000000000000000011111111111111111000000000000000000
+0000000000000000000000000000000000001111111111111110000000000000000011
+1111111111111111111110000000000000000000000000000000001111111111111111
+1000000000000000000000000000000000000000000000000000000001111111111110
+0000000000000000001111111111111111111101000000000000000000000000000000
+0001111111111111111110000000000000000000000000000000000000000000000000
+0000000111111111110000000000000000000111111111111111111110000000000000
+0000000000000000000001111111111111111111000000000000000000000000000000
+0000000000000000000000000000111111111000000000000000000011111111111111
+1111110000000000000000000000000000000000011111111111111111100000000000
+0000000000000000000000000000000000000000000000000111111100000000000000
+0000001111111111111111100000000000000000000000000000000000011111111111
+1111111100000000000000000000000000000000000000000000000000000000000000
+0010100000000000000000000011111111111111110000000000000000000000000000
+0000000011111111111111111110000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000111111111111111000000000
+0000000000000000000000000011111111111111111110000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000001111
+1111111110000000000000000000000000000000000000111111111111111111100000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000111111111111000000000000000000000000000000000000011111
+1111111111110000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000001111111111110000000000000000000000
+0000000000000011111111111111111000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000011111111111100
+0000000000000000000000000000000001111111111111111100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000001111111111110000000000000000000000000000000000111111111111111111
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001111111111100000000000000000000000000000000
+1111111111111111110000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000011111111111100000000000
+0000000000000000000111111111111111111000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000111
+1111111110000000000000000000000000000111111111111111111100000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000011111111111110000000000000000000000000011111111111111
+1111000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000011111111111100000000000000000000
+0000111111111111111111110000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000111111111111
+1000000000000000000000011111111111111111110000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000011111111111110000000000000000000011111111111111111111000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000011111111111110000000000000000000111111111
+1111111111100000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000111111111111100000000
+0000000001111111111111111111100000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+1111111111110000000000000000111111111111111111110000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000011111111111110000000000000011111111111111111110000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000011111111111100000000000001111
+1111111111111110000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000111111111
+1111000000000001111111111111111110000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000011111111111110000000000111111111111111111000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000011111111111110000000011111111111111111
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000111111111111110000
+0011111111111111111100000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0001111111111111000011111111111111111100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000001111111111111100111111111111111110000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000011111111111111111111111111
+1111100000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000011111
+1111111111111111111111110000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001111111111111111111111111111100000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000001111111111111111111111111110000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000011111111111111
+1111111111110000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+0000000111111111111111111111110000000000000000000000000000000000000000
+0000000000000000000000000101000000101000000000000000000000000000000000
+0000000000000000000000000000111111111111111111111000000000000000000000
+0000000000000000000000000000000000000000000011111100111111000000000000
+0000000000000000000000000000000000000000000000000111111111111111111110
+0000000000000000000000000000000000000000000000000000000000000001111111
+1111111110000000000000000000000000000000000000000000000000000000000000
+1111111111111111100000000000000000000000000000000000000000000000000000
+0000000000001111111111111111110000000000000000000000000000000000000000
+0000000000000000000001111111111111111000000000000000000000000000000000
+0000000000000000000000000000000011111111111111111100000000000000000000
+0000000000000000000000000000000000000000011111111111111000000000000000
+0000000000000000000000000000000000000000000000000001111111111111111111
+1000000000000000000000000000000000000000000000000000000000000001111111
+1111000000000000000000000000000000000000000000000000000000000000000000
+0111111111111111111100000000000000000000000000000000000000000000000000
+0000000000000001111101000000000000000000000000000000000000000000000000
+0000000000000000000000111111111111111111000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000011111111
\ No newline at end of file
--- /dev/null
+P2
+# CREATOR: GIMP PNM Filter Version 1.1
+128 128
+255
+0
+2
+4
+6
+8
+10
+12
+13
+16
+17
+19
+21
+22
+24
+26
+28
+30
+32
+33
+35
+36
+38
+40
+41
+42
+44
+45
+46
+48
+49
+51
+52
+54
+55
+56
+57
+58
+59
+60
+61
+63
+63
+65
+65
+66
+67
+67
+68
+69
+70
+71
+71
+72
+72
+72
+73
+74
+74
+74
+74
+74
+74
+75
+74
+75
+75
+74
+75
+74
+74
+74
+74
+73
+73
+73
+72
+72
+71
+70
+69
+69
+69
+67
+66
+66
+65
+64
+63
+62
+61
+60
+59
+58
+57
+56
+55
+54
+52
+51
+49
+48
+46
+45
+43
+42
+41
+39
+38
+36
+34
+33
+31
+29
+27
+26
+25
+23
+21
+19
+18
+16
+14
+12
+10
+8
+6
+4
+2
+2
+4
+6
+8
+10
+12
+13
+16
+18
+20
+21
+23
+24
+27
+29
+31
+32
+34
+35
+37
+38
+40
+41
+43
+45
+46
+48
+49
+50
+52
+54
+55
+56
+57
+59
+60
+61
+61
+63
+64
+66
+66
+67
+68
+69
+69
+70
+71
+72
+73
+73
+74
+74
+75
+76
+76
+76
+77
+76
+77
+77
+78
+77
+77
+77
+77
+77
+77
+78
+77
+77
+77
+76
+76
+75
+75
+74
+74
+74
+73
+72
+71
+71
+70
+68
+68
+67
+67
+65
+64
+63
+62
+60
+59
+59
+57
+56
+54
+54
+52
+51
+49
+47
+46
+45
+43
+41
+41
+38
+37
+35
+34
+32
+30
+29
+27
+25
+23
+21
+19
+18
+15
+14
+12
+10
+8
+6
+4
+4
+6
+8
+10
+12
+14
+16
+18
+20
+21
+23
+25
+27
+28
+30
+32
+34
+36
+37
+39
+40
+43
+44
+46
+47
+49
+50
+51
+53
+54
+56
+58
+58
+60
+60
+62
+63
+65
+66
+67
+68
+68
+70
+71
+72
+73
+73
+74
+74
+75
+76
+76
+78
+77
+78
+78
+79
+80
+79
+80
+80
+80
+80
+80
+80
+80
+80
+80
+80
+80
+79
+79
+78
+78
+78
+78
+77
+77
+76
+75
+75
+74
+73
+72
+71
+70
+70
+69
+67
+67
+65
+64
+63
+62
+61
+60
+59
+57
+56
+54
+53
+52
+51
+49
+47
+46
+44
+42
+41
+39
+38
+35
+34
+32
+31
+29
+27
+25
+23
+22
+19
+18
+16
+14
+12
+10
+8
+6
+6
+8
+10
+12
+14
+16
+18
+19
+22
+23
+26
+27
+29
+31
+33
+35
+37
+38
+39
+41
+43
+45
+47
+48
+49
+51
+53
+54
+56
+57
+58
+60
+61
+63
+64
+65
+66
+67
+69
+69
+70
+71
+72
+73
+74
+75
+76
+77
+77
+78
+79
+79
+80
+80
+81
+81
+81
+82
+82
+83
+82
+83
+83
+83
+83
+83
+83
+83
+83
+83
+82
+82
+82
+82
+80
+80
+80
+79
+79
+78
+77
+76
+75
+75
+74
+73
+73
+72
+71
+69
+68
+67
+66
+65
+64
+62
+61
+59
+59
+57
+55
+54
+52
+51
+50
+48
+47
+45
+43
+42
+40
+38
+36
+35
+33
+31
+29
+27
+25
+24
+22
+20
+18
+16
+14
+12
+10
+7
+8
+9
+12
+14
+16
+18
+19
+22
+24
+25
+27
+30
+31
+34
+35
+37
+38
+41
+42
+44
+45
+47
+49
+50
+52
+53
+55
+56
+58
+59
+61
+62
+63
+65
+66
+67
+69
+70
+71
+72
+73
+73
+75
+76
+77
+77
+78
+80
+80
+81
+81
+82
+82
+84
+83
+84
+84
+84
+85
+86
+85
+86
+86
+86
+86
+85
+86
+86
+86
+86
+85
+85
+84
+84
+84
+83
+83
+82
+81
+80
+80
+80
+78
+78
+77
+76
+75
+74
+73
+72
+71
+69
+68
+68
+66
+65
+64
+62
+61
+59
+58
+57
+55
+53
+52
+50
+49
+47
+46
+44
+42
+40
+39
+36
+35
+33
+31
+29
+28
+26
+23
+22
+20
+18
+16
+14
+12
+10
+10
+12
+14
+16
+18
+20
+22
+23
+26
+28
+30
+31
+33
+36
+37
+38
+41
+42
+45
+45
+48
+50
+51
+53
+55
+56
+58
+59
+60
+62
+63
+64
+66
+68
+69
+69
+71
+73
+74
+74
+76
+77
+77
+78
+79
+80
+82
+82
+82
+84
+85
+85
+85
+86
+86
+87
+87
+88
+88
+89
+88
+88
+89
+88
+89
+89
+88
+89
+88
+88
+88
+88
+87
+87
+86
+86
+86
+85
+85
+84
+82
+82
+82
+81
+80
+79
+78
+77
+75
+74
+73
+72
+71
+70
+68
+67
+66
+64
+64
+62
+60
+59
+57
+56
+54
+53
+51
+49
+48
+46
+44
+42
+40
+39
+37
+35
+34
+31
+30
+28
+26
+24
+21
+20
+18
+16
+14
+12
+12
+14
+16
+18
+20
+22
+24
+26
+28
+30
+32
+34
+36
+38
+39
+41
+43
+45
+47
+48
+50
+52
+53
+55
+57
+58
+59
+61
+63
+64
+65
+67
+69
+70
+71
+73
+74
+74
+76
+77
+78
+79
+80
+81
+83
+83
+84
+85
+85
+86
+87
+87
+89
+89
+90
+89
+90
+90
+91
+91
+91
+92
+92
+92
+92
+92
+91
+92
+92
+91
+91
+91
+90
+89
+89
+89
+88
+87
+87
+86
+86
+85
+84
+83
+82
+81
+80
+79
+78
+77
+76
+75
+74
+72
+71
+69
+68
+67
+66
+64
+63
+61
+59
+58
+56
+55
+53
+52
+50
+49
+46
+45
+43
+41
+39
+37
+36
+33
+32
+30
+28
+26
+24
+22
+20
+18
+15
+14
+14
+15
+18
+20
+22
+24
+26
+28
+30
+31
+33
+36
+37
+40
+42
+43
+45
+47
+48
+50
+52
+54
+56
+57
+59
+61
+62
+64
+65
+67
+68
+70
+71
+72
+74
+75
+76
+77
+78
+80
+81
+82
+83
+84
+85
+86
+87
+87
+88
+89
+89
+90
+90
+91
+92
+92
+93
+93
+94
+94
+94
+95
+94
+94
+94
+94
+94
+94
+94
+94
+94
+94
+93
+92
+92
+92
+90
+91
+90
+89
+88
+87
+86
+86
+85
+84
+83
+82
+81
+80
+78
+77
+76
+75
+73
+72
+70
+69
+68
+67
+65
+63
+62
+61
+59
+57
+56
+54
+52
+50
+49
+47
+45
+43
+41
+40
+38
+35
+34
+32
+30
+28
+26
+24
+22
+20
+17
+16
+15
+17
+20
+22
+24
+26
+28
+30
+32
+34
+35
+38
+40
+41
+44
+45
+48
+49
+51
+53
+54
+56
+58
+60
+62
+63
+65
+66
+68
+69
+70
+72
+73
+74
+76
+77
+79
+80
+81
+82
+84
+84
+85
+87
+87
+89
+89
+90
+91
+91
+92
+93
+94
+94
+94
+95
+96
+96
+96
+97
+97
+97
+97
+97
+98
+98
+98
+97
+97
+96
+96
+96
+95
+95
+95
+95
+94
+93
+92
+92
+91
+90
+89
+88
+88
+87
+86
+84
+83
+82
+81
+80
+79
+77
+76
+74
+73
+72
+71
+69
+68
+66
+64
+63
+61
+59
+58
+57
+54
+53
+51
+49
+48
+45
+43
+42
+39
+37
+35
+34
+31
+30
+28
+26
+24
+21
+20
+18
+17
+20
+22
+23
+26
+28
+30
+31
+34
+36
+38
+40
+42
+44
+46
+48
+49
+51
+53
+55
+57
+59
+60
+62
+63
+65
+66
+68
+70
+72
+73
+74
+76
+78
+78
+79
+81
+83
+83
+84
+86
+87
+89
+89
+90
+91
+92
+92
+94
+95
+95
+96
+96
+97
+98
+98
+99
+98
+99
+100
+100
+99
+100
+100
+100
+100
+100
+100
+100
+99
+99
+98
+99
+98
+98
+97
+96
+96
+95
+95
+93
+93
+92
+91
+90
+89
+89
+87
+86
+85
+84
+83
+81
+79
+78
+77
+75
+74
+73
+71
+70
+69
+67
+65
+64
+62
+60
+59
+57
+55
+53
+51
+49
+47
+46
+44
+41
+40
+38
+36
+34
+32
+30
+27
+26
+24
+21
+19
+19
+21
+24
+26
+28
+30
+32
+34
+35
+38
+40
+41
+44
+45
+48
+50
+52
+54
+56
+56
+59
+61
+62
+64
+66
+67
+69
+71
+73
+74
+76
+77
+78
+79
+81
+83
+84
+85
+86
+87
+89
+90
+91
+92
+93
+93
+95
+96
+97
+97
+97
+98
+99
+100
+100
+100
+101
+101
+102
+103
+102
+102
+103
+103
+102
+103
+102
+102
+103
+102
+102
+102
+101
+100
+100
+99
+99
+98
+98
+98
+97
+96
+95
+94
+92
+91
+91
+89
+89
+88
+87
+85
+84
+83
+81
+79
+78
+77
+75
+74
+73
+71
+69
+68
+66
+64
+62
+61
+59
+57
+55
+54
+51
+49
+48
+46
+43
+42
+40
+38
+36
+33
+32
+29
+27
+26
+23
+21
+21
+23
+25
+27
+30
+32
+33
+35
+38
+40
+42
+44
+45
+48
+50
+52
+53
+55
+57
+59
+61
+63
+64
+67
+68
+69
+71
+73
+75
+76
+77
+79
+81
+82
+83
+85
+87
+88
+89
+90
+91
+92
+93
+95
+95
+96
+97
+98
+99
+99
+101
+101
+102
+102
+103
+104
+104
+105
+105
+105
+105
+105
+106
+106
+106
+106
+106
+106
+105
+105
+105
+104
+104
+103
+103
+103
+102
+101
+101
+100
+99
+98
+97
+96
+96
+95
+93
+93
+91
+90
+88
+87
+86
+85
+83
+82
+81
+79
+77
+76
+74
+73
+71
+69
+68
+66
+65
+63
+61
+59
+57
+56
+54
+51
+50
+48
+46
+43
+42
+40
+38
+35
+34
+32
+30
+27
+25
+23
+22
+25
+27
+29
+32
+34
+35
+38
+40
+42
+44
+45
+48
+50
+52
+53
+56
+57
+60
+61
+64
+65
+67
+69
+70
+72
+74
+76
+77
+79
+80
+81
+83
+84
+86
+87
+88
+90
+91
+92
+94
+95
+96
+97
+98
+99
+100
+101
+102
+102
+103
+104
+105
+105
+106
+106
+107
+108
+108
+108
+108
+108
+108
+108
+109
+109
+108
+108
+108
+108
+107
+107
+106
+106
+106
+105
+104
+104
+103
+103
+102
+101
+100
+99
+98
+97
+96
+95
+94
+92
+91
+90
+89
+87
+86
+84
+83
+82
+80
+79
+76
+75
+74
+71
+70
+69
+67
+65
+63
+61
+59
+57
+56
+54
+51
+49
+48
+46
+44
+42
+40
+38
+35
+34
+31
+29
+27
+25
+24
+26
+29
+31
+33
+35
+37
+39
+42
+44
+46
+48
+49
+51
+54
+56
+57
+60
+61
+63
+65
+67
+69
+71
+73
+74
+76
+77
+79
+81
+82
+84
+85
+87
+89
+90
+91
+92
+94
+95
+96
+97
+99
+99
+100
+102
+103
+104
+104
+106
+106
+107
+108
+108
+109
+109
+110
+110
+110
+111
+111
+111
+111
+111
+111
+112
+111
+111
+111
+111
+111
+110
+110
+109
+109
+108
+108
+107
+106
+105
+105
+103
+102
+101
+100
+99
+99
+97
+96
+95
+94
+92
+91
+90
+88
+87
+86
+84
+82
+80
+79
+77
+75
+74
+72
+71
+69
+67
+65
+63
+61
+60
+58
+56
+54
+52
+50
+48
+46
+44
+42
+39
+37
+35
+34
+31
+28
+27
+26
+28
+31
+33
+35
+37
+39
+41
+44
+45
+47
+50
+52
+54
+56
+58
+59
+62
+64
+66
+67
+69
+71
+73
+75
+76
+78
+80
+82
+83
+85
+86
+88
+90
+91
+92
+94
+95
+97
+97
+98
+100
+101
+103
+103
+104
+105
+106
+107
+108
+109
+109
+110
+111
+111
+112
+112
+113
+113
+114
+114
+114
+114
+114
+115
+114
+114
+114
+113
+113
+113
+113
+112
+111
+111
+110
+110
+109
+108
+108
+107
+106
+106
+104
+103
+102
+102
+99
+99
+97
+97
+95
+94
+92
+91
+89
+87
+87
+84
+83
+81
+80
+78
+77
+75
+73
+71
+69
+67
+66
+63
+62
+60
+58
+56
+54
+51
+50
+48
+46
+44
+42
+39
+37
+35
+33
+31
+28
+28
+31
+32
+35
+36
+39
+41
+43
+46
+47
+49
+52
+54
+56
+57
+60
+62
+63
+65
+68
+69
+71
+73
+75
+77
+79
+80
+82
+84
+85
+87
+88
+90
+91
+93
+95
+96
+97
+99
+100
+101
+102
+104
+105
+106
+107
+108
+109
+109
+111
+111
+113
+113
+113
+114
+114
+115
+116
+116
+116
+117
+117
+117
+117
+117
+117
+117
+117
+117
+117
+116
+115
+115
+115
+115
+113
+113
+112
+111
+111
+110
+109
+108
+107
+106
+104
+103
+102
+102
+100
+98
+97
+96
+95
+93
+92
+90
+89
+87
+85
+84
+82
+80
+79
+77
+75
+73
+72
+69
+67
+66
+64
+61
+60
+57
+56
+53
+52
+49
+48
+46
+43
+41
+38
+37
+35
+33
+30
+30
+31
+34
+36
+39
+40
+42
+45
+47
+49
+52
+54
+56
+57
+60
+62
+64
+65
+68
+69
+71
+74
+76
+77
+79
+81
+83
+84
+86
+87
+89
+90
+93
+94
+96
+97
+99
+100
+101
+103
+104
+106
+106
+108
+109
+110
+111
+112
+112
+114
+114
+115
+115
+117
+117
+117
+117
+119
+118
+119
+119
+119
+120
+119
+120
+119
+120
+120
+119
+119
+119
+119
+118
+118
+117
+116
+116
+115
+114
+114
+113
+111
+111
+110
+109
+108
+106
+105
+104
+103
+101
+100
+99
+97
+96
+94
+92
+91
+89
+87
+86
+84
+83
+80
+79
+77
+76
+73
+71
+70
+67
+65
+64
+62
+59
+57
+55
+54
+51
+49
+47
+45
+43
+41
+38
+37
+34
+31
+32
+34
+35
+38
+40
+43
+45
+46
+49
+52
+53
+55
+57
+59
+62
+64
+66
+68
+70
+72
+73
+75
+77
+79
+81
+83
+85
+86
+88
+90
+91
+93
+95
+97
+98
+99
+101
+102
+103
+105
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+117
+119
+119
+120
+121
+120
+121
+121
+122
+122
+122
+122
+123
+123
+122
+123
+122
+122
+122
+121
+121
+120
+121
+120
+119
+118
+117
+117
+116
+115
+114
+113
+112
+111
+110
+108
+107
+106
+105
+104
+102
+100
+99
+98
+96
+95
+93
+91
+90
+88
+86
+84
+83
+81
+79
+77
+75
+74
+71
+70
+68
+66
+63
+62
+59
+57
+55
+53
+51
+49
+47
+45
+42
+40
+38
+36
+33
+33
+35
+37
+40
+42
+44
+47
+49
+51
+53
+56
+57
+59
+61
+63
+66
+68
+70
+72
+74
+76
+78
+80
+82
+83
+86
+87
+88
+90
+93
+94
+95
+97
+99
+101
+102
+103
+105
+106
+107
+108
+110
+111
+113
+113
+115
+116
+116
+118
+118
+120
+120
+121
+121
+122
+123
+124
+124
+125
+124
+125
+126
+126
+125
+125
+125
+125
+126
+125
+125
+124
+124
+124
+123
+122
+122
+121
+121
+119
+118
+117
+116
+116
+115
+113
+112
+111
+110
+109
+107
+106
+105
+103
+102
+100
+98
+97
+96
+93
+92
+90
+89
+87
+85
+83
+81
+79
+78
+76
+74
+71
+70
+68
+65
+64
+62
+59
+58
+56
+53
+51
+48
+46
+44
+42
+39
+38
+35
+35
+36
+39
+42
+43
+46
+48
+50
+53
+54
+57
+59
+61
+64
+65
+68
+69
+72
+74
+75
+78
+80
+81
+83
+86
+87
+89
+91
+93
+94
+96
+98
+99
+101
+102
+104
+105
+107
+109
+110
+111
+113
+114
+116
+116
+117
+119
+120
+121
+121
+122
+123
+124
+124
+126
+126
+126
+127
+127
+128
+128
+128
+128
+128
+128
+128
+128
+128
+128
+127
+127
+127
+127
+126
+125
+125
+124
+123
+123
+121
+121
+120
+118
+118
+116
+115
+114
+112
+111
+110
+108
+107
+105
+104
+102
+101
+99
+98
+96
+94
+93
+91
+89
+87
+85
+84
+82
+80
+78
+75
+74
+71
+70
+68
+65
+63
+61
+59
+57
+55
+52
+50
+49
+46
+44
+41
+39
+37
+37
+39
+40
+43
+46
+48
+49
+52
+54
+57
+59
+61
+63
+66
+68
+70
+72
+73
+76
+77
+80
+82
+84
+86
+88
+90
+92
+94
+95
+97
+98
+100
+101
+103
+105
+107
+108
+110
+111
+112
+113
+115
+116
+118
+118
+120
+121
+122
+123
+124
+124
+126
+127
+127
+128
+128
+129
+129
+129
+130
+131
+131
+131
+131
+131
+131
+131
+131
+130
+130
+130
+129
+129
+129
+128
+127
+126
+126
+125
+124
+123
+122
+121
+120
+119
+118
+116
+115
+114
+113
+111
+110
+108
+107
+104
+103
+102
+100
+98
+96
+95
+93
+91
+90
+87
+85
+84
+82
+79
+78
+75
+74
+72
+69
+67
+65
+63
+60
+59
+56
+55
+52
+49
+47
+46
+43
+41
+38
+37
+40
+42
+44
+47
+49
+52
+54
+56
+58
+61
+62
+65
+67
+69
+72
+73
+75
+77
+80
+82
+83
+86
+88
+89
+92
+93
+95
+97
+99
+101
+102
+104
+106
+108
+108
+110
+112
+114
+115
+116
+118
+119
+120
+121
+122
+124
+125
+126
+127
+128
+128
+130
+130
+130
+131
+132
+132
+133
+133
+133
+133
+134
+134
+134
+134
+133
+134
+133
+133
+132
+133
+132
+131
+131
+130
+129
+128
+127
+126
+126
+125
+124
+123
+121
+120
+119
+118
+117
+115
+114
+112
+111
+109
+107
+105
+104
+103
+101
+99
+97
+95
+94
+91
+90
+87
+86
+83
+82
+80
+78
+76
+73
+71
+69
+67
+65
+62
+61
+59
+56
+53
+52
+49
+47
+45
+43
+40
+39
+41
+44
+46
+48
+51
+54
+56
+58
+60
+63
+64
+66
+69
+71
+73
+76
+78
+80
+81
+84
+86
+88
+89
+92
+93
+95
+97
+100
+100
+103
+104
+106
+108
+110
+112
+113
+114
+116
+118
+119
+120
+122
+123
+124
+126
+126
+128
+128
+129
+130
+131
+132
+133
+134
+134
+134
+135
+136
+136
+136
+137
+137
+137
+137
+137
+137
+136
+136
+136
+136
+135
+134
+134
+133
+133
+131
+132
+130
+130
+128
+127
+126
+125
+124
+123
+121
+121
+118
+117
+116
+114
+112
+111
+110
+108
+107
+105
+102
+101
+100
+98
+95
+94
+91
+90
+88
+86
+83
+82
+79
+78
+76
+73
+71
+69
+67
+65
+62
+60
+58
+55
+54
+51
+49
+47
+44
+42
+41
+44
+46
+47
+50
+53
+55
+57
+60
+61
+64
+66
+68
+71
+72
+75
+77
+79
+82
+84
+85
+88
+90
+91
+93
+95
+98
+99
+101
+103
+105
+107
+108
+110
+112
+113
+115
+117
+118
+120
+121
+122
+124
+126
+126
+128
+129
+130
+131
+132
+133
+134
+135
+135
+136
+137
+138
+138
+139
+138
+139
+139
+140
+139
+139
+140
+139
+139
+139
+139
+138
+137
+138
+136
+136
+135
+135
+134
+133
+132
+131
+130
+129
+128
+127
+126
+124
+122
+121
+119
+119
+117
+115
+113
+112
+111
+109
+107
+105
+103
+101
+99
+98
+96
+94
+92
+90
+87
+86
+84
+82
+79
+78
+75
+73
+71
+68
+66
+64
+61
+60
+58
+55
+53
+50
+48
+46
+43
+42
+44
+47
+50
+52
+54
+56
+58
+61
+64
+66
+68
+70
+72
+74
+77
+79
+81
+83
+85
+87
+90
+92
+93
+95
+98
+99
+101
+103
+105
+107
+109
+111
+112
+115
+116
+117
+119
+120
+123
+123
+125
+126
+128
+129
+130
+132
+132
+134
+135
+136
+137
+137
+138
+139
+140
+140
+141
+141
+141
+141
+142
+143
+142
+143
+142
+142
+142
+142
+142
+141
+141
+141
+140
+139
+138
+137
+137
+135
+134
+134
+132
+132
+130
+129
+128
+126
+125
+124
+122
+121
+119
+118
+115
+115
+112
+110
+109
+107
+106
+104
+101
+100
+98
+96
+93
+92
+90
+88
+85
+83
+81
+79
+77
+74
+72
+70
+67
+66
+63
+61
+59
+56
+54
+52
+49
+47
+45
+44
+46
+49
+51
+54
+56
+58
+61
+62
+65
+67
+70
+72
+74
+76
+78
+81
+83
+85
+87
+89
+92
+93
+96
+98
+100
+102
+104
+106
+107
+110
+111
+113
+115
+117
+118
+120
+121
+123
+125
+126
+127
+129
+130
+132
+132
+134
+136
+136
+137
+139
+139
+140
+141
+142
+142
+143
+143
+144
+144
+145
+145
+145
+145
+145
+145
+145
+144
+145
+145
+144
+143
+143
+142
+142
+141
+140
+139
+138
+138
+136
+135
+134
+133
+132
+130
+129
+128
+126
+124
+123
+121
+120
+118
+116
+114
+113
+111
+109
+107
+106
+104
+102
+100
+98
+95
+94
+91
+90
+87
+86
+83
+81
+79
+76
+74
+72
+70
+68
+65
+63
+61
+58
+55
+54
+51
+48
+46
+45
+48
+50
+52
+55
+58
+60
+62
+64
+67
+69
+71
+74
+76
+78
+80
+83
+84
+86
+90
+91
+93
+95
+97
+99
+101
+103
+105
+108
+109
+111
+113
+115
+117
+118
+120
+122
+124
+126
+127
+128
+130
+132
+132
+134
+136
+136
+138
+139
+140
+141
+141
+143
+144
+144
+145
+146
+146
+147
+147
+148
+148
+148
+148
+148
+148
+147
+148
+147
+147
+146
+147
+145
+145
+144
+143
+143
+142
+141
+140
+138
+138
+137
+135
+135
+133
+131
+130
+128
+127
+125
+124
+122
+120
+119
+117
+115
+114
+111
+109
+108
+106
+103
+102
+99
+97
+95
+93
+92
+89
+87
+85
+83
+81
+78
+76
+74
+71
+69
+66
+65
+62
+60
+57
+55
+52
+50
+48
+47
+50
+52
+54
+57
+58
+61
+64
+66
+68
+71
+72
+75
+77
+80
+82
+85
+86
+89
+91
+93
+95
+98
+100
+102
+104
+105
+108
+110
+111
+114
+115
+117
+119
+121
+122
+125
+126
+127
+129
+131
+133
+134
+136
+137
+138
+140
+140
+142
+143
+144
+144
+145
+146
+147
+148
+148
+149
+150
+150
+150
+151
+150
+151
+151
+151
+150
+150
+151
+149
+149
+149
+148
+148
+147
+146
+145
+145
+144
+142
+141
+140
+139
+138
+137
+135
+133
+132
+131
+129
+127
+126
+125
+123
+121
+119
+117
+116
+113
+111
+109
+107
+105
+104
+101
+99
+98
+95
+94
+91
+89
+87
+84
+82
+79
+78
+75
+73
+71
+68
+65
+64
+61
+59
+56
+54
+52
+49
+48
+50
+53
+56
+58
+60
+62
+65
+67
+69
+72
+75
+77
+79
+81
+83
+86
+88
+90
+93
+95
+97
+99
+102
+104
+105
+108
+110
+111
+113
+116
+117
+119
+121
+123
+124
+127
+128
+129
+131
+133
+134
+136
+137
+139
+140
+142
+143
+144
+146
+146
+147
+148
+149
+150
+151
+151
+152
+152
+153
+153
+153
+154
+154
+153
+154
+153
+153
+153
+152
+152
+152
+151
+151
+150
+149
+149
+148
+146
+145
+144
+143
+142
+140
+139
+138
+137
+135
+134
+132
+130
+128
+126
+125
+123
+122
+119
+117
+115
+113
+111
+110
+108
+106
+104
+101
+99
+97
+95
+93
+90
+88
+86
+83
+81
+79
+76
+75
+72
+70
+67
+65
+62
+60
+58
+56
+53
+50
+49
+52
+55
+57
+59
+61
+64
+66
+69
+71
+74
+76
+78
+81
+83
+85
+88
+90
+93
+95
+96
+98
+101
+103
+105
+107
+109
+111
+114
+115
+118
+119
+121
+123
+125
+127
+129
+130
+132
+134
+136
+137
+139
+140
+141
+143
+144
+145
+147
+148
+149
+150
+151
+151
+152
+153
+154
+154
+155
+156
+156
+156
+157
+156
+157
+156
+156
+156
+155
+155
+155
+155
+154
+153
+153
+152
+151
+150
+149
+147
+147
+145
+144
+143
+141
+140
+138
+137
+136
+134
+132
+130
+128
+127
+125
+124
+122
+120
+118
+116
+113
+112
+110
+107
+105
+103
+101
+99
+97
+94
+92
+90
+88
+86
+83
+81
+78
+76
+73
+72
+69
+67
+65
+62
+59
+57
+55
+51
+51
+53
+55
+58
+60
+63
+66
+68
+71
+73
+75
+77
+80
+82
+85
+87
+89
+91
+93
+96
+98
+101
+103
+105
+108
+110
+111
+114
+115
+118
+120
+122
+123
+125
+127
+129
+131
+132
+134
+136
+137
+139
+141
+142
+144
+145
+147
+148
+149
+150
+151
+153
+154
+154
+155
+156
+157
+157
+158
+158
+158
+159
+159
+159
+159
+160
+159
+159
+158
+158
+158
+157
+157
+155
+155
+155
+153
+152
+151
+150
+149
+147
+147
+146
+144
+142
+141
+140
+138
+136
+134
+133
+131
+129
+127
+126
+123
+121
+119
+118
+115
+113
+112
+109
+107
+105
+103
+101
+98
+96
+94
+91
+89
+87
+84
+82
+80
+78
+76
+73
+71
+68
+66
+63
+61
+58
+55
+54
+52
+55
+57
+60
+63
+65
+67
+69
+72
+74
+77
+79
+81
+84
+86
+89
+91
+93
+95
+98
+100
+102
+104
+106
+109
+111
+113
+115
+118
+120
+122
+123
+126
+128
+130
+131
+133
+135
+136
+138
+140
+142
+143
+144
+146
+148
+149
+150
+151
+152
+154
+155
+156
+157
+158
+159
+159
+160
+161
+161
+162
+162
+162
+162
+162
+162
+162
+162
+161
+161
+161
+160
+159
+159
+158
+157
+157
+155
+154
+153
+151
+151
+150
+148
+146
+145
+143
+142
+140
+138
+137
+135
+133
+131
+129
+127
+126
+123
+121
+119
+118
+115
+114
+111
+108
+107
+104
+102
+100
+98
+95
+94
+91
+89
+86
+84
+82
+79
+77
+74
+72
+70
+67
+64
+62
+60
+57
+54
+54
+56
+58
+61
+64
+66
+69
+71
+74
+76
+78
+80
+83
+86
+88
+90
+93
+95
+97
+100
+102
+104
+106
+109
+111
+113
+115
+117
+119
+121
+123
+125
+127
+130
+132
+133
+135
+137
+138
+140
+142
+144
+146
+147
+149
+150
+152
+153
+154
+155
+156
+158
+159
+159
+161
+161
+162
+162
+163
+164
+164
+164
+164
+165
+165
+165
+165
+165
+164
+164
+163
+163
+162
+161
+160
+160
+159
+158
+156
+155
+155
+153
+151
+150
+148
+147
+146
+144
+142
+141
+139
+137
+135
+133
+132
+129
+127
+126
+123
+121
+119
+117
+115
+112
+110
+108
+107
+104
+102
+100
+97
+95
+92
+90
+88
+85
+83
+81
+79
+75
+73
+71
+69
+66
+63
+61
+58
+56
+55
+57
+60
+62
+65
+67
+69
+72
+74
+77
+80
+82
+84
+87
+89
+92
+94
+96
+99
+101
+103
+106
+108
+110
+112
+115
+117
+119
+121
+123
+125
+127
+130
+132
+133
+136
+137
+139
+141
+143
+145
+146
+148
+149
+151
+153
+154
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+166
+166
+167
+168
+167
+168
+168
+168
+168
+167
+167
+167
+166
+165
+165
+164
+163
+163
+162
+161
+159
+158
+156
+155
+154
+152
+151
+149
+148
+146
+144
+143
+141
+139
+138
+135
+133
+131
+130
+127
+126
+123
+121
+119
+117
+115
+113
+111
+108
+106
+104
+101
+99
+97
+95
+91
+89
+87
+84
+82
+79
+77
+74
+72
+70
+67
+65
+62
+59
+57
+56
+58
+60
+63
+66
+68
+71
+73
+76
+79
+81
+84
+86
+89
+91
+94
+96
+98
+100
+103
+105
+107
+110
+112
+114
+116
+118
+121
+123
+125
+127
+130
+131
+133
+136
+137
+139
+141
+143
+145
+146
+149
+150
+152
+153
+155
+156
+158
+159
+161
+162
+163
+164
+165
+165
+167
+168
+168
+169
+170
+169
+170
+171
+171
+171
+170
+171
+170
+169
+170
+169
+168
+167
+166
+166
+165
+164
+163
+162
+160
+159
+158
+156
+155
+153
+151
+151
+148
+146
+145
+143
+142
+140
+137
+136
+133
+131
+130
+127
+125
+123
+121
+119
+116
+114
+111
+110
+107
+105
+102
+100
+98
+96
+93
+91
+89
+86
+84
+81
+79
+76
+74
+71
+68
+66
+64
+61
+58
+57
+60
+62
+65
+67
+70
+72
+75
+78
+80
+82
+84
+87
+90
+92
+95
+97
+99
+102
+105
+106
+109
+111
+114
+116
+118
+121
+122
+125
+127
+130
+132
+134
+136
+137
+139
+142
+144
+145
+147
+149
+151
+153
+154
+155
+157
+159
+160
+161
+163
+165
+165
+167
+168
+169
+170
+171
+171
+172
+172
+173
+173
+173
+173
+173
+173
+173
+173
+172
+172
+171
+171
+170
+169
+169
+168
+167
+166
+165
+163
+162
+161
+158
+157
+156
+154
+153
+151
+148
+147
+145
+143
+141
+139
+137
+136
+133
+131
+129
+127
+124
+123
+120
+118
+116
+113
+111
+109
+107
+104
+102
+99
+97
+95
+92
+89
+87
+85
+82
+80
+77
+75
+72
+70
+67
+65
+62
+60
+58
+61
+63
+66
+69
+71
+74
+76
+79
+81
+84
+86
+89
+91
+93
+96
+98
+101
+103
+105
+108
+110
+113
+116
+118
+120
+122
+125
+126
+129
+131
+133
+135
+137
+139
+142
+144
+145
+148
+149
+151
+153
+154
+156
+158
+160
+161
+163
+164
+165
+166
+168
+169
+171
+171
+172
+173
+174
+174
+175
+175
+176
+176
+176
+176
+176
+176
+175
+175
+175
+174
+174
+173
+172
+171
+170
+169
+168
+167
+165
+165
+163
+161
+160
+158
+156
+155
+153
+151
+149
+147
+145
+144
+141
+140
+137
+135
+133
+131
+129
+127
+124
+122
+120
+117
+115
+113
+110
+108
+106
+103
+100
+98
+96
+94
+91
+89
+86
+83
+81
+78
+76
+74
+71
+68
+66
+64
+60
+59
+62
+65
+67
+70
+73
+75
+78
+80
+83
+85
+88
+90
+92
+95
+97
+100
+103
+105
+107
+109
+112
+114
+117
+119
+121
+123
+126
+128
+131
+133
+135
+137
+139
+141
+143
+146
+148
+149
+152
+153
+155
+156
+158
+160
+162
+164
+165
+167
+168
+169
+170
+172
+173
+174
+175
+175
+177
+177
+177
+178
+178
+179
+179
+179
+179
+179
+179
+178
+178
+177
+177
+176
+175
+173
+173
+171
+171
+170
+168
+167
+165
+163
+162
+161
+159
+157
+155
+153
+151
+150
+148
+146
+143
+141
+139
+137
+134
+133
+130
+128
+126
+124
+122
+119
+117
+114
+112
+109
+107
+105
+102
+100
+97
+95
+92
+90
+88
+84
+83
+80
+77
+75
+72
+70
+67
+65
+62
+61
+63
+66
+68
+71
+73
+76
+79
+81
+84
+86
+89
+91
+94
+96
+99
+102
+104
+106
+109
+111
+113
+116
+119
+120
+123
+125
+127
+130
+132
+134
+137
+139
+141
+143
+145
+147
+150
+151
+154
+155
+157
+159
+161
+162
+165
+165
+167
+169
+171
+172
+173
+174
+176
+177
+178
+178
+179
+180
+181
+181
+181
+182
+182
+182
+182
+182
+181
+181
+180
+180
+179
+178
+178
+176
+176
+175
+173
+172
+170
+169
+167
+166
+164
+162
+160
+159
+157
+155
+154
+152
+149
+147
+146
+143
+141
+139
+136
+134
+132
+130
+128
+125
+123
+120
+118
+116
+114
+111
+109
+106
+104
+101
+98
+96
+94
+91
+89
+87
+83
+81
+79
+76
+73
+71
+69
+65
+63
+61
+64
+66
+69
+72
+74
+77
+80
+82
+85
+88
+90
+93
+95
+98
+100
+102
+105
+107
+110
+112
+115
+117
+120
+122
+124
+127
+129
+131
+134
+136
+139
+141
+143
+145
+147
+150
+151
+154
+155
+158
+159
+161
+163
+164
+167
+168
+170
+171
+173
+174
+176
+177
+178
+179
+180
+181
+182
+183
+183
+183
+184
+185
+185
+185
+185
+185
+184
+184
+183
+183
+182
+182
+180
+179
+178
+177
+175
+174
+173
+172
+169
+168
+167
+165
+163
+161
+159
+158
+155
+153
+151
+149
+147
+145
+143
+141
+138
+136
+134
+131
+130
+127
+124
+122
+120
+117
+115
+113
+110
+108
+105
+103
+100
+97
+95
+92
+90
+87
+85
+82
+79
+77
+74
+72
+69
+66
+64
+63
+65
+68
+70
+73
+75
+78
+81
+83
+86
+88
+91
+94
+97
+99
+101
+104
+106
+109
+111
+114
+116
+118
+121
+124
+126
+128
+131
+133
+136
+138
+140
+142
+145
+147
+149
+151
+154
+156
+157
+159
+161
+164
+166
+167
+169
+170
+172
+173
+175
+177
+178
+180
+180
+182
+183
+184
+185
+185
+186
+187
+187
+187
+187
+188
+187
+187
+186
+186
+186
+186
+184
+184
+183
+182
+181
+179
+178
+177
+176
+174
+172
+171
+169
+167
+165
+163
+162
+159
+157
+155
+154
+151
+149
+146
+144
+142
+140
+138
+135
+133
+131
+128
+126
+123
+121
+119
+116
+114
+112
+109
+107
+104
+101
+99
+96
+94
+91
+88
+86
+84
+81
+78
+76
+73
+70
+67
+65
+64
+66
+69
+72
+74
+76
+79
+82
+84
+87
+90
+92
+95
+97
+100
+103
+105
+108
+110
+113
+115
+118
+120
+122
+125
+128
+130
+132
+135
+137
+139
+142
+144
+146
+149
+151
+153
+155
+158
+160
+161
+163
+166
+167
+169
+171
+172
+174
+176
+178
+179
+180
+181
+183
+184
+186
+186
+187
+188
+188
+189
+190
+190
+191
+190
+190
+190
+190
+189
+188
+188
+187
+187
+185
+184
+184
+182
+180
+179
+177
+176
+175
+172
+171
+169
+168
+166
+163
+161
+160
+157
+155
+153
+151
+148
+146
+144
+141
+140
+137
+134
+133
+130
+128
+125
+122
+120
+118
+115
+112
+110
+108
+105
+103
+100
+97
+95
+92
+90
+88
+84
+82
+79
+77
+74
+71
+68
+66
+64
+67
+70
+73
+75
+77
+80
+83
+86
+88
+91
+93
+96
+99
+101
+104
+106
+109
+112
+114
+116
+119
+122
+124
+126
+129
+131
+134
+137
+138
+141
+144
+145
+148
+150
+152
+155
+157
+159
+161
+163
+166
+168
+170
+171
+173
+175
+177
+179
+180
+181
+183
+184
+186
+187
+188
+189
+189
+191
+191
+192
+193
+193
+193
+193
+193
+193
+193
+192
+192
+191
+190
+189
+188
+187
+186
+185
+183
+181
+180
+179
+177
+175
+173
+171
+169
+168
+165
+163
+161
+159
+157
+155
+152
+150
+148
+146
+143
+141
+138
+136
+134
+131
+129
+126
+124
+121
+119
+117
+114
+111
+108
+107
+104
+102
+98
+96
+94
+90
+88
+85
+83
+80
+77
+75
+72
+70
+67
+65
+68
+71
+73
+76
+79
+81
+84
+86
+89
+91
+94
+97
+100
+102
+105
+108
+110
+112
+115
+118
+120
+123
+125
+128
+130
+133
+135
+138
+140
+142
+145
+147
+150
+152
+154
+157
+158
+161
+163
+165
+167
+169
+171
+174
+175
+178
+179
+181
+182
+184
+185
+187
+188
+189
+190
+192
+193
+193
+194
+194
+195
+195
+195
+196
+196
+196
+196
+195
+194
+193
+193
+191
+190
+189
+188
+187
+185
+184
+182
+180
+179
+177
+175
+173
+171
+169
+167
+165
+163
+160
+159
+156
+154
+152
+149
+147
+144
+143
+140
+138
+135
+132
+130
+127
+125
+123
+120
+117
+115
+113
+110
+108
+104
+102
+100
+97
+94
+92
+89
+86
+83
+81
+78
+75
+73
+71
+68
+66
+69
+71
+74
+76
+79
+82
+84
+88
+90
+93
+96
+98
+100
+104
+106
+108
+111
+114
+116
+119
+121
+124
+126
+129
+132
+134
+136
+139
+141
+144
+146
+149
+151
+153
+156
+158
+160
+163
+165
+167
+169
+171
+173
+175
+177
+179
+181
+183
+185
+186
+188
+189
+191
+192
+193
+194
+195
+196
+197
+197
+198
+198
+199
+199
+199
+198
+198
+198
+197
+196
+196
+195
+193
+192
+190
+190
+188
+186
+185
+183
+181
+180
+177
+175
+173
+171
+170
+167
+165
+163
+160
+158
+155
+154
+151
+149
+146
+144
+141
+139
+136
+134
+131
+129
+127
+124
+122
+119
+116
+114
+111
+109
+105
+103
+101
+98
+96
+93
+90
+88
+85
+82
+80
+77
+74
+72
+68
+67
+70
+73
+75
+77
+81
+83
+86
+88
+91
+93
+97
+99
+101
+104
+107
+110
+112
+115
+117
+120
+123
+126
+128
+131
+133
+135
+138
+140
+143
+145
+148
+150
+152
+155
+158
+160
+162
+164
+166
+169
+171
+173
+175
+178
+180
+182
+183
+185
+187
+188
+190
+192
+193
+194
+196
+197
+198
+199
+199
+201
+200
+201
+201
+201
+201
+202
+201
+200
+199
+199
+198
+197
+196
+194
+193
+192
+190
+189
+187
+185
+183
+181
+180
+178
+175
+173
+171
+169
+166
+165
+162
+160
+157
+155
+153
+150
+148
+145
+143
+140
+138
+136
+132
+131
+127
+125
+123
+120
+118
+115
+113
+110
+107
+104
+101
+99
+97
+94
+91
+88
+86
+83
+81
+78
+75
+72
+70
+67
+71
+74
+76
+78
+82
+84
+87
+89
+92
+95
+97
+100
+103
+105
+108
+110
+113
+116
+119
+121
+123
+126
+129
+131
+134
+137
+140
+141
+145
+147
+149
+152
+154
+156
+159
+161
+163
+166
+168
+171
+172
+175
+177
+179
+181
+183
+185
+187
+189
+191
+192
+194
+195
+197
+198
+199
+200
+202
+202
+203
+203
+204
+205
+205
+204
+204
+204
+203
+202
+201
+201
+199
+199
+197
+195
+194
+192
+191
+189
+187
+185
+183
+181
+179
+177
+175
+172
+171
+168
+166
+164
+162
+159
+156
+154
+152
+149
+146
+144
+141
+139
+137
+133
+131
+129
+126
+124
+121
+118
+116
+113
+110
+108
+105
+103
+100
+97
+94
+92
+89
+86
+84
+81
+79
+76
+73
+71
+69
+71
+73
+77
+79
+82
+85
+88
+90
+93
+95
+98
+101
+104
+106
+109
+111
+114
+117
+120
+122
+125
+128
+130
+133
+135
+137
+141
+143
+145
+148
+151
+153
+155
+157
+161
+163
+165
+168
+170
+172
+175
+177
+179
+181
+183
+185
+187
+189
+191
+193
+194
+196
+197
+199
+200
+202
+203
+204
+205
+206
+207
+207
+207
+207
+207
+207
+207
+206
+205
+205
+204
+202
+200
+200
+198
+197
+194
+193
+191
+189
+188
+185
+183
+181
+179
+176
+175
+173
+170
+167
+165
+163
+160
+158
+155
+153
+150
+148
+146
+142
+140
+137
+135
+133
+129
+127
+125
+122
+119
+117
+114
+112
+109
+106
+103
+101
+98
+95
+93
+90
+87
+85
+82
+79
+76
+74
+71
+69
+72
+74
+77
+80
+83
+85
+88
+90
+94
+96
+99
+102
+104
+107
+110
+113
+115
+118
+120
+123
+126
+129
+131
+134
+136
+139
+141
+144
+147
+149
+152
+154
+157
+159
+161
+165
+166
+169
+171
+174
+176
+178
+180
+183
+185
+187
+189
+191
+193
+195
+197
+199
+201
+202
+203
+205
+206
+207
+208
+208
+210
+210
+210
+210
+210
+209
+209
+209
+208
+207
+206
+204
+204
+202
+201
+199
+197
+195
+193
+191
+189
+187
+185
+183
+181
+178
+176
+174
+171
+169
+167
+165
+162
+159
+157
+154
+151
+149
+147
+144
+141
+139
+137
+134
+131
+129
+126
+123
+120
+118
+115
+112
+109
+107
+105
+102
+99
+96
+94
+91
+88
+86
+83
+80
+78
+74
+72
+70
+73
+76
+78
+81
+84
+86
+88
+92
+95
+98
+100
+103
+106
+108
+111
+114
+116
+118
+121
+124
+126
+129
+132
+134
+137
+140
+142
+145
+148
+150
+153
+155
+158
+160
+163
+165
+168
+171
+173
+175
+178
+180
+182
+185
+187
+189
+191
+194
+195
+197
+199
+201
+203
+204
+206
+207
+209
+209
+211
+212
+212
+212
+213
+212
+213
+213
+212
+212
+211
+210
+209
+207
+206
+204
+202
+201
+199
+198
+195
+193
+191
+189
+187
+184
+182
+180
+177
+175
+173
+170
+168
+166
+163
+160
+158
+155
+152
+151
+148
+145
+142
+140
+138
+134
+132
+129
+127
+124
+121
+119
+116
+113
+110
+108
+105
+102
+100
+97
+94
+91
+89
+86
+83
+81
+78
+75
+72
+71
+73
+76
+78
+81
+85
+87
+90
+92
+95
+98
+100
+103
+106
+109
+112
+114
+116
+119
+123
+125
+127
+130
+133
+135
+139
+141
+143
+146
+149
+152
+154
+157
+160
+162
+164
+167
+170
+172
+175
+177
+179
+181
+184
+186
+189
+191
+193
+195
+197
+199
+202
+203
+205
+207
+208
+210
+211
+212
+213
+214
+215
+215
+216
+216
+215
+215
+215
+214
+213
+212
+211
+209
+208
+207
+205
+203
+201
+199
+198
+195
+193
+191
+189
+186
+184
+181
+179
+177
+175
+171
+170
+167
+164
+162
+159
+157
+154
+152
+149
+146
+144
+141
+138
+136
+133
+131
+128
+125
+122
+119
+117
+114
+111
+109
+106
+103
+101
+98
+95
+93
+90
+87
+84
+81
+79
+76
+73
+71
+74
+77
+79
+82
+85
+88
+91
+93
+95
+98
+101
+104
+106
+109
+112
+114
+118
+120
+123
+126
+128
+131
+134
+136
+139
+142
+145
+147
+149
+153
+155
+158
+160
+163
+165
+169
+171
+173
+176
+178
+181
+183
+186
+188
+190
+192
+195
+197
+199
+201
+203
+206
+207
+209
+210
+212
+213
+215
+216
+216
+218
+218
+218
+219
+218
+218
+217
+217
+216
+215
+214
+212
+211
+208
+207
+205
+204
+201
+199
+197
+195
+192
+190
+188
+185
+183
+181
+178
+175
+173
+171
+168
+165
+163
+161
+158
+156
+152
+149
+147
+144
+141
+139
+136
+133
+131
+128
+126
+123
+120
+118
+115
+112
+109
+107
+104
+101
+99
+96
+93
+90
+87
+85
+82
+79
+77
+74
+71
+74
+77
+80
+82
+85
+88
+91
+94
+96
+99
+102
+104
+107
+110
+113
+116
+118
+122
+124
+126
+129
+132
+135
+137
+141
+143
+145
+148
+150
+153
+156
+158
+161
+164
+167
+170
+172
+174
+177
+179
+182
+185
+187
+190
+191
+194
+197
+199
+201
+203
+205
+207
+209
+211
+213
+214
+216
+217
+218
+220
+221
+220
+221
+221
+221
+221
+220
+219
+218
+217
+216
+215
+212
+211
+209
+207
+205
+203
+201
+198
+197
+194
+192
+190
+187
+185
+182
+179
+177
+174
+172
+169
+167
+164
+161
+159
+156
+154
+150
+148
+145
+143
+140
+138
+134
+132
+129
+126
+124
+121
+118
+115
+112
+110
+108
+105
+102
+100
+96
+94
+91
+88
+86
+82
+80
+77
+74
+72
+75
+77
+80
+83
+86
+89
+92
+95
+97
+100
+102
+105
+108
+111
+113
+117
+119
+122
+124
+128
+130
+133
+135
+139
+140
+144
+146
+149
+152
+154
+157
+160
+162
+165
+168
+171
+173
+175
+178
+181
+183
+186
+188
+190
+193
+195
+198
+201
+203
+205
+207
+209
+211
+213
+214
+217
+219
+220
+221
+222
+223
+223
+223
+224
+224
+223
+223
+222
+221
+219
+218
+217
+215
+213
+211
+209
+207
+205
+203
+200
+198
+196
+193
+191
+188
+185
+184
+180
+178
+175
+173
+170
+167
+165
+163
+160
+157
+154
+151
+149
+146
+143
+141
+138
+136
+133
+130
+127
+125
+122
+119
+116
+113
+110
+108
+106
+102
+100
+97
+94
+92
+89
+86
+83
+81
+77
+75
+73
+75
+78
+81
+84
+87
+89
+92
+95
+97
+101
+103
+106
+108
+111
+114
+117
+119
+122
+125
+128
+131
+134
+136
+139
+142
+145
+147
+150
+152
+155
+158
+161
+163
+166
+168
+171
+174
+177
+179
+182
+185
+187
+190
+192
+195
+197
+200
+201
+205
+206
+209
+211
+213
+215
+217
+219
+221
+222
+224
+224
+226
+227
+226
+227
+227
+226
+225
+225
+224
+222
+221
+219
+217
+215
+214
+211
+208
+207
+204
+202
+200
+197
+194
+192
+190
+187
+184
+182
+179
+177
+174
+172
+168
+166
+164
+161
+158
+156
+153
+150
+147
+144
+142
+139
+136
+133
+131
+128
+125
+122
+120
+117
+114
+112
+109
+106
+103
+100
+97
+95
+92
+89
+87
+83
+80
+78
+75
+73
+76
+78
+81
+84
+87
+89
+92
+95
+98
+101
+104
+106
+109
+112
+115
+117
+120
+123
+126
+128
+132
+134
+137
+140
+142
+145
+148
+150
+154
+156
+158
+161
+164
+167
+170
+172
+175
+177
+180
+183
+185
+188
+191
+193
+196
+198
+201
+203
+205
+208
+210
+213
+215
+218
+219
+221
+223
+225
+226
+227
+229
+229
+230
+229
+229
+229
+228
+227
+226
+224
+223
+221
+219
+217
+215
+213
+210
+208
+206
+203
+201
+199
+196
+193
+191
+188
+185
+183
+180
+178
+175
+172
+169
+167
+164
+161
+159
+156
+154
+150
+148
+145
+143
+140
+136
+134
+131
+129
+125
+123
+120
+118
+114
+112
+110
+107
+103
+101
+98
+95
+93
+90
+87
+84
+82
+78
+76
+74
+76
+79
+81
+85
+88
+90
+93
+95
+98
+101
+104
+107
+109
+112
+115
+117
+121
+123
+126
+129
+132
+135
+137
+140
+142
+146
+148
+151
+154
+156
+159
+162
+164
+167
+170
+173
+176
+179
+181
+184
+186
+189
+192
+194
+197
+200
+202
+205
+207
+210
+212
+215
+217
+219
+221
+223
+225
+227
+228
+229
+231
+231
+232
+233
+232
+232
+231
+229
+228
+227
+225
+223
+221
+219
+216
+214
+212
+209
+207
+204
+202
+200
+197
+194
+192
+189
+187
+184
+181
+178
+176
+173
+170
+168
+164
+163
+160
+157
+154
+151
+148
+146
+143
+140
+137
+134
+131
+129
+126
+124
+120
+117
+115
+113
+110
+106
+104
+102
+98
+95
+93
+90
+87
+84
+81
+78
+76
+74
+76
+80
+83
+85
+88
+90
+94
+96
+99
+101
+104
+107
+110
+113
+116
+118
+122
+124
+127
+129
+132
+135
+138
+140
+144
+146
+149
+151
+155
+157
+160
+163
+166
+168
+171
+174
+176
+179
+181
+185
+187
+190
+192
+195
+198
+200
+203
+206
+208
+210
+214
+216
+218
+221
+223
+225
+227
+229
+231
+232
+233
+235
+235
+235
+235
+234
+234
+232
+231
+229
+228
+225
+223
+221
+219
+216
+214
+211
+209
+206
+203
+201
+198
+196
+193
+190
+187
+184
+182
+179
+177
+174
+171
+168
+166
+163
+160
+157
+154
+151
+149
+146
+143
+141
+138
+135
+132
+129
+127
+124
+121
+118
+115
+113
+110
+107
+104
+102
+98
+96
+93
+91
+88
+85
+82
+79
+76
+73
+76
+80
+82
+85
+88
+91
+94
+96
+100
+102
+105
+107
+110
+113
+115
+119
+122
+125
+127
+130
+133
+136
+138
+141
+144
+147
+149
+152
+155
+158
+161
+164
+166
+169
+172
+174
+177
+179
+182
+185
+188
+191
+193
+197
+199
+202
+204
+207
+210
+212
+215
+217
+220
+222
+225
+227
+229
+232
+233
+235
+236
+237
+238
+238
+238
+238
+236
+235
+233
+231
+229
+226
+224
+222
+219
+218
+215
+212
+210
+207
+205
+202
+199
+196
+193
+191
+188
+186
+183
+179
+177
+175
+171
+169
+166
+163
+161
+158
+155
+152
+150
+146
+144
+141
+138
+135
+132
+130
+127
+125
+121
+119
+116
+113
+111
+107
+105
+102
+99
+96
+94
+91
+88
+86
+82
+80
+76
+75
+76
+80
+82
+86
+88
+91
+93
+97
+99
+102
+105
+108
+111
+113
+116
+119
+121
+124
+127
+130
+133
+136
+139
+141
+144
+147
+150
+153
+155
+159
+161
+163
+166
+169
+172
+174
+178
+180
+183
+186
+188
+192
+194
+196
+200
+202
+205
+208
+210
+213
+215
+218
+221
+224
+226
+229
+231
+233
+235
+237
+239
+240
+240
+241
+241
+240
+239
+237
+235
+233
+231
+228
+226
+223
+221
+218
+216
+213
+210
+208
+205
+202
+200
+197
+194
+191
+189
+186
+183
+181
+177
+175
+172
+169
+167
+163
+161
+158
+155
+152
+149
+147
+144
+141
+139
+136
+133
+130
+127
+125
+122
+119
+116
+113
+110
+108
+105
+102
+100
+97
+94
+91
+88
+85
+83
+80
+77
+75
+77
+80
+83
+85
+88
+91
+94
+97
+99
+102
+105
+108
+111
+114
+116
+120
+122
+125
+128
+130
+133
+136
+139
+142
+145
+148
+150
+153
+156
+158
+161
+164
+167
+169
+173
+176
+178
+180
+184
+186
+189
+192
+195
+197
+200
+203
+206
+209
+212
+214
+217
+220
+222
+225
+227
+230
+232
+234
+237
+240
+241
+243
+243
+244
+243
+242
+241
+239
+237
+235
+232
+230
+227
+224
+222
+219
+216
+214
+211
+208
+206
+203
+200
+197
+194
+192
+190
+186
+183
+181
+178
+175
+173
+170
+166
+164
+161
+158
+156
+153
+150
+147
+145
+141
+139
+136
+134
+131
+128
+125
+122
+119
+117
+114
+111
+108
+105
+102
+99
+97
+94
+91
+88
+85
+83
+80
+77
+74
+77
+80
+83
+86
+88
+92
+94
+97
+100
+102
+105
+108
+111
+113
+117
+119
+123
+125
+128
+131
+133
+137
+139
+141
+145
+148
+151
+153
+156
+159
+161
+164
+168
+170
+173
+176
+178
+181
+184
+187
+189
+193
+196
+198
+200
+204
+206
+209
+212
+214
+218
+220
+223
+226
+229
+231
+234
+236
+239
+241
+243
+245
+246
+247
+246
+245
+243
+241
+239
+236
+234
+231
+228
+226
+223
+220
+217
+214
+212
+209
+206
+204
+201
+198
+196
+193
+190
+187
+184
+181
+179
+176
+173
+170
+168
+164
+162
+159
+156
+153
+151
+148
+145
+142
+139
+137
+133
+130
+128
+125
+122
+119
+117
+114
+111
+108
+105
+103
+100
+97
+94
+92
+88
+86
+83
+80
+77
+75
+77
+80
+83
+86
+88
+92
+94
+97
+100
+103
+106
+109
+111
+114
+117
+119
+122
+125
+128
+131
+134
+136
+140
+142
+145
+148
+151
+153
+156
+159
+162
+165
+167
+170
+173
+176
+178
+182
+185
+187
+190
+193
+196
+199
+202
+204
+207
+209
+213
+215
+218
+220
+223
+227
+229
+232
+235
+238
+240
+242
+245
+247
+249
+250
+249
+247
+245
+242
+240
+237
+234
+232
+229
+226
+224
+221
+218
+216
+213
+210
+206
+204
+201
+198
+196
+193
+190
+187
+185
+182
+178
+175
+173
+170
+168
+164
+162
+159
+156
+153
+150
+148
+145
+142
+139
+136
+133
+131
+128
+126
+122
+120
+117
+114
+111
+109
+106
+103
+100
+97
+94
+91
+89
+85
+83
+80
+77
+75
+77
+80
+83
+86
+89
+91
+94
+97
+100
+102
+106
+109
+112
+115
+117
+120
+123
+125
+128
+131
+134
+137
+139
+142
+145
+147
+151
+154
+156
+159
+162
+164
+167
+171
+174
+176
+179
+181
+185
+187
+190
+193
+196
+198
+202
+204
+207
+210
+213
+216
+218
+221
+224
+227
+230
+232
+235
+238
+241
+243
+246
+248
+251
+252
+251
+249
+246
+244
+241
+238
+235
+232
+229
+226
+224
+221
+219
+216
+213
+209
+207
+204
+202
+199
+195
+193
+190
+187
+185
+182
+179
+176
+173
+171
+168
+165
+162
+159
+156
+154
+151
+148
+146
+142
+139
+137
+134
+131
+129
+125
+123
+120
+117
+114
+112
+109
+105
+102
+100
+98
+95
+92
+89
+86
+84
+80
+77
+75
+77
+81
+83
+86
+88
+92
+94
+98
+100
+103
+105
+108
+111
+114
+117
+120
+123
+126
+128
+131
+134
+136
+139
+143
+145
+148
+151
+154
+157
+159
+163
+164
+168
+170
+174
+176
+179
+181
+185
+187
+190
+193
+196
+199
+201
+204
+207
+210
+213
+215
+219
+221
+224
+226
+230
+233
+235
+238
+241
+244
+247
+250
+252
+255
+252
+250
+246
+244
+241
+238
+236
+233
+230
+227
+224
+222
+218
+216
+213
+210
+207
+204
+202
+199
+196
+193
+190
+188
+185
+182
+179
+176
+173
+171
+167
+164
+162
+159
+156
+154
+150
+148
+145
+142
+139
+136
+133
+131
+128
+125
+122
+120
+117
+115
+111
+108
+106
+103
+100
+97
+94
+92
+89
+86
+83
+81
+78
+74
+78
+80
+83
+86
+88
+92
+95
+97
+100
+103
+106
+109
+111
+114
+117
+119
+123
+125
+128
+131
+134
+136
+140
+142
+145
+148
+151
+153
+157
+159
+162
+165
+168
+170
+173
+177
+179
+182
+185
+187
+190
+192
+196
+199
+201
+204
+207
+210
+213
+216
+218
+221
+224
+227
+230
+232
+235
+238
+241
+243
+246
+249
+251
+253
+251
+249
+246
+243
+241
+238
+235
+233
+230
+227
+224
+221
+218
+216
+213
+210
+207
+204
+201
+198
+196
+192
+191
+187
+184
+182
+179
+176
+173
+170
+168
+165
+162
+159
+156
+153
+151
+148
+145
+142
+140
+137
+133
+131
+129
+125
+122
+120
+117
+114
+111
+108
+106
+103
+100
+98
+95
+92
+89
+86
+83
+80
+78
+74
+78
+80
+83
+86
+89
+91
+94
+97
+100
+103
+105
+109
+111
+114
+116
+120
+123
+126
+128
+131
+134
+136
+139
+142
+145
+148
+150
+153
+156
+159
+162
+165
+167
+170
+173
+176
+179
+182
+184
+188
+190
+193
+196
+198
+201
+204
+207
+209
+212
+215
+218
+221
+223
+226
+229
+232
+235
+237
+239
+242
+244
+247
+249
+249
+249
+247
+245
+243
+239
+238
+235
+232
+229
+227
+224
+220
+218
+215
+213
+210
+206
+204
+201
+199
+196
+193
+189
+188
+184
+181
+179
+176
+173
+170
+168
+165
+162
+159
+156
+153
+150
+147
+145
+143
+139
+137
+133
+131
+128
+126
+122
+120
+117
+114
+112
+109
+105
+103
+100
+97
+94
+92
+89
+86
+83
+81
+77
+74
+77
+81
+83
+86
+89
+92
+95
+97
+100
+103
+105
+108
+111
+114
+116
+120
+122
+125
+128
+131
+134
+136
+140
+142
+145
+147
+151
+154
+156
+159
+162
+165
+167
+170
+172
+175
+178
+181
+184
+187
+190
+193
+195
+198
+201
+203
+206
+209
+212
+215
+217
+220
+223
+226
+229
+231
+234
+236
+239
+241
+243
+245
+246
+246
+246
+245
+243
+241
+238
+236
+234
+231
+228
+226
+222
+220
+217
+215
+212
+209
+207
+203
+201
+198
+195
+193
+190
+187
+184
+181
+178
+176
+173
+170
+167
+164
+161
+159
+156
+154
+150
+148
+145
+142
+139
+136
+134
+131
+128
+125
+122
+120
+117
+114
+111
+108
+105
+103
+100
+97
+95
+91
+89
+86
+83
+80
+77
+75
+77
+80
+83
+86
+88
+92
+94
+97
+99
+103
+106
+109
+111
+113
+117
+120
+122
+125
+128
+131
+133
+137
+139
+142
+145
+147
+151
+153
+155
+158
+161
+164
+167
+170
+173
+175
+178
+180
+183
+187
+189
+192
+194
+197
+200
+203
+205
+209
+212
+214
+217
+219
+222
+225
+227
+229
+232
+234
+237
+239
+241
+242
+243
+244
+243
+242
+241
+240
+237
+235
+233
+229
+227
+225
+222
+219
+217
+213
+211
+208
+206
+203
+200
+198
+195
+192
+189
+186
+184
+181
+178
+175
+172
+170
+167
+164
+161
+158
+156
+153
+150
+147
+144
+142
+139
+136
+133
+131
+128
+125
+122
+119
+117
+114
+111
+108
+106
+103
+100
+97
+94
+91
+89
+86
+83
+80
+77
+75
+77
+79
+83
+85
+88
+91
+94
+97
+100
+102
+105
+108
+111
+114
+116
+119
+122
+124
+127
+130
+133
+136
+139
+141
+145
+147
+150
+152
+155
+159
+161
+164
+166
+170
+172
+175
+177
+181
+184
+186
+189
+191
+195
+197
+199
+202
+205
+208
+211
+213
+216
+219
+221
+224
+226
+228
+231
+233
+235
+237
+239
+239
+241
+241
+241
+239
+238
+237
+235
+233
+231
+228
+226
+223
+221
+219
+216
+213
+210
+207
+205
+202
+200
+197
+195
+192
+189
+186
+183
+181
+177
+175
+172
+169
+166
+164
+161
+159
+155
+152
+149
+147
+144
+141
+139
+136
+133
+130
+128
+125
+122
+119
+116
+114
+110
+108
+105
+102
+100
+97
+94
+91
+89
+86
+83
+80
+77
+74
+77
+79
+82
+85
+88
+90
+93
+96
+99
+102
+105
+107
+110
+113
+116
+119
+121
+125
+127
+130
+133
+135
+138
+141
+143
+147
+149
+152
+155
+158
+161
+163
+166
+169
+172
+174
+177
+180
+182
+185
+188
+191
+194
+196
+199
+201
+204
+207
+209
+212
+215
+217
+220
+222
+224
+227
+229
+231
+233
+235
+236
+237
+238
+238
+237
+238
+236
+235
+233
+231
+229
+227
+224
+223
+219
+218
+214
+212
+209
+207
+204
+201
+199
+197
+193
+190
+188
+185
+183
+180
+177
+174
+171
+169
+166
+163
+160
+157
+155
+152
+149
+147
+144
+141
+139
+135
+132
+130
+127
+124
+122
+118
+116
+113
+111
+108
+105
+102
+99
+96
+94
+91
+88
+86
+82
+80
+77
+74
+77
+79
+82
+85
+87
+90
+93
+96
+99
+102
+104
+107
+110
+113
+115
+118
+121
+123
+127
+130
+132
+135
+138
+141
+144
+147
+149
+152
+155
+157
+160
+162
+166
+168
+171
+174
+176
+179
+182
+185
+187
+190
+193
+196
+198
+200
+203
+206
+208
+211
+213
+216
+219
+220
+223
+225
+227
+229
+231
+233
+234
+235
+235
+235
+235
+234
+233
+232
+231
+229
+227
+225
+223
+220
+218
+215
+213
+211
+208
+206
+203
+201
+198
+195
+192
+190
+187
+184
+182
+180
+176
+174
+171
+168
+165
+162
+160
+157
+155
+152
+149
+146
+143
+141
+138
+135
+132
+130
+126
+124
+121
+118
+116
+113
+110
+107
+104
+102
+99
+96
+93
+91
+88
+85
+82
+79
+76
+73
+77
+79
+81
+85
+88
+90
+93
+96
+98
+101
+104
+106
+109
+112
+115
+118
+120
+124
+126
+129
+132
+134
+137
+140
+143
+146
+149
+151
+154
+157
+159
+162
+165
+167
+170
+173
+176
+178
+181
+184
+187
+189
+191
+194
+197
+200
+202
+204
+207
+210
+212
+214
+217
+218
+221
+223
+225
+227
+228
+229
+231
+232
+233
+233
+233
+232
+230
+230
+229
+227
+225
+223
+221
+219
+217
+215
+212
+209
+208
+205
+202
+200
+197
+195
+191
+189
+186
+184
+181
+179
+175
+173
+170
+167
+165
+162
+159
+157
+153
+151
+148
+146
+143
+140
+137
+135
+132
+129
+127
+124
+120
+118
+115
+112
+109
+106
+104
+101
+99
+95
+93
+90
+87
+84
+82
+79
+76
+73
+76
+79
+81
+84
+86
+89
+93
+95
+98
+101
+104
+106
+109
+112
+114
+117
+121
+123
+126
+129
+131
+134
+136
+139
+142
+145
+147
+151
+153
+156
+158
+162
+164
+167
+170
+172
+175
+177
+180
+183
+185
+188
+191
+193
+196
+199
+201
+203
+205
+208
+210
+213
+215
+217
+219
+221
+222
+224
+226
+227
+228
+229
+230
+230
+229
+229
+228
+227
+226
+225
+223
+221
+219
+217
+215
+213
+210
+208
+206
+204
+201
+198
+196
+193
+191
+188
+186
+182
+180
+178
+174
+172
+169
+166
+164
+162
+159
+156
+153
+150
+148
+145
+142
+139
+137
+134
+131
+128
+126
+123
+121
+118
+115
+112
+109
+106
+103
+101
+98
+95
+92
+90
+87
+84
+81
+78
+75
+72
+76
+78
+81
+83
+87
+89
+92
+95
+97
+101
+103
+106
+109
+112
+115
+117
+119
+123
+126
+128
+130
+133
+136
+139
+142
+144
+147
+149
+153
+155
+158
+160
+163
+166
+169
+171
+173
+177
+179
+181
+184
+187
+189
+192
+194
+197
+199
+202
+204
+207
+209
+211
+214
+215
+217
+219
+221
+223
+223
+224
+226
+227
+227
+226
+226
+227
+226
+225
+223
+223
+221
+218
+217
+215
+214
+211
+209
+207
+204
+202
+200
+197
+195
+192
+190
+187
+184
+182
+179
+176
+173
+171
+168
+166
+163
+161
+158
+156
+153
+150
+147
+144
+142
+139
+136
+133
+131
+128
+125
+122
+119
+117
+114
+111
+109
+105
+103
+100
+97
+95
+92
+89
+86
+83
+80
+78
+75
+72
+75
+77
+80
+83
+86
+89
+91
+94
+97
+99
+102
+105
+108
+111
+114
+116
+119
+121
+124
+127
+130
+132
+136
+138
+141
+143
+146
+149
+151
+154
+157
+159
+163
+165
+168
+170
+173
+176
+178
+181
+184
+186
+188
+191
+193
+196
+198
+200
+203
+205
+207
+209
+211
+213
+215
+216
+218
+220
+221
+222
+223
+223
+224
+224
+224
+223
+223
+222
+220
+220
+219
+217
+215
+213
+211
+209
+207
+205
+202
+200
+198
+196
+193
+191
+188
+186
+183
+181
+178
+175
+173
+170
+168
+165
+162
+160
+157
+155
+152
+149
+146
+143
+140
+138
+135
+133
+130
+127
+124
+121
+119
+116
+113
+111
+108
+105
+102
+99
+97
+95
+92
+89
+86
+83
+80
+77
+75
+72
+74
+77
+80
+82
+85
+88
+91
+94
+97
+99
+102
+105
+107
+111
+112
+116
+119
+122
+124
+126
+130
+132
+134
+137
+140
+143
+146
+148
+151
+153
+156
+159
+161
+164
+167
+169
+172
+174
+176
+179
+182
+185
+186
+190
+192
+194
+196
+199
+200
+203
+206
+208
+209
+211
+213
+214
+216
+217
+219
+220
+220
+221
+221
+221
+221
+221
+220
+220
+218
+217
+215
+215
+212
+211
+209
+207
+205
+203
+201
+199
+197
+194
+192
+190
+186
+185
+182
+179
+177
+175
+172
+169
+167
+164
+161
+159
+156
+153
+151
+148
+145
+143
+140
+137
+135
+132
+129
+127
+124
+121
+118
+115
+113
+110
+107
+104
+102
+99
+96
+93
+91
+88
+86
+83
+79
+77
+74
+71
+74
+77
+79
+82
+85
+88
+91
+93
+95
+99
+102
+104
+106
+109
+112
+115
+117
+120
+123
+125
+129
+132
+134
+137
+139
+142
+145
+147
+150
+152
+155
+158
+161
+163
+165
+168
+171
+173
+175
+178
+180
+183
+186
+188
+190
+193
+194
+197
+199
+201
+203
+206
+207
+209
+210
+212
+213
+214
+215
+216
+217
+218
+218
+218
+218
+218
+217
+217
+216
+215
+214
+212
+211
+209
+207
+205
+203
+202
+199
+197
+195
+193
+190
+188
+185
+183
+180
+178
+176
+173
+170
+168
+166
+163
+160
+157
+155
+153
+150
+147
+145
+142
+139
+136
+134
+131
+128
+126
+123
+120
+117
+115
+112
+109
+107
+104
+101
+99
+96
+93
+90
+88
+85
+82
+80
+76
+74
+71
+73
+76
+79
+82
+84
+87
+90
+92
+95
+98
+100
+104
+106
+109
+112
+114
+116
+120
+122
+125
+128
+130
+133
+136
+138
+141
+143
+147
+149
+151
+154
+156
+159
+162
+165
+167
+169
+172
+174
+177
+179
+181
+184
+186
+188
+191
+193
+195
+197
+199
+201
+203
+205
+207
+208
+209
+211
+212
+214
+214
+214
+215
+216
+216
+215
+215
+215
+214
+213
+212
+211
+210
+208
+207
+205
+203
+201
+199
+198
+195
+193
+190
+188
+186
+184
+182
+180
+177
+174
+171
+169
+167
+164
+162
+159
+157
+154
+151
+149
+146
+144
+141
+139
+135
+133
+131
+128
+125
+122
+120
+117
+114
+112
+108
+106
+103
+101
+98
+96
+92
+90
+87
+84
+81
+79
+76
+73
+70
+72
+75
+78
+81
+83
+86
+89
+91
+94
+97
+100
+102
+105
+108
+110
+113
+116
+119
+121
+124
+127
+129
+132
+134
+137
+140
+142
+145
+148
+150
+153
+155
+158
+160
+163
+165
+168
+171
+173
+176
+178
+180
+182
+185
+187
+189
+191
+193
+195
+197
+199
+201
+203
+205
+206
+207
+208
+210
+210
+211
+212
+212
+213
+212
+213
+212
+212
+212
+211
+209
+208
+207
+206
+204
+203
+200
+199
+197
+195
+193
+191
+189
+187
+185
+182
+180
+178
+176
+173
+170
+168
+165
+163
+160
+158
+155
+153
+151
+148
+145
+142
+139
+138
+135
+132
+130
+126
+124
+121
+118
+116
+114
+111
+108
+106
+103
+100
+97
+94
+92
+89
+86
+83
+81
+78
+75
+72
+69
+72
+75
+77
+80
+83
+86
+88
+91
+93
+96
+99
+101
+104
+107
+110
+112
+115
+117
+120
+123
+126
+128
+131
+133
+136
+139
+142
+144
+147
+149
+152
+154
+157
+159
+161
+164
+166
+169
+171
+174
+176
+179
+180
+183
+185
+187
+189
+191
+193
+195
+197
+199
+200
+202
+203
+205
+206
+207
+208
+209
+209
+210
+210
+210
+210
+210
+209
+209
+208
+207
+206
+204
+203
+202
+200
+199
+197
+195
+193
+191
+189
+188
+185
+183
+180
+178
+176
+173
+172
+169
+167
+164
+161
+160
+156
+154
+152
+149
+147
+144
+142
+139
+136
+133
+131
+128
+125
+123
+120
+118
+115
+112
+110
+107
+104
+102
+99
+97
+94
+91
+89
+85
+83
+80
+78
+74
+72
+68
+71
+74
+76
+79
+82
+85
+88
+90
+93
+95
+98
+101
+104
+107
+109
+112
+114
+117
+119
+122
+125
+127
+130
+133
+136
+138
+140
+142
+146
+147
+151
+152
+156
+158
+160
+163
+165
+168
+170
+172
+174
+177
+179
+181
+183
+185
+187
+189
+191
+193
+195
+196
+198
+200
+200
+202
+204
+204
+205
+205
+206
+206
+207
+207
+207
+207
+206
+206
+205
+204
+203
+202
+201
+199
+198
+197
+195
+193
+191
+190
+187
+185
+183
+181
+179
+177
+175
+173
+169
+168
+166
+163
+160
+158
+156
+153
+150
+148
+146
+143
+140
+138
+135
+133
+130
+128
+125
+122
+119
+117
+114
+112
+109
+106
+104
+101
+99
+95
+93
+91
+87
+85
+82
+79
+77
+73
+71
+68
+70
+73
+76
+79
+81
+84
+87
+89
+92
+95
+97
+100
+103
+105
+108
+111
+113
+116
+118
+121
+124
+126
+129
+131
+134
+137
+139
+141
+144
+147
+149
+151
+154
+157
+159
+161
+163
+166
+168
+170
+172
+175
+177
+180
+181
+183
+185
+187
+189
+191
+192
+194
+196
+197
+198
+200
+201
+202
+203
+203
+203
+204
+204
+204
+205
+204
+204
+203
+202
+202
+201
+200
+198
+197
+195
+194
+193
+191
+189
+187
+185
+184
+181
+179
+177
+175
+173
+170
+168
+166
+164
+162
+158
+157
+154
+152
+149
+146
+144
+142
+139
+136
+134
+132
+129
+126
+123
+121
+118
+116
+113
+110
+108
+105
+102
+100
+97
+95
+92
+89
+87
+84
+81
+78
+76
+73
+70
+67
+70
+72
+75
+77
+81
+83
+86
+89
+91
+94
+97
+99
+102
+104
+107
+110
+113
+115
+118
+120
+123
+125
+128
+131
+132
+135
+138
+141
+142
+145
+147
+150
+152
+155
+158
+160
+162
+164
+167
+168
+171
+173
+175
+177
+179
+181
+184
+185
+187
+188
+190
+192
+193
+195
+196
+196
+198
+199
+200
+200
+201
+201
+201
+202
+202
+201
+201
+201
+200
+199
+198
+197
+196
+194
+193
+192
+190
+189
+187
+185
+183
+182
+180
+177
+176
+173
+171
+169
+167
+165
+162
+160
+157
+155
+153
+150
+148
+146
+143
+141
+138
+136
+133
+131
+128
+126
+123
+120
+117
+115
+112
+110
+107
+105
+102
+99
+97
+94
+91
+89
+86
+83
+80
+77
+75
+72
+69
+66
+69
+72
+74
+77
+79
+82
+85
+87
+90
+93
+96
+98
+100
+104
+106
+108
+111
+113
+116
+119
+121
+124
+126
+129
+132
+134
+136
+139
+141
+144
+146
+149
+151
+154
+155
+158
+160
+163
+165
+167
+169
+172
+174
+175
+177
+179
+181
+183
+185
+186
+188
+189
+190
+192
+194
+194
+196
+196
+197
+197
+198
+198
+198
+199
+199
+198
+198
+198
+197
+196
+196
+194
+194
+192
+190
+189
+187
+186
+185
+183
+181
+180
+177
+175
+173
+172
+169
+167
+164
+162
+160
+158
+155
+154
+151
+149
+146
+143
+141
+139
+136
+134
+132
+129
+127
+124
+122
+119
+117
+114
+111
+109
+106
+103
+100
+98
+95
+92
+90
+88
+85
+82
+79
+77
+74
+71
+68
+65
+68
+71
+73
+76
+78
+82
+84
+86
+90
+92
+94
+97
+99
+102
+105
+107
+110
+113
+115
+117
+120
+122
+126
+128
+130
+132
+136
+137
+140
+143
+145
+147
+149
+152
+154
+156
+159
+161
+163
+166
+168
+169
+172
+174
+175
+177
+179
+180
+182
+184
+186
+187
+188
+190
+190
+191
+193
+193
+194
+195
+196
+195
+196
+196
+195
+196
+195
+194
+194
+194
+193
+192
+191
+189
+188
+186
+186
+184
+182
+181
+179
+177
+175
+173
+171
+170
+167
+165
+163
+161
+159
+157
+154
+152
+150
+147
+144
+143
+140
+137
+135
+133
+130
+128
+125
+123
+120
+117
+115
+112
+110
+108
+105
+103
+99
+97
+94
+91
+89
+87
+84
+81
+78
+76
+73
+71
+68
+64
+67
+70
+72
+75
+77
+81
+83
+85
+88
+91
+93
+96
+99
+101
+104
+107
+109
+112
+114
+117
+119
+121
+124
+126
+129
+132
+133
+136
+138
+141
+143
+145
+148
+150
+152
+155
+157
+159
+161
+163
+165
+167
+169
+171
+173
+175
+177
+179
+180
+182
+183
+185
+186
+187
+188
+189
+190
+191
+191
+192
+193
+193
+193
+193
+193
+192
+192
+192
+192
+191
+190
+189
+188
+187
+186
+184
+183
+181
+180
+178
+176
+175
+173
+172
+170
+167
+166
+163
+161
+159
+157
+154
+153
+151
+148
+146
+143
+141
+139
+136
+133
+132
+128
+127
+124
+121
+119
+116
+114
+112
+109
+106
+103
+101
+98
+96
+94
+91
+88
+86
+83
+80
+77
+75
+72
+70
+67
+63
+66
+69
+71
+74
+76
+79
+82
+85
+87
+90
+92
+95
+98
+100
+102
+105
+107
+110
+113
+115
+118
+120
+122
+125
+128
+130
+132
+135
+137
+140
+141
+144
+146
+149
+151
+153
+155
+157
+159
+161
+163
+166
+168
+170
+171
+172
+174
+176
+178
+179
+180
+182
+183
+185
+185
+186
+187
+188
+189
+190
+190
+189
+190
+190
+190
+190
+189
+189
+189
+188
+187
+186
+186
+184
+183
+182
+181
+179
+178
+176
+175
+172
+170
+169
+167
+165
+163
+161
+159
+157
+155
+153
+151
+149
+146
+144
+142
+139
+137
+135
+132
+130
+128
+125
+122
+121
+118
+115
+112
+110
+107
+105
+102
+100
+98
+94
+93
+89
+87
+84
+82
+80
+77
+74
+72
+69
+66
+62
+65
+67
+71
+73
+76
+78
+80
+83
+86
+88
+91
+93
+96
+99
+101
+104
+106
+109
+111
+114
+117
+118
+121
+124
+126
+129
+130
+133
+135
+137
+140
+142
+144
+147
+149
+151
+153
+155
+157
+159
+161
+164
+166
+167
+169
+170
+172
+174
+175
+176
+178
+180
+181
+182
+183
+184
+185
+185
+186
+186
+186
+187
+187
+187
+188
+187
+187
+186
+186
+185
+185
+184
+183
+181
+180
+180
+178
+176
+176
+174
+172
+170
+169
+167
+165
+163
+161
+160
+158
+156
+154
+152
+149
+147
+145
+142
+140
+138
+136
+133
+131
+128
+126
+124
+121
+119
+116
+114
+111
+109
+106
+104
+102
+98
+96
+94
+91
+89
+86
+84
+81
+78
+75
+73
+70
+68
+65
+61
+64
+67
+69
+72
+75
+77
+80
+83
+85
+88
+90
+92
+95
+97
+100
+103
+105
+108
+110
+112
+115
+118
+120
+122
+125
+127
+129
+132
+134
+136
+139
+140
+142
+145
+147
+149
+151
+153
+156
+157
+159
+161
+163
+164
+166
+168
+170
+172
+173
+174
+175
+176
+178
+179
+180
+181
+182
+182
+184
+183
+184
+184
+185
+185
+184
+184
+184
+184
+184
+182
+182
+182
+180
+179
+178
+177
+176
+174
+173
+171
+170
+168
+167
+165
+163
+161
+159
+157
+156
+153
+152
+149
+147
+145
+142
+140
+138
+136
+134
+132
+129
+127
+124
+122
+120
+117
+115
+113
+110
+108
+105
+103
+100
+98
+95
+92
+90
+88
+85
+82
+80
+77
+75
+72
+69
+66
+64
+61
+63
+66
+69
+71
+74
+76
+79
+81
+83
+86
+89
+91
+93
+96
+99
+101
+104
+106
+108
+111
+114
+116
+119
+121
+123
+125
+128
+130
+132
+135
+137
+139
+141
+144
+145
+147
+149
+151
+153
+156
+157
+159
+161
+163
+164
+166
+168
+169
+171
+171
+173
+175
+175
+177
+178
+179
+179
+179
+181
+181
+181
+181
+182
+182
+182
+181
+181
+181
+180
+180
+179
+179
+177
+177
+175
+174
+173
+171
+170
+169
+167
+165
+165
+163
+161
+159
+157
+155
+154
+151
+150
+147
+145
+143
+141
+139
+137
+134
+132
+130
+127
+125
+123
+121
+118
+116
+114
+111
+108
+106
+104
+101
+99
+96
+93
+91
+89
+87
+84
+81
+79
+76
+73
+71
+69
+65
+63
+59
+62
+65
+67
+70
+73
+74
+77
+80
+82
+85
+87
+90
+93
+95
+98
+99
+103
+105
+107
+110
+112
+114
+117
+119
+121
+123
+125
+128
+130
+132
+135
+137
+139
+141
+143
+146
+148
+149
+151
+154
+155
+157
+158
+160
+162
+163
+165
+166
+168
+169
+171
+172
+173
+174
+175
+175
+176
+177
+178
+178
+179
+179
+179
+179
+179
+179
+178
+178
+178
+177
+177
+176
+175
+174
+173
+171
+170
+169
+168
+166
+165
+164
+162
+161
+159
+157
+155
+153
+152
+149
+147
+145
+143
+141
+139
+137
+135
+133
+131
+128
+126
+124
+122
+119
+117
+114
+112
+110
+107
+105
+102
+100
+98
+95
+93
+90
+87
+84
+82
+80
+78
+75
+72
+70
+67
+65
+62
+59
+61
+63
+66
+68
+71
+73
+76
+79
+81
+83
+86
+88
+91
+93
+96
+99
+101
+103
+106
+108
+110
+113
+116
+117
+120
+122
+124
+127
+129
+131
+133
+135
+137
+139
+141
+143
+146
+147
+149
+151
+153
+155
+156
+158
+160
+161
+163
+164
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+175
+176
+175
+176
+176
+176
+176
+176
+176
+176
+175
+174
+174
+173
+172
+172
+170
+169
+168
+167
+166
+164
+163
+161
+159
+158
+156
+155
+153
+151
+149
+147
+146
+143
+142
+139
+137
+136
+133
+131
+129
+126
+124
+122
+120
+117
+115
+113
+111
+108
+105
+104
+100
+99
+96
+94
+91
+89
+87
+84
+81
+79
+76
+74
+71
+68
+66
+64
+61
+57
+60
+62
+65
+67
+70
+73
+75
+78
+80
+82
+85
+87
+89
+92
+94
+97
+99
+102
+104
+107
+109
+111
+113
+116
+118
+121
+123
+124
+127
+129
+131
+133
+135
+138
+140
+141
+144
+146
+147
+149
+151
+153
+154
+156
+157
+159
+161
+162
+163
+164
+165
+166
+168
+169
+170
+170
+171
+171
+172
+172
+172
+173
+173
+173
+173
+173
+173
+172
+172
+171
+171
+170
+169
+169
+167
+166
+165
+165
+163
+162
+161
+159
+157
+156
+154
+152
+151
+149
+147
+145
+143
+141
+139
+137
+136
+133
+131
+129
+127
+124
+122
+121
+118
+116
+114
+111
+108
+106
+104
+101
+100
+97
+94
+92
+90
+88
+84
+82
+80
+77
+74
+72
+70
+67
+64
+62
+60
+56
+59
+61
+63
+66
+69
+71
+74
+76
+79
+81
+83
+86
+89
+91
+93
+96
+98
+100
+102
+105
+107
+110
+112
+114
+116
+119
+121
+123
+125
+128
+130
+131
+133
+136
+138
+139
+141
+143
+145
+147
+148
+150
+151
+154
+154
+156
+158
+159
+160
+162
+163
+164
+165
+166
+167
+168
+168
+169
+170
+170
+170
+170
+170
+171
+171
+170
+170
+170
+169
+169
+168
+167
+167
+166
+165
+164
+163
+161
+160
+159
+158
+156
+155
+154
+152
+151
+149
+147
+145
+143
+142
+140
+138
+135
+133
+131
+129
+127
+125
+123
+121
+118
+116
+114
+112
+110
+107
+105
+102
+100
+98
+96
+93
+90
+88
+86
+83
+81
+79
+76
+74
+71
+68
+66
+63
+61
+59
+54
+57
+60
+62
+65
+67
+69
+73
+75
+77
+80
+82
+84
+86
+90
+92
+94
+97
+98
+101
+103
+105
+108
+110
+112
+114
+117
+119
+121
+124
+125
+127
+129
+131
+134
+136
+137
+139
+142
+142
+144
+146
+148
+150
+151
+153
+154
+156
+157
+158
+159
+161
+162
+162
+163
+164
+165
+165
+166
+167
+167
+167
+168
+168
+168
+168
+168
+167
+167
+166
+166
+166
+165
+164
+163
+162
+161
+160
+159
+158
+157
+155
+154
+152
+152
+150
+148
+146
+144
+143
+141
+139
+137
+135
+134
+132
+130
+127
+125
+123
+121
+119
+116
+115
+113
+110
+108
+106
+103
+101
+99
+97
+94
+92
+89
+87
+84
+82
+80
+77
+74
+72
+69
+67
+65
+62
+59
+57
+53
+56
+59
+61
+64
+66
+68
+70
+73
+75
+78
+80
+83
+85
+88
+90
+92
+95
+97
+99
+102
+104
+107
+108
+110
+113
+115
+117
+119
+122
+124
+125
+127
+130
+132
+133
+135
+137
+139
+140
+142
+144
+146
+147
+149
+151
+152
+153
+154
+156
+157
+158
+159
+159
+160
+162
+162
+163
+163
+163
+164
+164
+165
+164
+165
+165
+165
+165
+164
+164
+163
+163
+162
+162
+160
+160
+159
+158
+157
+156
+155
+153
+152
+150
+149
+147
+145
+144
+142
+141
+139
+137
+135
+133
+131
+130
+128
+125
+123
+122
+119
+118
+115
+113
+111
+108
+106
+104
+101
+99
+97
+95
+92
+90
+88
+85
+83
+81
+78
+76
+73
+71
+68
+66
+63
+61
+59
+56
+52
+55
+57
+60
+62
+64
+67
+69
+72
+74
+76
+79
+81
+84
+86
+89
+91
+94
+96
+97
+100
+103
+105
+107
+109
+111
+113
+115
+117
+119
+121
+124
+126
+127
+129
+131
+133
+134
+136
+139
+140
+142
+143
+144
+147
+148
+149
+151
+151
+153
+154
+155
+156
+157
+158
+159
+159
+160
+161
+161
+161
+162
+162
+162
+162
+162
+161
+161
+161
+161
+161
+160
+159
+159
+158
+157
+156
+155
+154
+153
+152
+150
+150
+148
+147
+145
+144
+141
+140
+138
+136
+135
+134
+132
+129
+127
+125
+124
+121
+120
+117
+115
+113
+111
+109
+107
+104
+102
+100
+98
+96
+93
+91
+88
+87
+84
+82
+79
+76
+74
+71
+70
+67
+64
+62
+60
+57
+55
+51
+54
+56
+58
+61
+63
+66
+68
+70
+73
+75
+78
+80
+82
+84
+87
+89
+91
+94
+96
+99
+100
+102
+104
+107
+110
+111
+113
+116
+117
+120
+122
+123
+125
+128
+129
+131
+133
+134
+136
+137
+139
+140
+143
+144
+145
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+157
+158
+158
+159
+158
+159
+159
+159
+159
+159
+159
+158
+158
+158
+157
+156
+156
+155
+155
+153
+153
+152
+150
+149
+148
+147
+145
+144
+142
+140
+140
+138
+136
+135
+133
+131
+129
+127
+125
+123
+121
+119
+118
+115
+113
+111
+109
+107
+104
+102
+101
+98
+96
+94
+92
+89
+87
+84
+83
+80
+77
+76
+73
+70
+68
+66
+64
+61
+58
+56
+53
+49
+52
+55
+57
+60
+62
+64
+67
+69
+71
+73
+76
+79
+81
+83
+86
+88
+90
+92
+95
+96
+98
+101
+104
+105
+108
+110
+112
+113
+115
+118
+119
+121
+123
+125
+127
+128
+131
+132
+133
+135
+137
+138
+140
+142
+143
+144
+145
+147
+148
+149
+150
+151
+151
+152
+154
+153
+154
+155
+156
+155
+156
+157
+157
+156
+156
+156
+156
+156
+155
+155
+154
+154
+153
+152
+152
+150
+150
+149
+147
+146
+146
+144
+143
+142
+141
+139
+137
+135
+134
+132
+130
+129
+127
+125
+123
+121
+120
+117
+116
+113
+112
+109
+108
+105
+103
+101
+98
+97
+94
+92
+90
+88
+86
+83
+81
+78
+76
+73
+71
+69
+67
+64
+62
+59
+57
+54
+51
+48
+50
+53
+55
+58
+61
+63
+65
+68
+70
+72
+75
+77
+79
+81
+84
+85
+88
+91
+93
+95
+97
+100
+101
+103
+106
+107
+110
+112
+114
+116
+117
+120
+121
+123
+124
+127
+128
+130
+131
+133
+135
+136
+137
+139
+141
+142
+143
+144
+145
+146
+147
+148
+149
+149
+150
+151
+152
+152
+153
+153
+153
+154
+153
+153
+153
+153
+153
+153
+153
+152
+152
+151
+150
+150
+149
+149
+148
+146
+145
+144
+143
+141
+140
+139
+138
+136
+135
+133
+131
+130
+129
+127
+125
+123
+121
+119
+118
+115
+114
+112
+109
+108
+105
+104
+101
+99
+97
+95
+93
+91
+88
+86
+84
+81
+79
+77
+74
+73
+70
+68
+66
+63
+60
+58
+56
+53
+51
+47
+50
+51
+54
+56
+58
+61
+63
+65
+69
+71
+73
+75
+78
+80
+82
+84
+86
+89
+91
+93
+95
+97
+100
+102
+103
+105
+108
+109
+112
+114
+115
+117
+119
+120
+122
+124
+126
+128
+129
+130
+132
+134
+135
+136
+138
+139
+140
+141
+143
+143
+144
+145
+146
+147
+148
+148
+148
+150
+150
+150
+150
+151
+151
+151
+151
+150
+150
+151
+149
+150
+149
+148
+148
+147
+147
+146
+145
+144
+143
+141
+140
+139
+138
+137
+135
+133
+132
+130
+130
+127
+126
+124
+122
+121
+119
+117
+115
+114
+112
+109
+108
+105
+104
+101
+99
+97
+95
+93
+90
+89
+87
+84
+82
+79
+78
+75
+73
+71
+68
+66
+64
+61
+59
+56
+54
+52
+49
+45
+48
+50
+53
+55
+57
+60
+62
+64
+67
+69
+71
+73
+76
+79
+80
+82
+85
+87
+89
+91
+94
+95
+97
+100
+102
+104
+106
+107
+109
+111
+113
+115
+117
+119
+120
+122
+124
+125
+127
+129
+130
+131
+133
+134
+136
+137
+138
+139
+140
+141
+142
+142
+144
+144
+145
+146
+146
+147
+147
+147
+148
+148
+148
+148
+148
+148
+148
+147
+147
+147
+146
+145
+145
+144
+144
+143
+142
+141
+140
+139
+138
+137
+135
+134
+133
+132
+130
+128
+127
+125
+124
+122
+120
+119
+117
+115
+114
+111
+109
+108
+105
+104
+101
+100
+98
+95
+94
+92
+89
+87
+85
+82
+80
+78
+76
+73
+71
+69
+67
+64
+62
+60
+57
+55
+52
+50
+47
+44
+46
+49
+51
+54
+56
+58
+61
+63
+65
+67
+70
+72
+74
+76
+78
+81
+83
+85
+87
+89
+92
+93
+96
+98
+99
+101
+103
+106
+107
+110
+111
+113
+115
+116
+118
+120
+121
+123
+125
+126
+128
+129
+130
+131
+133
+134
+135
+136
+137
+138
+139
+140
+141
+141
+142
+143
+143
+143
+144
+145
+145
+145
+146
+145
+145
+145
+145
+145
+144
+144
+144
+143
+142
+141
+141
+140
+140
+138
+138
+137
+135
+134
+133
+131
+130
+129
+128
+126
+124
+123
+121
+119
+118
+117
+115
+113
+111
+109
+107
+105
+104
+102
+99
+97
+96
+93
+91
+90
+87
+85
+83
+81
+78
+77
+74
+72
+70
+67
+65
+63
+61
+58
+56
+54
+51
+48
+47
+43
+45
+47
+49
+52
+54
+56
+59
+61
+64
+66
+68
+70
+73
+74
+77
+79
+82
+84
+85
+88
+90
+92
+94
+96
+97
+100
+102
+103
+105
+107
+109
+111
+113
+114
+116
+117
+119
+121
+123
+124
+125
+126
+127
+129
+130
+131
+133
+134
+134
+135
+137
+138
+138
+138
+140
+140
+141
+141
+142
+142
+142
+142
+142
+142
+142
+143
+142
+142
+142
+141
+141
+141
+139
+139
+138
+137
+137
+135
+135
+134
+133
+132
+130
+129
+127
+127
+125
+124
+122
+120
+119
+118
+116
+114
+113
+111
+109
+107
+105
+104
+102
+100
+98
+96
+93
+91
+90
+87
+85
+84
+81
+79
+77
+74
+72
+70
+68
+66
+63
+61
+59
+56
+54
+52
+49
+47
+45
+41
+44
+45
+48
+50
+52
+55
+57
+59
+61
+64
+66
+68
+71
+72
+75
+78
+79
+82
+84
+86
+88
+90
+91
+93
+96
+98
+99
+102
+103
+105
+106
+108
+111
+112
+113
+115
+117
+119
+120
+121
+123
+124
+126
+127
+127
+129
+130
+131
+132
+133
+134
+135
+135
+136
+136
+137
+137
+139
+138
+139
+139
+139
+139
+139
+139
+139
+140
+139
+139
+139
+138
+137
+137
+136
+135
+135
+134
+133
+132
+131
+130
+129
+128
+127
+125
+124
+123
+121
+120
+118
+116
+115
+113
+111
+110
+108
+107
+105
+103
+102
+99
+97
+95
+93
+91
+90
+87
+86
+83
+81
+80
+77
+75
+73
+70
+68
+66
+64
+62
+60
+58
+55
+52
+51
+48
+46
+43
+39
+42
+44
+46
+49
+50
+53
+56
+58
+60
+62
+65
+67
+69
+71
+74
+76
+78
+79
+81
+84
+86
+87
+90
+91
+94
+96
+97
+99
+101
+103
+105
+106
+108
+109
+111
+112
+115
+116
+117
+118
+120
+122
+122
+124
+125
+127
+128
+129
+129
+130
+132
+132
+133
+133
+134
+135
+135
+136
+136
+136
+136
+136
+137
+137
+137
+136
+137
+136
+136
+136
+135
+135
+134
+133
+132
+132
+131
+131
+129
+128
+127
+127
+125
+124
+123
+121
+120
+119
+117
+116
+114
+112
+112
+110
+107
+107
+105
+103
+101
+99
+98
+96
+93
+91
+90
+87
+86
+84
+82
+79
+77
+75
+73
+71
+69
+67
+64
+62
+60
+58
+55
+54
+51
+49
+46
+44
+41
+38
+40
+43
+45
+47
+49
+51
+54
+56
+58
+61
+62
+65
+67
+69
+72
+73
+76
+77
+80
+81
+83
+85
+88
+90
+92
+94
+96
+97
+99
+101
+102
+104
+106
+107
+109
+110
+112
+114
+115
+116
+118
+119
+120
+121
+122
+124
+125
+126
+127
+127
+128
+129
+130
+131
+131
+132
+132
+132
+133
+133
+134
+134
+134
+134
+134
+134
+133
+134
+133
+132
+133
+131
+132
+131
+130
+129
+128
+128
+126
+126
+125
+124
+122
+121
+120
+119
+118
+116
+115
+114
+112
+111
+109
+107
+106
+104
+102
+101
+98
+97
+95
+93
+91
+90
+87
+86
+84
+82
+80
+78
+75
+73
+72
+69
+67
+65
+63
+60
+59
+56
+53
+51
+49
+47
+45
+43
+40
+36
+39
+41
+44
+45
+48
+50
+52
+55
+57
+59
+61
+63
+65
+67
+69
+71
+74
+76
+78
+80
+81
+84
+86
+87
+89
+91
+93
+95
+97
+99
+100
+101
+103
+105
+106
+109
+109
+111
+113
+114
+115
+117
+117
+119
+120
+121
+122
+123
+124
+125
+126
+126
+127
+128
+128
+129
+130
+130
+130
+130
+131
+131
+131
+131
+131
+131
+131
+131
+130
+130
+129
+129
+128
+128
+127
+126
+126
+125
+124
+124
+122
+121
+120
+119
+117
+116
+116
+113
+113
+111
+109
+108
+107
+105
+103
+102
+100
+99
+97
+94
+93
+91
+89
+88
+85
+83
+81
+80
+78
+76
+73
+72
+70
+67
+65
+63
+61
+59
+56
+54
+52
+50
+48
+46
+43
+41
+38
+34
+37
+39
+41
+44
+46
+48
+50
+53
+55
+57
+59
+61
+63
+66
+68
+70
+71
+73
+76
+77
+79
+82
+84
+85
+87
+89
+91
+93
+94
+96
+98
+100
+101
+103
+104
+106
+107
+108
+110
+112
+112
+114
+115
+116
+118
+119
+119
+121
+121
+122
+123
+124
+125
+125
+126
+127
+127
+127
+127
+128
+128
+128
+128
+129
+128
+128
+128
+128
+128
+127
+127
+126
+126
+125
+124
+124
+123
+122
+122
+120
+120
+118
+118
+116
+115
+114
+113
+111
+110
+108
+107
+106
+104
+103
+101
+100
+97
+96
+94
+92
+91
+89
+87
+86
+84
+82
+80
+78
+76
+73
+72
+70
+68
+66
+63
+61
+59
+56
+55
+53
+51
+48
+46
+44
+41
+40
+37
+33
+35
+37
+39
+42
+44
+46
+49
+51
+53
+55
+57
+59
+62
+63
+66
+67
+69
+71
+74
+76
+78
+80
+81
+84
+86
+87
+89
+90
+92
+94
+95
+97
+98
+100
+102
+104
+104
+106
+108
+109
+110
+111
+112
+114
+114
+116
+116
+118
+118
+120
+121
+121
+122
+123
+123
+123
+124
+124
+125
+125
+125
+126
+126
+125
+126
+125
+125
+125
+125
+125
+124
+123
+123
+123
+122
+121
+120
+120
+119
+118
+117
+116
+115
+113
+112
+111
+110
+109
+108
+107
+105
+103
+102
+100
+99
+97
+95
+94
+93
+90
+88
+87
+85
+83
+82
+80
+77
+76
+73
+72
+70
+68
+66
+63
+61
+59
+58
+56
+53
+51
+49
+47
+44
+42
+40
+37
+36
+31
+33
+36
+38
+41
+42
+45
+47
+49
+51
+53
+55
+57
+60
+61
+64
+65
+68
+70
+71
+74
+76
+77
+80
+81
+83
+85
+87
+89
+90
+92
+93
+95
+96
+98
+99
+101
+103
+104
+105
+107
+108
+108
+110
+111
+112
+113
+114
+115
+116
+117
+118
+118
+119
+120
+120
+121
+121
+122
+122
+122
+123
+122
+123
+122
+122
+123
+122
+123
+122
+122
+121
+120
+120
+120
+119
+119
+118
+117
+116
+115
+114
+113
+112
+111
+110
+109
+108
+106
+105
+104
+102
+101
+99
+98
+97
+95
+93
+92
+90
+88
+86
+84
+83
+81
+79
+77
+76
+73
+72
+70
+68
+66
+64
+62
+60
+58
+56
+53
+52
+49
+47
+44
+42
+40
+38
+36
+34
+29
+32
+34
+36
+38
+41
+43
+45
+47
+50
+52
+54
+56
+58
+60
+62
+64
+66
+68
+70
+71
+74
+75
+77
+79
+81
+83
+85
+86
+88
+89
+91
+92
+94
+95
+97
+99
+100
+101
+102
+104
+105
+106
+107
+108
+110
+111
+111
+113
+113
+114
+115
+116
+117
+117
+118
+118
+118
+119
+119
+119
+120
+120
+120
+120
+120
+120
+119
+120
+119
+119
+118
+118
+117
+117
+116
+116
+115
+114
+113
+113
+111
+110
+109
+108
+108
+107
+105
+104
+102
+101
+99
+98
+97
+95
+94
+92
+91
+89
+87
+86
+84
+83
+80
+79
+77
+76
+74
+72
+69
+68
+66
+64
+61
+60
+57
+55
+53
+51
+49
+47
+45
+43
+41
+39
+37
+34
+32
+28
+31
+33
+35
+37
+39
+41
+43
+46
+47
+50
+51
+53
+56
+58
+60
+61
+64
+65
+67
+70
+72
+73
+75
+77
+79
+80
+82
+83
+85
+87
+89
+90
+92
+93
+95
+96
+97
+99
+100
+102
+102
+103
+105
+106
+106
+108
+109
+110
+111
+111
+112
+113
+113
+114
+115
+115
+116
+116
+117
+116
+117
+117
+117
+116
+117
+117
+117
+117
+116
+115
+116
+115
+114
+114
+113
+113
+112
+111
+111
+110
+109
+108
+107
+106
+104
+104
+102
+101
+100
+98
+98
+96
+94
+93
+92
+90
+89
+87
+86
+84
+82
+81
+78
+77
+75
+73
+72
+69
+68
+66
+63
+61
+60
+57
+56
+54
+51
+50
+48
+46
+43
+41
+39
+37
+35
+32
+30
+27
+29
+31
+33
+35
+37
+39
+41
+43
+45
+48
+50
+52
+54
+56
+58
+59
+62
+64
+65
+68
+69
+71
+73
+74
+77
+78
+80
+81
+83
+84
+86
+88
+90
+90
+92
+94
+95
+96
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+110
+111
+112
+112
+112
+113
+113
+113
+113
+114
+114
+114
+114
+114
+114
+114
+113
+113
+114
+113
+112
+112
+111
+110
+110
+110
+109
+108
+107
+106
+105
+104
+104
+102
+101
+100
+99
+98
+96
+95
+93
+92
+91
+89
+87
+86
+85
+83
+81
+80
+78
+76
+74
+72
+71
+69
+68
+66
+63
+62
+60
+57
+56
+53
+52
+50
+47
+46
+44
+41
+39
+37
+35
+33
+31
+28
+25
+27
+29
+31
+33
+36
+37
+40
+41
+43
+46
+48
+50
+52
+54
+56
+58
+60
+61
+63
+65
+68
+69
+71
+72
+74
+75
+78
+79
+81
+82
+84
+85
+87
+88
+90
+91
+92
+93
+95
+96
+98
+98
+100
+101
+101
+102
+104
+105
+106
+106
+107
+108
+108
+109
+110
+110
+110
+110
+111
+111
+111
+111
+111
+112
+111
+111
+111
+111
+111
+110
+110
+109
+109
+109
+108
+107
+106
+106
+105
+105
+103
+103
+101
+101
+100
+98
+97
+96
+95
+94
+92
+91
+90
+89
+87
+85
+84
+82
+81
+79
+77
+76
+74
+72
+71
+69
+67
+66
+63
+61
+60
+58
+55
+53
+52
+49
+47
+45
+43
+42
+39
+38
+35
+34
+31
+29
+27
+22
+25
+27
+29
+31
+34
+35
+37
+40
+42
+44
+46
+48
+50
+52
+54
+56
+58
+59
+61
+63
+64
+66
+68
+71
+72
+74
+75
+77
+79
+80
+81
+83
+84
+85
+87
+89
+90
+91
+92
+93
+95
+96
+97
+98
+99
+100
+101
+102
+102
+103
+104
+105
+105
+105
+106
+107
+108
+107
+108
+108
+108
+109
+108
+108
+108
+108
+109
+108
+108
+108
+107
+107
+107
+105
+105
+105
+104
+103
+102
+102
+101
+100
+99
+98
+97
+96
+95
+93
+92
+91
+90
+88
+87
+86
+84
+83
+82
+80
+78
+77
+75
+74
+72
+70
+69
+66
+65
+63
+61
+60
+57
+56
+54
+51
+49
+48
+46
+43
+41
+40
+38
+35
+33
+31
+29
+27
+25
+21
+23
+25
+27
+29
+32
+33
+36
+38
+40
+42
+44
+46
+48
+50
+52
+54
+55
+57
+59
+61
+63
+64
+66
+68
+70
+71
+73
+74
+76
+77
+80
+81
+82
+84
+85
+86
+87
+89
+90
+92
+92
+93
+94
+95
+96
+97
+98
+99
+99
+100
+102
+102
+103
+103
+104
+104
+104
+105
+105
+105
+105
+105
+106
+106
+105
+105
+105
+106
+105
+105
+105
+104
+104
+103
+102
+102
+101
+101
+100
+99
+98
+97
+97
+95
+94
+94
+93
+91
+89
+88
+88
+86
+84
+83
+82
+80
+79
+77
+76
+75
+72
+71
+69
+68
+66
+65
+62
+61
+59
+58
+56
+54
+51
+50
+48
+46
+44
+42
+40
+38
+36
+34
+31
+30
+27
+25
+23
+19
+22
+24
+26
+27
+30
+32
+34
+36
+38
+39
+42
+43
+46
+47
+50
+51
+53
+55
+57
+58
+60
+63
+64
+66
+67
+69
+70
+73
+74
+75
+76
+78
+80
+81
+83
+83
+85
+86
+87
+89
+90
+91
+92
+93
+94
+95
+95
+96
+97
+98
+98
+99
+100
+100
+101
+102
+101
+102
+103
+103
+103
+102
+103
+103
+102
+102
+103
+102
+103
+102
+102
+101
+101
+100
+100
+100
+99
+98
+98
+97
+96
+94
+93
+93
+92
+91
+90
+89
+87
+87
+85
+83
+83
+81
+80
+78
+77
+75
+74
+72
+71
+69
+68
+65
+64
+63
+61
+59
+57
+55
+54
+51
+50
+47
+46
+44
+42
+40
+38
+36
+34
+32
+30
+28
+25
+24
+22
+17
+19
+21
+23
+25
+28
+30
+31
+34
+36
+37
+40
+42
+43
+46
+47
+50
+51
+53
+54
+57
+58
+60
+62
+64
+65
+67
+68
+70
+72
+73
+74
+76
+77
+79
+80
+81
+83
+83
+85
+86
+87
+88
+89
+91
+91
+92
+92
+93
+95
+95
+96
+96
+97
+98
+98
+99
+99
+99
+99
+100
+100
+100
+100
+100
+100
+100
+100
+100
+99
+99
+98
+99
+98
+97
+97
+97
+96
+95
+94
+94
+92
+92
+91
+90
+89
+89
+87
+86
+84
+84
+82
+81
+80
+79
+77
+75
+74
+73
+71
+70
+68
+67
+65
+63
+62
+60
+59
+56
+55
+53
+51
+49
+47
+46
+44
+42
+40
+38
+36
+34
+32
+29
+28
+25
+24
+21
+19
+16
+18
+19
+22
+24
+26
+28
+30
+31
+34
+36
+38
+40
+42
+44
+45
+47
+49
+50
+52
+54
+56
+57
+59
+61
+62
+65
+66
+67
+69
+71
+72
+73
+75
+76
+78
+79
+80
+81
+83
+83
+85
+86
+86
+87
+88
+89
+90
+91
+91
+92
+93
+94
+95
+95
+95
+95
+96
+96
+97
+97
+97
+97
+97
+97
+97
+98
+97
+97
+97
+96
+96
+96
+95
+95
+94
+94
+93
+92
+92
+91
+90
+89
+88
+87
+86
+86
+84
+83
+82
+81
+80
+78
+77
+76
+75
+73
+72
+71
+69
+68
+66
+64
+63
+61
+59
+58
+56
+54
+53
+50
+49
+47
+45
+44
+42
+40
+38
+35
+33
+32
+29
+28
+26
+24
+22
+19
+17
+13
+16
+18
+19
+22
+24
+26
+28
+30
+31
+34
+36
+38
+40
+42
+43
+45
+47
+48
+50
+52
+54
+55
+57
+59
+60
+62
+63
+65
+67
+68
+69
+71
+72
+74
+75
+76
+77
+79
+80
+81
+82
+82
+84
+85
+86
+87
+88
+88
+89
+89
+91
+91
+92
+92
+93
+93
+94
+93
+94
+94
+94
+94
+94
+95
+95
+95
+95
+94
+94
+94
+93
+93
+93
+92
+92
+91
+90
+89
+89
+88
+88
+87
+85
+84
+84
+82
+82
+80
+79
+79
+78
+76
+75
+73
+72
+70
+69
+68
+66
+65
+63
+62
+61
+59
+58
+56
+54
+52
+50
+48
+47
+45
+44
+41
+39
+37
+35
+34
+31
+30
+28
+26
+24
+22
+20
+18
+16
+12
+14
+16
+18
+20
+22
+24
+26
+28
+30
+32
+33
+36
+38
+39
+41
+43
+45
+46
+48
+50
+52
+54
+55
+57
+58
+59
+61
+63
+64
+65
+67
+68
+69
+71
+72
+74
+75
+76
+77
+78
+79
+80
+82
+82
+83
+84
+84
+86
+87
+87
+88
+88
+89
+89
+90
+90
+90
+90
+91
+91
+91
+92
+92
+92
+92
+91
+91
+92
+91
+91
+91
+90
+89
+89
+88
+88
+87
+87
+86
+85
+85
+84
+84
+82
+81
+80
+79
+78
+77
+76
+75
+74
+72
+71
+70
+68
+67
+66
+64
+63
+61
+60
+58
+56
+55
+53
+52
+50
+48
+46
+45
+43
+41
+39
+38
+36
+34
+32
+30
+28
+26
+24
+22
+20
+18
+15
+14
+9
+12
+14
+16
+18
+20
+22
+24
+25
+28
+30
+32
+34
+35
+37
+39
+41
+42
+44
+46
+48
+49
+50
+53
+54
+56
+58
+59
+60
+62
+63
+65
+66
+67
+69
+70
+71
+72
+73
+74
+75
+76
+78
+78
+80
+81
+81
+82
+83
+83
+85
+85
+86
+86
+86
+86
+88
+88
+87
+88
+89
+89
+88
+89
+89
+89
+88
+89
+88
+88
+88
+88
+88
+87
+87
+86
+85
+85
+84
+84
+83
+82
+81
+81
+80
+79
+78
+77
+76
+75
+73
+72
+71
+70
+68
+67
+66
+64
+63
+62
+60
+59
+57
+56
+54
+53
+51
+49
+48
+46
+45
+43
+41
+39
+37
+35
+34
+31
+30
+28
+26
+24
+22
+20
+18
+16
+14
+12
+8
+10
+12
+14
+16
+18
+20
+22
+24
+25
+27
+29
+32
+33
+35
+37
+38
+40
+41
+44
+45
+48
+49
+50
+52
+53
+55
+56
+57
+60
+61
+62
+63
+65
+66
+67
+68
+69
+71
+72
+73
+74
+75
+76
+76
+78
+79
+79
+80
+80
+81
+82
+83
+83
+83
+84
+85
+85
+85
+86
+86
+86
+86
+86
+86
+86
+86
+86
+85
+85
+85
+85
+84
+84
+83
+83
+82
+82
+81
+81
+80
+79
+79
+78
+77
+75
+75
+74
+73
+72
+71
+69
+69
+67
+66
+65
+63
+62
+61
+59
+58
+57
+55
+54
+52
+50
+48
+47
+45
+44
+42
+40
+38
+36
+35
+33
+31
+30
+27
+26
+23
+22
+20
+18
+16
+14
+12
+10
+5
+8
+10
+12
+14
+16
+18
+20
+22
+24
+25
+27
+29
+31
+33
+34
+36
+38
+40
+42
+43
+45
+47
+48
+49
+52
+52
+54
+55
+56
+58
+60
+60
+62
+63
+65
+66
+67
+68
+69
+71
+72
+72
+73
+74
+75
+76
+77
+77
+78
+78
+79
+80
+80
+81
+82
+82
+82
+82
+82
+83
+83
+83
+83
+84
+83
+83
+82
+83
+82
+82
+82
+81
+81
+80
+81
+80
+80
+79
+78
+77
+77
+76
+75
+74
+74
+72
+72
+71
+69
+68
+67
+66
+64
+63
+62
+60
+60
+58
+57
+55
+54
+53
+51
+50
+48
+47
+45
+43
+41
+39
+38
+36
+34
+33
+31
+29
+27
+25
+23
+22
+20
+18
+16
+14
+12
+10
+8
+4
+6
+8
+10
+12
+14
+16
+17
+19
+21
+24
+25
+27
+29
+30
+33
+34
+36
+38
+39
+41
+43
+44
+46
+47
+49
+50
+52
+53
+55
+56
+57
+58
+60
+61
+62
+63
+65
+65
+67
+67
+68
+70
+71
+71
+72
+73
+74
+75
+75
+76
+76
+77
+77
+78
+79
+79
+79
+79
+80
+80
+80
+81
+81
+81
+80
+81
+80
+80
+80
+79
+79
+79
+79
+78
+78
+77
+77
+76
+75
+75
+74
+73
+72
+71
+71
+70
+69
+68
+67
+66
+65
+64
+62
+61
+60
+59
+57
+56
+54
+53
+52
+50
+48
+47
+46
+44
+43
+41
+39
+37
+36
+34
+33
+30
+29
+27
+26
+23
+21
+20
+18
+16
+13
+11
+10
+8
+6
+2
+4
+6
+8
+10
+11
+14
+16
+18
+19
+21
+23
+25
+27
+29
+30
+32
+33
+35
+37
+39
+40
+42
+43
+45
+46
+48
+49
+51
+52
+53
+55
+56
+57
+58
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+69
+70
+71
+71
+72
+73
+74
+74
+74
+76
+75
+77
+77
+77
+77
+77
+78
+77
+77
+78
+77
+77
+77
+77
+77
+77
+77
+77
+76
+75
+75
+74
+74
+73
+73
+72
+71
+71
+70
+69
+68
+67
+66
+65
+64
+63
+62
+60
+60
+59
+57
+56
+54
+54
+52
+50
+49
+48
+46
+44
+43
+42
+40
+38
+37
+35
+33
+32
+30
+28
+27
+25
+23
+22
+20
+18
+16
+14
+11
+10
+8
+6
+4
--- /dev/null
+P3
+# CREATOR: GIMP PNM Filter Version 1.1
+160 120
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+243
+50
+50
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+50
+86
+243
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+0
+255
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+242
+190
+255
+218
+71
+255
+207
+17
+255
+205
+4
+255
+210
+31
+255
+223
+95
+255
+243
+196
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+239
+174
+255
+204
+2
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+213
+43
+255
+204
+0
+255
+219
+77
+255
+247
+214
+255
+254
+251
+255
+251
+234
+255
+238
+169
+255
+217
+63
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+205
+5
+255
+204
+0
+255
+252
+238
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+210
+32
+255
+204
+0
+255
+230
+132
+255
+251
+237
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+236
+158
+255
+204
+0
+255
+204
+0
+255
+204
+1
+255
+211
+36
+255
+221
+87
+255
+237
+164
+255
+254
+250
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+242
+190
+255
+219
+77
+255
+206
+11
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+214
+48
+255
+251
+233
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+254
+252
+255
+247
+213
+255
+234
+152
+255
+211
+35
+255
+204
+0
+255
+222
+92
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+248
+220
+255
+204
+0
+255
+208
+19
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+251
+235
+255
+204
+0
+255
+205
+5
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+1
+255
+204
+0
+255
+255
+254
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+1
+255
+204
+0
+255
+255
+254
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+1
+255
+204
+0
+255
+255
+254
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+215
+54
+255
+234
+150
+255
+247
+215
+255
+254
+248
+255
+254
+249
+255
+245
+204
+255
+218
+68
+255
+204
+0
+255
+212
+42
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+208
+19
+255
+204
+0
+255
+242
+190
+255
+255
+254
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+208
+19
+255
+204
+0
+255
+242
+190
+255
+255
+254
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+208
+19
+255
+204
+0
+255
+242
+190
+255
+255
+254
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+247
+217
+255
+204
+2
+255
+206
+10
+255
+251
+236
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+252
+239
+255
+206
+11
+255
+204
+2
+255
+247
+216
+255
+255
+255
+255
+241
+186
+255
+219
+75
+255
+207
+15
+255
+206
+9
+255
+215
+57
+255
+242
+188
+255
+255
+255
+255
+255
+255
+255
+247
+217
+255
+204
+2
+255
+206
+10
+255
+251
+236
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+252
+239
+255
+206
+11
+255
+204
+2
+255
+247
+216
+255
+255
+255
+255
+241
+186
+255
+219
+75
+255
+207
+15
+255
+206
+9
+255
+215
+57
+255
+242
+188
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+2
+255
+238
+172
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+221
+84
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+221
+84
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+221
+84
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+221
+85
+255
+204
+0
+255
+230
+132
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+232
+138
+255
+204
+0
+255
+220
+80
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+205
+5
+255
+245
+204
+255
+255
+255
+255
+255
+255
+255
+221
+85
+255
+204
+0
+255
+230
+132
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+232
+138
+255
+204
+0
+255
+220
+80
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+205
+5
+255
+245
+204
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+245
+203
+255
+226
+111
+255
+213
+46
+255
+206
+9
+255
+205
+5
+255
+209
+27
+255
+221
+83
+255
+243
+195
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+250
+229
+255
+221
+83
+255
+208
+18
+255
+204
+1
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+250
+229
+255
+221
+83
+255
+208
+18
+255
+204
+1
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+250
+229
+255
+221
+83
+255
+208
+18
+255
+204
+1
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+245
+205
+255
+204
+0
+255
+209
+25
+255
+254
+249
+255
+255
+255
+255
+255
+255
+255
+254
+251
+255
+210
+29
+255
+204
+0
+255
+244
+198
+255
+255
+255
+255
+255
+255
+255
+221
+84
+255
+245
+205
+255
+254
+249
+255
+249
+227
+255
+222
+88
+255
+204
+0
+255
+222
+88
+255
+255
+255
+255
+255
+255
+255
+245
+205
+255
+204
+0
+255
+209
+25
+255
+254
+249
+255
+255
+255
+255
+255
+255
+255
+254
+251
+255
+210
+29
+255
+204
+0
+255
+244
+198
+255
+255
+255
+255
+255
+255
+255
+221
+84
+255
+245
+205
+255
+254
+249
+255
+249
+227
+255
+222
+88
+255
+204
+0
+255
+222
+88
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+218
+71
+255
+204
+0
+255
+236
+159
+255
+255
+255
+255
+255
+255
+255
+238
+168
+255
+204
+0
+255
+216
+60
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+252
+239
+255
+204
+0
+255
+210
+29
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+218
+71
+255
+204
+0
+255
+236
+159
+255
+255
+255
+255
+255
+255
+255
+238
+168
+255
+204
+0
+255
+216
+60
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+252
+239
+255
+204
+0
+255
+210
+29
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+206
+10
+255
+206
+11
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+206
+10
+255
+206
+11
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+242
+192
+255
+204
+0
+255
+213
+46
+255
+255
+255
+255
+255
+255
+255
+215
+56
+255
+204
+0
+255
+240
+178
+255
+255
+255
+255
+255
+255
+255
+254
+252
+255
+232
+139
+255
+214
+48
+255
+206
+10
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+205
+6
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+242
+192
+255
+204
+0
+255
+213
+46
+255
+255
+255
+255
+255
+255
+255
+215
+56
+255
+204
+0
+255
+240
+178
+255
+255
+255
+255
+255
+255
+255
+254
+252
+255
+232
+139
+255
+214
+48
+255
+206
+10
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+205
+6
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+209
+26
+255
+209
+27
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+209
+26
+255
+209
+27
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+216
+58
+255
+204
+0
+255
+241
+187
+255
+244
+199
+255
+204
+0
+255
+212
+42
+255
+255
+254
+255
+255
+255
+255
+255
+255
+255
+227
+113
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+216
+58
+255
+204
+0
+255
+241
+187
+255
+244
+199
+255
+204
+0
+255
+212
+42
+255
+255
+254
+255
+255
+255
+255
+255
+255
+255
+227
+113
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+213
+43
+255
+213
+43
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+213
+43
+255
+213
+43
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+240
+179
+255
+204
+0
+255
+218
+72
+255
+221
+86
+255
+204
+0
+255
+236
+158
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+208
+18
+255
+204
+0
+255
+238
+168
+255
+252
+240
+255
+255
+254
+255
+252
+241
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+240
+179
+255
+204
+0
+255
+218
+72
+255
+221
+86
+255
+204
+0
+255
+236
+158
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+208
+18
+255
+204
+0
+255
+238
+168
+255
+252
+240
+255
+255
+254
+255
+252
+241
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+254
+255
+213
+45
+255
+204
+1
+255
+205
+3
+255
+209
+27
+255
+254
+249
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+206
+9
+255
+204
+0
+255
+239
+176
+255
+254
+248
+255
+248
+221
+255
+221
+87
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+254
+255
+213
+45
+255
+204
+1
+255
+205
+3
+255
+209
+27
+255
+254
+249
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+206
+9
+255
+204
+0
+255
+239
+176
+255
+254
+248
+255
+248
+221
+255
+221
+87
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+237
+165
+255
+204
+0
+255
+204
+0
+255
+232
+138
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+220
+81
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+219
+76
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+237
+165
+255
+204
+0
+255
+204
+0
+255
+232
+138
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+220
+81
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+219
+76
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+248
+218
+255
+204
+0
+255
+207
+15
+255
+252
+241
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+251
+235
+255
+220
+82
+255
+206
+10
+255
+207
+16
+255
+223
+96
+255
+252
+240
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+248
+218
+255
+204
+0
+255
+207
+15
+255
+252
+241
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+251
+235
+255
+220
+82
+255
+206
+10
+255
+207
+16
+255
+223
+96
+255
+252
+240
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+236
+158
+255
+204
+0
+255
+227
+116
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+236
+158
+255
+204
+0
+255
+227
+116
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+252
+238
+255
+218
+71
+255
+204
+0
+255
+247
+213
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+252
+238
+255
+218
+71
+255
+204
+0
+255
+247
+213
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+219
+74
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+204
+0
+255
+204
+0
+255
+219
+74
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+205
+4
+255
+217
+65
+255
+250
+229
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+204
+0
+255
+205
+4
+255
+217
+65
+255
+250
+229
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
+255
{ [ os windows? ] [ "libusb-1.0.dll" ] }
{ [ os macosx? ] [ "libusb-1.0.dylib" ] }
{ [ os unix? ] [ "libusb-1.0.so" ] }
- } cond "cdecl" add-library >>
+ } cond cdecl add-library >>
LIBRARY: libusb
: libusb_cpu_to_le16 ( x -- y )
ALIAS: libusb_le16_to_cpu libusb_cpu_to_le16
-CONSTANT: LIBUSB_CLASS_PER_INTERFACE 0
-CONSTANT: LIBUSB_CLASS_AUDIO 1
-CONSTANT: LIBUSB_CLASS_COMM 2
-CONSTANT: LIBUSB_CLASS_HID 3
-CONSTANT: LIBUSB_CLASS_PRINTER 7
-CONSTANT: LIBUSB_CLASS_PTP 6
-CONSTANT: LIBUSB_CLASS_MASS_STORAGE 8
-CONSTANT: LIBUSB_CLASS_HUB 9
-CONSTANT: LIBUSB_CLASS_DATA 10
-CONSTANT: LIBUSB_CLASS_VENDOR_SPEC HEX: ff
-TYPEDEF: int libusb_class_code
-
-CONSTANT: LIBUSB_DT_DEVICE HEX: 01
-CONSTANT: LIBUSB_DT_CONFIG HEX: 02
-CONSTANT: LIBUSB_DT_STRING HEX: 03
-CONSTANT: LIBUSB_DT_INTERFACE HEX: 04
-CONSTANT: LIBUSB_DT_ENDPOINT HEX: 05
-CONSTANT: LIBUSB_DT_HID HEX: 21
-CONSTANT: LIBUSB_DT_REPORT HEX: 22
-CONSTANT: LIBUSB_DT_PHYSICAL HEX: 23
-CONSTANT: LIBUSB_DT_HUB HEX: 29
-TYPEDEF: int libusb_descriptor_type
+C-ENUM: libusb_class_code
+ { LIBUSB_CLASS_PER_INTERFACE 0 }
+ { LIBUSB_CLASS_AUDIO 1 }
+ { LIBUSB_CLASS_COMM 2 }
+ { LIBUSB_CLASS_HID 3 }
+ { LIBUSB_CLASS_PRINTER 7 }
+ { LIBUSB_CLASS_PTP 6 }
+ { LIBUSB_CLASS_MASS_STORAGE 8 }
+ { LIBUSB_CLASS_HUB 9 }
+ { LIBUSB_CLASS_DATA 10 }
+ { LIBUSB_CLASS_VENDOR_SPEC HEX: ff } ;
+
+C-ENUM: libusb_descriptor_type
+ { LIBUSB_DT_DEVICE HEX: 01 }
+ { LIBUSB_DT_CONFIG HEX: 02 }
+ { LIBUSB_DT_STRING HEX: 03 }
+ { LIBUSB_DT_INTERFACE HEX: 04 }
+ { LIBUSB_DT_ENDPOINT HEX: 05 }
+ { LIBUSB_DT_HID HEX: 21 }
+ { LIBUSB_DT_REPORT HEX: 22 }
+ { LIBUSB_DT_PHYSICAL HEX: 23 }
+ { LIBUSB_DT_HUB HEX: 29 } ;
CONSTANT: LIBUSB_DT_DEVICE_SIZE 18
CONSTANT: LIBUSB_DT_CONFIG_SIZE 9
CONSTANT: LIBUSB_ENDPOINT_ADDRESS_MASK HEX: 0f
CONSTANT: LIBUSB_ENDPOINT_DIR_MASK HEX: 80
-CONSTANT: LIBUSB_ENDPOINT_IN HEX: 80
-CONSTANT: LIBUSB_ENDPOINT_OUT HEX: 00
-TYPEDEF: int libusb_endpoint_direction
+C-ENUM: libusb_endpoint_direction
+ { LIBUSB_ENDPOINT_IN HEX: 80 }
+ { LIBUSB_ENDPOINT_OUT HEX: 00 } ;
CONSTANT: LIBUSB_TRANSFER_TYPE_MASK HEX: 03
-CONSTANT: LIBUSB_TRANSFER_TYPE_CONTROL 0
-CONSTANT: LIBUSB_TRANSFER_TYPE_ISOCHRONOUS 1
-CONSTANT: LIBUSB_TRANSFER_TYPE_BULK 2
-CONSTANT: LIBUSB_TRANSFER_TYPE_INTERRUPT 3
-TYPEDEF: int libusb_transfer_type
-
-CONSTANT: LIBUSB_REQUEST_GET_STATUS HEX: 00
-CONSTANT: LIBUSB_REQUEST_CLEAR_FEATURE HEX: 01
-CONSTANT: LIBUSB_REQUEST_SET_FEATURE HEX: 03
-CONSTANT: LIBUSB_REQUEST_SET_ADDRESS HEX: 05
-CONSTANT: LIBUSB_REQUEST_GET_DESCRIPTOR HEX: 06
-CONSTANT: LIBUSB_REQUEST_SET_DESCRIPTOR HEX: 07
-CONSTANT: LIBUSB_REQUEST_GET_CONFIGURATION HEX: 08
-CONSTANT: LIBUSB_REQUEST_SET_CONFIGURATION HEX: 09
-CONSTANT: LIBUSB_REQUEST_GET_INTERFACE HEX: 0A
-CONSTANT: LIBUSB_REQUEST_SET_INTERFACE HEX: 0B
-CONSTANT: LIBUSB_REQUEST_SYNCH_FRAME HEX: 0C
-TYPEDEF: int libusb_standard_request
-
-CONSTANT: LIBUSB_REQUEST_TYPE_STANDARD HEX: 00
-CONSTANT: LIBUSB_REQUEST_TYPE_CLASS HEX: 20
-CONSTANT: LIBUSB_REQUEST_TYPE_VENDOR HEX: 40
-CONSTANT: LIBUSB_REQUEST_TYPE_RESERVED HEX: 60
-
-CONSTANT: LIBUSB_RECIPIENT_DEVICE HEX: 00
-CONSTANT: LIBUSB_RECIPIENT_INTERFACE HEX: 01
-CONSTANT: LIBUSB_RECIPIENT_ENDPOINT HEX: 02
-CONSTANT: LIBUSB_RECIPIENT_OTHER HEX: 03
-TYPEDEF: int libusb_request_recipient
+C-ENUM: libusb_transfer_type
+ { LIBUSB_TRANSFER_TYPE_CONTROL 0 }
+ { LIBUSB_TRANSFER_TYPE_ISOCHRONOUS 1 }
+ { LIBUSB_TRANSFER_TYPE_BULK 2 }
+ { LIBUSB_TRANSFER_TYPE_INTERRUPT 3 } ;
+
+C-ENUM: libusb_standard_request
+ { LIBUSB_REQUEST_GET_STATUS HEX: 00 }
+ { LIBUSB_REQUEST_CLEAR_FEATURE HEX: 01 }
+ { LIBUSB_REQUEST_SET_FEATURE HEX: 03 }
+ { LIBUSB_REQUEST_SET_ADDRESS HEX: 05 }
+ { LIBUSB_REQUEST_GET_DESCRIPTOR HEX: 06 }
+ { LIBUSB_REQUEST_SET_DESCRIPTOR HEX: 07 }
+ { LIBUSB_REQUEST_GET_CONFIGURATION HEX: 08 }
+ { LIBUSB_REQUEST_SET_CONFIGURATION HEX: 09 }
+ { LIBUSB_REQUEST_GET_INTERFACE HEX: 0A }
+ { LIBUSB_REQUEST_SET_INTERFACE HEX: 0B }
+ { LIBUSB_REQUEST_SYNCH_FRAME HEX: 0C } ;
+
+C-ENUM: libusb_request_type
+ { LIBUSB_REQUEST_TYPE_STANDARD HEX: 00 }
+ { LIBUSB_REQUEST_TYPE_CLASS HEX: 20 }
+ { LIBUSB_REQUEST_TYPE_VENDOR HEX: 40 }
+ { LIBUSB_REQUEST_TYPE_RESERVED HEX: 60 } ;
+
+C-ENUM: libusb_request_recipient
+ { LIBUSB_RECIPIENT_DEVICE HEX: 00 }
+ { LIBUSB_RECIPIENT_INTERFACE HEX: 01 }
+ { LIBUSB_RECIPIENT_ENDPOINT HEX: 02 }
+ { LIBUSB_RECIPIENT_OTHER HEX: 03 } ;
CONSTANT: LIBUSB_ISO_SYNC_TYPE_MASK HEX: 0C
-CONSTANT: LIBUSB_ISO_SYNC_TYPE_NONE 0
-CONSTANT: LIBUSB_ISO_SYNC_TYPE_ASYNC 1
-CONSTANT: LIBUSB_ISO_SYNC_TYPE_ADAPTIVE 2
-CONSTANT: LIBUSB_ISO_SYNC_TYPE_SYNC 3
-TYPEDEF: int libusb_iso_sync_type
+C-ENUM: libusb_iso_sync_type
+ { LIBUSB_ISO_SYNC_TYPE_NONE 0 }
+ { LIBUSB_ISO_SYNC_TYPE_ASYNC 1 }
+ { LIBUSB_ISO_SYNC_TYPE_ADAPTIVE 2 }
+ { LIBUSB_ISO_SYNC_TYPE_SYNC 3 } ;
CONSTANT: LIBUSB_ISO_USAGE_TYPE_MASK HEX: 30
-CONSTANT: LIBUSB_ISO_USAGE_TYPE_DATA 0
-CONSTANT: LIBUSB_ISO_USAGE_TYPE_FEEDBACK 1
-CONSTANT: LIBUSB_ISO_USAGE_TYPE_IMPLICIT 2
-TYPEDEF: int libusb_iso_usage_type
+C-ENUM: libusb_iso_usage_type
+ { LIBUSB_ISO_USAGE_TYPE_DATA 0 }
+ { LIBUSB_ISO_USAGE_TYPE_FEEDBACK 1 }
+ { LIBUSB_ISO_USAGE_TYPE_IMPLICIT 2 } ;
STRUCT: libusb_device_descriptor
{ bLength uint8_t }
C-TYPE: libusb_device
C-TYPE: libusb_device_handle
-CONSTANT: LIBUSB_SUCCESS 0
-CONSTANT: LIBUSB_ERROR_IO -1
-CONSTANT: LIBUSB_ERROR_INVALID_PARAM -2
-CONSTANT: LIBUSB_ERROR_ACCESS -3
-CONSTANT: LIBUSB_ERROR_NO_DEVICE -4
-CONSTANT: LIBUSB_ERROR_NOT_FOUND -5
-CONSTANT: LIBUSB_ERROR_BUSY -6
-CONSTANT: LIBUSB_ERROR_TIMEOUT -7
-CONSTANT: LIBUSB_ERROR_OVERFLOW -8
-CONSTANT: LIBUSB_ERROR_PIPE -9
-CONSTANT: LIBUSB_ERROR_INTERRUPTED -10
-CONSTANT: LIBUSB_ERROR_NO_MEM -11
-CONSTANT: LIBUSB_ERROR_NOT_SUPPORTED -12
-CONSTANT: LIBUSB_ERROR_OTHER -99
-TYPEDEF: int libusb_error
-
-C-ENUM:
+C-ENUM: libusb_error
+ { LIBUSB_SUCCESS 0 }
+ { LIBUSB_ERROR_IO -1 }
+ { LIBUSB_ERROR_INVALID_PARAM -2 }
+ { LIBUSB_ERROR_ACCESS -3 }
+ { LIBUSB_ERROR_NO_DEVICE -4 }
+ { LIBUSB_ERROR_NOT_FOUND -5 }
+ { LIBUSB_ERROR_BUSY -6 }
+ { LIBUSB_ERROR_TIMEOUT -7 }
+ { LIBUSB_ERROR_OVERFLOW -8 }
+ { LIBUSB_ERROR_PIPE -9 }
+ { LIBUSB_ERROR_INTERRUPTED -10 }
+ { LIBUSB_ERROR_NO_MEM -11 }
+ { LIBUSB_ERROR_NOT_SUPPORTED -12 }
+ { LIBUSB_ERROR_OTHER -99 } ;
+
+C-ENUM: libusb_transfer_status
LIBUSB_TRANSFER_COMPLETED
LIBUSB_TRANSFER_ERROR
LIBUSB_TRANSFER_TIMED_OUT
LIBUSB_TRANSFER_STALL
LIBUSB_TRANSFER_NO_DEVICE
LIBUSB_TRANSFER_OVERFLOW ;
-TYPEDEF: int libusb_transfer_status
-CONSTANT: LIBUSB_TRANSFER_SHORT_NOT_OK 1
-CONSTANT: LIBUSB_TRANSFER_FREE_BUFFER 2
-CONSTANT: LIBUSB_TRANSFER_FREE_TRANSFER 4
-TYPEDEF: int libusb_transfer_flags
+C-ENUM: libusb_transfer_flags
+ { LIBUSB_TRANSFER_SHORT_NOT_OK 1 }
+ { LIBUSB_TRANSFER_FREE_BUFFER 2 }
+ { LIBUSB_TRANSFER_FREE_TRANSFER 4 } ;
STRUCT: libusb_iso_packet_descriptor
{ length uint }
! Copyright (C) 2009 Matthew Willis.
! See http://factorcode.org/license.txt for BSD license.
-USING: alien.libraries alien.syntax system sequences combinators kernel ;
+USING: alien alien.libraries alien.syntax system sequences combinators kernel alien.c-types ;
IN: llvm.core
{ [ os macosx? ] [ "/usr/local/lib/lib" ".dylib" surround ] }
{ [ os windows? ] [ ".dll" append ] }
{ [ os unix? ] [ "lib" ".so" surround ] }
- } cond "cdecl" add-library ;
+ } cond cdecl add-library ;
"LLVMSystem" add-llvm-library
"LLVMSupport" add-llvm-library
TYPEDEF: uint unsigned
TYPEDEF: unsigned enum
-CONSTANT: LLVMZExtAttribute BIN: 1
-CONSTANT: LLVMSExtAttribute BIN: 10
-CONSTANT: LLVMNoReturnAttribute BIN: 100
-CONSTANT: LLVMInRegAttribute BIN: 1000
-CONSTANT: LLVMStructRetAttribute BIN: 10000
-CONSTANT: LLVMNoUnwindAttribute BIN: 100000
-CONSTANT: LLVMNoAliasAttribute BIN: 1000000
-CONSTANT: LLVMByValAttribute BIN: 10000000
-CONSTANT: LLVMNestAttribute BIN: 100000000
-CONSTANT: LLVMReadNoneAttribute BIN: 1000000000
-CONSTANT: LLVMReadOnlyAttribute BIN: 10000000000
-TYPEDEF: enum LLVMAttribute;
-
-C-ENUM:
+C-ENUM: LLVMAttribute
+ { LLVMZExtAttribute BIN: 1 }
+ { LLVMSExtAttribute BIN: 10 }
+ { LLVMNoReturnAttribute BIN: 100 }
+ { LLVMInRegAttribute BIN: 1000 }
+ { LLVMStructRetAttribute BIN: 10000 }
+ { LLVMNoUnwindAttribute BIN: 100000 }
+ { LLVMNoAliasAttribute BIN: 1000000 }
+ { LLVMByValAttribute BIN: 10000000 }
+ { LLVMNestAttribute BIN: 100000000 }
+ { LLVMReadNoneAttribute BIN: 1000000000 }
+ { LLVMReadOnlyAttribute BIN: 10000000000 } ;
+
+C-ENUM: LLVMTypeKind
LLVMVoidTypeKind
LLVMFloatTypeKind
LLVMDoubleTypeKind
LLVMPointerTypeKind
LLVMOpaqueTypeKind
LLVMVectorTypeKind ;
-TYPEDEF: enum LLVMTypeKind
-C-ENUM:
+C-ENUM: LLVMLinkage
LLVMExternalLinkage
LLVMLinkOnceLinkage
LLVMWeakLinkage
LLVMDLLExportLinkage
LLVMExternalWeakLinkage
LLVMGhostLinkage ;
-TYPEDEF: enum LLVMLinkage
-C-ENUM:
+C-ENUM: LLVMVisibility
LLVMDefaultVisibility
LLVMHiddenVisibility
LLVMProtectedVisibility ;
-TYPEDEF: enum LLVMVisibility
-
-CONSTANT: LLVMCCallConv 0
-CONSTANT: LLVMFastCallConv 8
-CONSTANT: LLVMColdCallConv 9
-CONSTANT: LLVMX86StdcallCallConv 64
-CONSTANT: LLVMX86FastcallCallConv 65
-TYPEDEF: enum LLVMCallConv
-
-CONSTANT: LLVMIntEQ 32
-CONSTANT: LLVMIntNE 33
-CONSTANT: LLVMIntUGT 34
-CONSTANT: LLVMIntUGE 35
-CONSTANT: LLVMIntULT 36
-CONSTANT: LLVMIntULE 37
-CONSTANT: LLVMIntSGT 38
-CONSTANT: LLVMIntSGE 39
-CONSTANT: LLVMIntSLT 40
-CONSTANT: LLVMIntSLE 41
-TYPEDEF: enum LLVMIntPredicate
-
-C-ENUM:
+
+C-ENUM: LLVMCallConv
+ { LLVMCCallConv 0 }
+ { LLVMFastCallConv 8 }
+ { LLVMColdCallConv 9 }
+ { LLVMX86StdcallCallConv 64 }
+ { LLVMX86FastcallCallConv 65 } ;
+
+C-ENUM: LLVMIntPredicate
+ { LLVMIntEQ 32 }
+ { LLVMIntNE 33 }
+ { LLVMIntUGT 34 }
+ { LLVMIntUGE 35 }
+ { LLVMIntULT 36 }
+ { LLVMIntULE 37 }
+ { LLVMIntSGT 38 }
+ { LLVMIntSGE 39 }
+ { LLVMIntSLT 40 }
+ { LLVMIntSLE 41 } ;
+
+C-ENUM: LLVMRealPredicate
LLVMRealPredicateFalse
LLVMRealOEQ
LLVMRealOGT
LLVMRealULE
LLVMRealUNE
LLVMRealPredicateTrue ;
-TYPEDEF: enum LLVMRealPredicate
! Opaque Types
! Copyright (C) 2009 Matthew Willis.
! See http://factorcode.org/license.txt for BSD license.
-USING: alien.libraries alien.syntax llvm.core ;
+USING: alien.c-types alien.libraries alien.syntax llvm.core ;
IN: llvm.engine
<<
dup name>> function-pointer ,
dup return>> c-type ,
dup params>> [ second c-type ] map ,
- "cdecl" , \ alien-indirect ,
+ cdecl , \ alien-indirect ,
] [ ] make swap function-effect [ define-declared ] with-compilation-unit ;
: install-module ( name -- )
- thejit get mps>> at [
+ current-jit mps>> at [
module>> functions [ install-function ] each
] [ "no such module" throw ] if* ;
IN: llvm.jit
-SYMBOL: thejit
-
TUPLE: jit ee mps ;
: empty-engine ( -- engine )
: <jit> ( -- jit )
jit new empty-engine >>ee H{ } clone >>mps ;
+: current-jit ( -- jit )
+ \ current-jit global [ drop <jit> ] cache ;
+
: (remove-functions) ( function -- )
- thejit get ee>> value>> over LLVMFreeMachineCodeForFunction
+ current-jit ee>> value>> over LLVMFreeMachineCodeForFunction
LLVMGetNextFunction dup ALIEN: 0 = [ drop ] [ (remove-functions) ] if ;
: remove-functions ( module -- )
LLVMGetFirstFunction dup ALIEN: 0 = [ drop ] [ (remove-functions) ] if ;
: remove-provider ( provider -- )
- thejit get ee>> value>> swap value>> f <void*> f <void*>
+ current-jit ee>> value>> swap value>> f <void*> f <void*>
[ LLVMRemoveModuleProvider drop ] 2keep *void* [ llvm-throw ] when*
*void* module new swap >>value
[ value>> remove-functions ] with-disposal ;
: remove-module ( name -- )
- dup thejit get mps>> at [
+ dup current-jit mps>> at [
remove-provider
- thejit get mps>> delete-at
+ current-jit mps>> delete-at
] [ drop ] if* ;
: add-module ( module name -- )
[ <provider> ] dip [ remove-module ] keep
- thejit get ee>> value>> pick
+ current-jit ee>> value>> pick
[ [ value>> LLVMAddModuleProvider ] [ t >>disposed drop ] bi ] with-disposal
- thejit get mps>> set-at ;
+ current-jit mps>> set-at ;
: function-pointer ( name -- alien )
- thejit get ee>> value>> dup
+ current-jit ee>> value>> dup
rot f <void*> [ LLVMFindFunction drop ] keep
- *void* LLVMGetPointerToGlobal ;
-
-thejit [ <jit> ] initialize
\ No newline at end of file
+ *void* LLVMGetPointerToGlobal ;
\ No newline at end of file
bindings
-untested
+not tested
VarArgs = WhiteSpace "..." WhiteSpace => [[ drop ... ]]
ParamListContinued = "," (Type | VarArgs):t => [[ t ]]
ParamList = "(" Type:t (ParamListContinued*):ts ")" => [[ ts t prefix ]]
-Function = T:t WhiteSpace ( ParamList | NoFunctionParams ):ts => [[ ... ts member? dup [ ... ts delete ] when t ts >array rot <function> ]]
+Function = T:t WhiteSpace ( ParamList | NoFunctionParams ):ts => [[ ... ts member? dup [ ... ts remove! drop ] when t ts >array rot <function> ]]
PackedStructure = "<" WhiteSpace "{" Type:ty (StructureTypesList)*:ts "}" WhiteSpace ">" => [[ ts ty prefix >array t <struct> ]]
UpReference = "\\" Number:n => [[ n <up-ref> ]]
Name = '%' ([a-zA-Z][a-zA-Z0-9]*):id => [[ id flatten >string ]]
--- /dev/null
+Erik Charlebois
--- /dev/null
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: io io.streams.string kernel literals macho multiline strings
+tools.test ;
+IN: macho.tests
+
+STRING: validation-output
+0000000100000f1c __stub_helper stub helpers
+0000000100001040 __program_vars _pvars
+0000000100001068 __data _NXArgc
+0000000100001070 __data _NXArgv
+0000000100001080 __data ___progname
+0000000100000000 __mh_execute_header
+0000000100001078 __data _environ
+0000000100000ef8 __text _main
+0000000100000ebc __text start
+0000000000000000 ___gxx_personality_v0
+0000000000000000 _exit
+0000000000000000 _printf
+0000000000000000 dyld_stub_binder
+
+;
+
+{ $ validation-output }
+[ <string-writer> dup [ "resource:extra/macho/a.macho" macho-nm ] with-output-stream >string ]
+unit-test
--- /dev/null
+! Copyright (C) 2010 Erik Charlebois.
+! See http:// factorcode.org/license.txt for BSD license.
+USING: accessors alien alien.c-types alien.strings alien.syntax
+classes classes.struct combinators combinators.short-circuit
+io.encodings.ascii io.encodings.string kernel literals make
+math sequences specialized-arrays typed fry io.mmap formatting
+locals splitting ;
+FROM: alien.c-types => short ;
+IN: macho
+
+! FFI data
+TYPEDEF: int integer_t
+TYPEDEF: int vm_prot_t
+TYPEDEF: integer_t cpu_type_t
+TYPEDEF: integer_t cpu_subtype_t
+TYPEDEF: integer_t cpu_threadtype_t
+
+CONSTANT: VM_PROT_NONE HEX: 00
+CONSTANT: VM_PROT_READ HEX: 01
+CONSTANT: VM_PROT_WRITE HEX: 02
+CONSTANT: VM_PROT_EXECUTE HEX: 04
+CONSTANT: VM_PROT_DEFAULT HEX: 03
+CONSTANT: VM_PROT_ALL HEX: 07
+CONSTANT: VM_PROT_NO_CHANGE HEX: 08
+CONSTANT: VM_PROT_COPY HEX: 10
+CONSTANT: VM_PROT_WANTS_COPY HEX: 10
+
+! loader.h
+STRUCT: mach_header
+ { magic uint }
+ { cputype cpu_type_t }
+ { cpusubtype cpu_subtype_t }
+ { filetype uint }
+ { ncmds uint }
+ { sizeofcmds uint }
+ { flags uint } ;
+
+CONSTANT: MH_MAGIC HEX: feedface
+CONSTANT: MH_CIGAM HEX: cefaedfe
+
+STRUCT: mach_header_64
+ { magic uint }
+ { cputype cpu_type_t }
+ { cpusubtype cpu_subtype_t }
+ { filetype uint }
+ { ncmds uint }
+ { sizeofcmds uint }
+ { flags uint }
+ { reserved uint } ;
+
+CONSTANT: MH_MAGIC_64 HEX: feedfacf
+CONSTANT: MH_CIGAM_64 HEX: cffaedfe
+
+CONSTANT: MH_OBJECT HEX: 1
+CONSTANT: MH_EXECUTE HEX: 2
+CONSTANT: MH_FVMLIB HEX: 3
+CONSTANT: MH_CORE HEX: 4
+CONSTANT: MH_PRELOAD HEX: 5
+CONSTANT: MH_DYLIB HEX: 6
+CONSTANT: MH_DYLINKER HEX: 7
+CONSTANT: MH_BUNDLE HEX: 8
+CONSTANT: MH_DYLIB_STUB HEX: 9
+CONSTANT: MH_DSYM HEX: a
+CONSTANT: MH_KEXT_BUNDLE HEX: b
+
+CONSTANT: MH_NOUNDEFS HEX: 1
+CONSTANT: MH_INCRLINK HEX: 2
+CONSTANT: MH_DYLDLINK HEX: 4
+CONSTANT: MH_BINDATLOAD HEX: 8
+CONSTANT: MH_PREBOUND HEX: 10
+CONSTANT: MH_SPLIT_SEGS HEX: 20
+CONSTANT: MH_LAZY_INIT HEX: 40
+CONSTANT: MH_TWOLEVEL HEX: 80
+CONSTANT: MH_FORCE_FLAT HEX: 100
+CONSTANT: MH_NOMULTIDEFS HEX: 200
+CONSTANT: MH_NOFIXPREBINDING HEX: 400
+CONSTANT: MH_PREBINDABLE HEX: 800
+CONSTANT: MH_ALLMODSBOUND HEX: 1000
+CONSTANT: MH_SUBSECTIONS_VIA_SYMBOLS HEX: 2000
+CONSTANT: MH_CANONICAL HEX: 4000
+CONSTANT: MH_WEAK_DEFINES HEX: 8000
+CONSTANT: MH_BINDS_TO_WEAK HEX: 10000
+CONSTANT: MH_ALLOW_STACK_EXECUTION HEX: 20000
+CONSTANT: MH_DEAD_STRIPPABLE_DYLIB HEX: 400000
+CONSTANT: MH_ROOT_SAFE HEX: 40000
+CONSTANT: MH_SETUID_SAFE HEX: 80000
+CONSTANT: MH_NO_REEXPORTED_DYLIBS HEX: 100000
+CONSTANT: MH_PIE HEX: 200000
+
+STRUCT: load_command
+ { cmd uint }
+ { cmdsize uint } ;
+
+CONSTANT: LC_REQ_DYLD HEX: 80000000
+
+CONSTANT: LC_SEGMENT HEX: 1
+CONSTANT: LC_SYMTAB HEX: 2
+CONSTANT: LC_SYMSEG HEX: 3
+CONSTANT: LC_THREAD HEX: 4
+CONSTANT: LC_UNIXTHREAD HEX: 5
+CONSTANT: LC_LOADFVMLIB HEX: 6
+CONSTANT: LC_IDFVMLIB HEX: 7
+CONSTANT: LC_IDENT HEX: 8
+CONSTANT: LC_FVMFILE HEX: 9
+CONSTANT: LC_PREPAGE HEX: a
+CONSTANT: LC_DYSYMTAB HEX: b
+CONSTANT: LC_LOAD_DYLIB HEX: c
+CONSTANT: LC_ID_DYLIB HEX: d
+CONSTANT: LC_LOAD_DYLINKER HEX: e
+CONSTANT: LC_ID_DYLINKER HEX: f
+CONSTANT: LC_PREBOUND_DYLIB HEX: 10
+CONSTANT: LC_ROUTINES HEX: 11
+CONSTANT: LC_SUB_FRAMEWORK HEX: 12
+CONSTANT: LC_SUB_UMBRELLA HEX: 13
+CONSTANT: LC_SUB_CLIENT HEX: 14
+CONSTANT: LC_SUB_LIBRARY HEX: 15
+CONSTANT: LC_TWOLEVEL_HINTS HEX: 16
+CONSTANT: LC_PREBIND_CKSUM HEX: 17
+CONSTANT: LC_LOAD_WEAK_DYLIB HEX: 80000018
+CONSTANT: LC_SEGMENT_64 HEX: 19
+CONSTANT: LC_ROUTINES_64 HEX: 1a
+CONSTANT: LC_UUID HEX: 1b
+CONSTANT: LC_RPATH HEX: 8000001c
+CONSTANT: LC_CODE_SIGNATURE HEX: 1d
+CONSTANT: LC_SEGMENT_SPLIT_INFO HEX: 1e
+CONSTANT: LC_REEXPORT_DYLIB HEX: 8000001f
+CONSTANT: LC_LAZY_LOAD_DYLIB HEX: 20
+CONSTANT: LC_ENCRYPTION_INFO HEX: 21
+CONSTANT: LC_DYLD_INFO HEX: 22
+CONSTANT: LC_DYLD_INFO_ONLY HEX: 80000022
+
+UNION-STRUCT: lc_str
+ { offset uint }
+ { ptr char* } ;
+
+STRUCT: segment_command
+ { cmd uint }
+ { cmdsize uint }
+ { segname char[16] }
+ { vmaddr uint }
+ { vmsize uint }
+ { fileoff uint }
+ { filesize uint }
+ { maxprot vm_prot_t }
+ { initprot vm_prot_t }
+ { nsects uint }
+ { flags uint } ;
+
+STRUCT: segment_command_64
+ { cmd uint }
+ { cmdsize uint }
+ { segname char[16] }
+ { vmaddr ulonglong }
+ { vmsize ulonglong }
+ { fileoff ulonglong }
+ { filesize ulonglong }
+ { maxprot vm_prot_t }
+ { initprot vm_prot_t }
+ { nsects uint }
+ { flags uint } ;
+
+CONSTANT: SG_HIGHVM HEX: 1
+CONSTANT: SG_FVMLIB HEX: 2
+CONSTANT: SG_NORELOC HEX: 4
+CONSTANT: SG_PROTECTED_VERSION_1 HEX: 8
+
+STRUCT: section
+ { sectname char[16] }
+ { segname char[16] }
+ { addr uint }
+ { size uint }
+ { offset uint }
+ { align uint }
+ { reloff uint }
+ { nreloc uint }
+ { flags uint }
+ { reserved1 uint }
+ { reserved2 uint } ;
+
+STRUCT: section_64
+ { sectname char[16] }
+ { segname char[16] }
+ { addr ulonglong }
+ { size ulonglong }
+ { offset uint }
+ { align uint }
+ { reloff uint }
+ { nreloc uint }
+ { flags uint }
+ { reserved1 uint }
+ { reserved2 uint }
+ { reserved3 uint } ;
+
+CONSTANT: SECTION_TYPE HEX: 000000ff
+CONSTANT: SECTION_ATTRIBUTES HEX: ffffff00
+
+CONSTANT: S_REGULAR HEX: 0
+CONSTANT: S_ZEROFILL HEX: 1
+CONSTANT: S_CSTRING_LITERALS HEX: 2
+CONSTANT: S_4BYTE_LITERALS HEX: 3
+CONSTANT: S_8BYTE_LITERALS HEX: 4
+CONSTANT: S_LITERAL_POINTERS HEX: 5
+CONSTANT: S_NON_LAZY_SYMBOL_POINTERS HEX: 6
+CONSTANT: S_LAZY_SYMBOL_POINTERS HEX: 7
+CONSTANT: S_SYMBOL_STUBS HEX: 8
+CONSTANT: S_MOD_INIT_FUNC_POINTERS HEX: 9
+CONSTANT: S_MOD_TERM_FUNC_POINTERS HEX: a
+CONSTANT: S_COALESCED HEX: b
+CONSTANT: S_GB_ZEROFILL HEX: c
+CONSTANT: S_INTERPOSING HEX: d
+CONSTANT: S_16BYTE_LITERALS HEX: e
+CONSTANT: S_DTRACE_DOF HEX: f
+CONSTANT: S_LAZY_DYLIB_SYMBOL_POINTERS HEX: 10
+
+CONSTANT: SECTION_ATTRIBUTES_USR HEX: ff000000
+CONSTANT: S_ATTR_PURE_INSTRUCTIONS HEX: 80000000
+CONSTANT: S_ATTR_NO_TOC HEX: 40000000
+CONSTANT: S_ATTR_STRIP_STATIC_SYMS HEX: 20000000
+CONSTANT: S_ATTR_NO_DEAD_STRIP HEX: 10000000
+CONSTANT: S_ATTR_LIVE_SUPPORT HEX: 08000000
+CONSTANT: S_ATTR_SELF_MODIFYING_CODE HEX: 04000000
+CONSTANT: S_ATTR_DEBUG HEX: 02000000
+CONSTANT: SECTION_ATTRIBUTES_SYS HEX: 00ffff00
+CONSTANT: S_ATTR_SOME_INSTRUCTIONS HEX: 00000400
+CONSTANT: S_ATTR_EXT_RELOC HEX: 00000200
+CONSTANT: S_ATTR_LOC_RELOC HEX: 00000100
+
+CONSTANT: SEG_PAGEZERO "__PAGEZERO"
+CONSTANT: SEG_TEXT "__TEXT"
+CONSTANT: SECT_TEXT "__text"
+CONSTANT: SECT_FVMLIB_INIT0 "__fvmlib_init0"
+CONSTANT: SECT_FVMLIB_INIT1 "__fvmlib_init1"
+CONSTANT: SEG_DATA "__DATA"
+CONSTANT: SECT_DATA "__data"
+CONSTANT: SECT_BSS "__bss"
+CONSTANT: SECT_COMMON "__common"
+CONSTANT: SEG_OBJC "__OBJC"
+CONSTANT: SECT_OBJC_SYMBOLS "__symbol_table"
+CONSTANT: SECT_OBJC_MODULES "__module_info"
+CONSTANT: SECT_OBJC_STRINGS "__selector_strs"
+CONSTANT: SECT_OBJC_REFS "__selector_refs"
+CONSTANT: SEG_ICON "__ICON"
+CONSTANT: SECT_ICON_HEADER "__header"
+CONSTANT: SECT_ICON_TIFF "__tiff"
+CONSTANT: SEG_LINKEDIT "__LINKEDIT"
+CONSTANT: SEG_UNIXSTACK "__UNIXSTACK"
+CONSTANT: SEG_IMPORT "__IMPORT"
+
+STRUCT: fvmlib
+ { name lc_str }
+ { minor_version uint }
+ { header_addr uint } ;
+
+STRUCT: fvmlib_command
+ { cmd uint }
+ { cmdsize uint }
+ { fvmlib fvmlib } ;
+
+STRUCT: dylib
+ { name lc_str }
+ { timestamp uint }
+ { current_version uint }
+ { compatibility_version uint } ;
+
+STRUCT: dylib_command
+ { cmd uint }
+ { cmdsize uint }
+ { dylib dylib } ;
+
+STRUCT: sub_framework_command
+ { cmd uint }
+ { cmdsize uint }
+ { umbrella lc_str } ;
+
+STRUCT: sub_client_command
+ { cmd uint }
+ { cmdsize uint }
+ { client lc_str } ;
+
+STRUCT: sub_umbrella_command
+ { cmd uint }
+ { cmdsize uint }
+ { sub_umbrella lc_str } ;
+
+STRUCT: sub_library_command
+ { cmd uint }
+ { cmdsize uint }
+ { sub_library lc_str } ;
+
+STRUCT: prebound_dylib_command
+ { cmd uint }
+ { cmdsize uint }
+ { name lc_str }
+ { nmodules uint }
+ { linked_modules lc_str } ;
+
+STRUCT: dylinker_command
+ { cmd uint }
+ { cmdsize uint }
+ { name lc_str } ;
+
+STRUCT: thread_command
+ { cmd uint }
+ { cmdsize uint } ;
+
+STRUCT: routines_command
+ { cmd uint }
+ { cmdsize uint }
+ { init_address uint }
+ { init_module uint }
+ { reserved1 uint }
+ { reserved2 uint }
+ { reserved3 uint }
+ { reserved4 uint }
+ { reserved5 uint }
+ { reserved6 uint } ;
+
+STRUCT: routines_command_64
+ { cmd uint }
+ { cmdsize uint }
+ { init_address ulonglong }
+ { init_module ulonglong }
+ { reserved1 ulonglong }
+ { reserved2 ulonglong }
+ { reserved3 ulonglong }
+ { reserved4 ulonglong }
+ { reserved5 ulonglong }
+ { reserved6 ulonglong } ;
+
+STRUCT: symtab_command
+ { cmd uint }
+ { cmdsize uint }
+ { symoff uint }
+ { nsyms uint }
+ { stroff uint }
+ { strsize uint } ;
+
+STRUCT: dysymtab_command
+ { cmd uint }
+ { cmdsize uint }
+ { ilocalsym uint }
+ { nlocalsym uint }
+ { iextdefsym uint }
+ { nextdefsym uint }
+ { iundefsym uint }
+ { nundefsym uint }
+ { tocoff uint }
+ { ntoc uint }
+ { modtaboff uint }
+ { nmodtab uint }
+ { extrefsymoff uint }
+ { nextrefsyms uint }
+ { indirectsymoff uint }
+ { nindirectsyms uint }
+ { extreloff uint }
+ { nextrel uint }
+ { locreloff uint }
+ { nlocrel uint } ;
+
+CONSTANT: INDIRECT_SYMBOL_LOCAL HEX: 80000000
+CONSTANT: INDIRECT_SYMBOL_ABS HEX: 40000000
+
+STRUCT: dylib_table_of_contents
+ { symbol_index uint }
+ { module_index uint } ;
+
+STRUCT: dylib_module
+ { module_name uint }
+ { iextdefsym uint }
+ { nextdefsym uint }
+ { irefsym uint }
+ { nrefsym uint }
+ { ilocalsym uint }
+ { nlocalsym uint }
+ { iextrel uint }
+ { nextrel uint }
+ { iinit_iterm uint }
+ { ninit_nterm uint }
+ { objc_module_info_addr uint }
+ { objc_module_info_size uint } ;
+
+STRUCT: dylib_module_64
+ { module_name uint }
+ { iextdefsym uint }
+ { nextdefsym uint }
+ { irefsym uint }
+ { nrefsym uint }
+ { ilocalsym uint }
+ { nlocalsym uint }
+ { iextrel uint }
+ { nextrel uint }
+ { iinit_iterm uint }
+ { ninit_nterm uint }
+ { objc_module_info_size uint }
+ { objc_module_info_addr ulonglong } ;
+
+STRUCT: dylib_reference
+ { isym_flags uint } ;
+
+STRUCT: twolevel_hints_command
+ { cmd uint }
+ { cmdsize uint }
+ { offset uint }
+ { nhints uint } ;
+
+STRUCT: twolevel_hint
+ { isub_image_itoc uint } ;
+
+STRUCT: prebind_cksum_command
+ { cmd uint }
+ { cmdsize uint }
+ { cksum uint } ;
+
+STRUCT: uuid_command
+ { cmd uint }
+ { cmdsize uint }
+ { uuid uchar[16] } ;
+
+STRUCT: rpath_command
+ { cmd uint }
+ { cmdsize uint }
+ { path lc_str } ;
+
+STRUCT: linkedit_data_command
+ { cmd uint }
+ { cmdsize uint }
+ { dataoff uint }
+ { datasize uint } ;
+
+STRUCT: encryption_info_command
+ { cmd uint }
+ { cmdsize uint }
+ { cryptoff uint }
+ { cryptsize uint }
+ { cryptid uint } ;
+
+STRUCT: dyld_info_command
+ { cmd uint }
+ { cmdsize uint }
+ { rebase_off uint }
+ { rebase_size uint }
+ { bind_off uint }
+ { bind_size uint }
+ { weak_bind_off uint }
+ { weak_bind_size uint }
+ { lazy_bind_off uint }
+ { lazy_bind_size uint }
+ { export_off uint }
+ { export_size uint } ;
+
+CONSTANT: REBASE_TYPE_POINTER 1
+CONSTANT: REBASE_TYPE_TEXT_ABSOLUTE32 2
+CONSTANT: REBASE_TYPE_TEXT_PCREL32 3
+
+CONSTANT: REBASE_OPCODE_MASK HEX: F0
+CONSTANT: REBASE_IMMEDIATE_MASK HEX: 0F
+CONSTANT: REBASE_OPCODE_DONE HEX: 00
+CONSTANT: REBASE_OPCODE_SET_TYPE_IMM HEX: 10
+CONSTANT: REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB HEX: 20
+CONSTANT: REBASE_OPCODE_ADD_ADDR_ULEB HEX: 30
+CONSTANT: REBASE_OPCODE_ADD_ADDR_IMM_SCALED HEX: 40
+CONSTANT: REBASE_OPCODE_DO_REBASE_IMM_TIMES HEX: 50
+CONSTANT: REBASE_OPCODE_DO_REBASE_ULEB_TIMES HEX: 60
+CONSTANT: REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB HEX: 70
+CONSTANT: REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB HEX: 80
+
+CONSTANT: BIND_TYPE_POINTER 1
+CONSTANT: BIND_TYPE_TEXT_ABSOLUTE32 2
+CONSTANT: BIND_TYPE_TEXT_PCREL32 3
+
+CONSTANT: BIND_SPECIAL_DYLIB_SELF 0
+CONSTANT: BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE -1
+CONSTANT: BIND_SPECIAL_DYLIB_FLAT_LOOKUP -2
+
+CONSTANT: BIND_SYMBOL_FLAGS_WEAK_IMPORT HEX: 1
+CONSTANT: BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION HEX: 8
+
+CONSTANT: BIND_OPCODE_MASK HEX: F0
+CONSTANT: BIND_IMMEDIATE_MASK HEX: 0F
+CONSTANT: BIND_OPCODE_DONE HEX: 00
+CONSTANT: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM HEX: 10
+CONSTANT: BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB HEX: 20
+CONSTANT: BIND_OPCODE_SET_DYLIB_SPECIAL_IMM HEX: 30
+CONSTANT: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM HEX: 40
+CONSTANT: BIND_OPCODE_SET_TYPE_IMM HEX: 50
+CONSTANT: BIND_OPCODE_SET_ADDEND_SLEB HEX: 60
+CONSTANT: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB HEX: 70
+CONSTANT: BIND_OPCODE_ADD_ADDR_ULEB HEX: 80
+CONSTANT: BIND_OPCODE_DO_BIND HEX: 90
+CONSTANT: BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB HEX: A0
+CONSTANT: BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED HEX: B0
+CONSTANT: BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB HEX: C0
+
+CONSTANT: EXPORT_SYMBOL_FLAGS_KIND_MASK HEX: 03
+CONSTANT: EXPORT_SYMBOL_FLAGS_KIND_REGULAR HEX: 00
+CONSTANT: EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL HEX: 01
+CONSTANT: EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION HEX: 04
+CONSTANT: EXPORT_SYMBOL_FLAGS_INDIRECT_DEFINITION HEX: 08
+CONSTANT: EXPORT_SYMBOL_FLAGS_HAS_SPECIALIZATIONS HEX: 10
+
+STRUCT: symseg_command
+ { cmd uint }
+ { cmdsize uint }
+ { offset uint }
+ { size uint } ;
+
+STRUCT: ident_command
+ { cmd uint }
+ { cmdsize uint } ;
+
+STRUCT: fvmfile_command
+ { cmd uint }
+ { cmdsize uint }
+ { name lc_str }
+ { header_addr uint } ;
+
+! machine.h
+CONSTANT: CPU_STATE_MAX 4
+CONSTANT: CPU_STATE_USER 0
+CONSTANT: CPU_STATE_SYSTEM 1
+CONSTANT: CPU_STATE_IDLE 2
+CONSTANT: CPU_STATE_NICE 3
+
+CONSTANT: CPU_ARCH_MASK HEX: ff000000
+CONSTANT: CPU_ARCH_ABI64 HEX: 01000000
+
+CONSTANT: CPU_TYPE_ANY -1
+CONSTANT: CPU_TYPE_VAX 1
+CONSTANT: CPU_TYPE_MC680x0 6
+CONSTANT: CPU_TYPE_X86 7
+ALIAS: CPU_TYPE_I386 CPU_TYPE_X86
+CONSTANT: CPU_TYPE_X86_64 flags{ CPU_TYPE_X86 CPU_ARCH_ABI64 }
+CONSTANT: CPU_TYPE_MC98000 10
+CONSTANT: CPU_TYPE_HPPA 11
+CONSTANT: CPU_TYPE_ARM 12
+CONSTANT: CPU_TYPE_MC88000 13
+CONSTANT: CPU_TYPE_SPARC 14
+CONSTANT: CPU_TYPE_I860 15
+CONSTANT: CPU_TYPE_POWERPC 18
+CONSTANT: CPU_TYPE_POWERPC64 flags{ CPU_TYPE_POWERPC CPU_ARCH_ABI64 }
+
+CONSTANT: CPU_SUBTYPE_MASK HEX: ff000000
+CONSTANT: CPU_SUBTYPE_LIB64 HEX: 80000000
+
+CONSTANT: CPU_SUBTYPE_MULTIPLE -1
+CONSTANT: CPU_SUBTYPE_LITTLE_ENDIAN 0
+CONSTANT: CPU_SUBTYPE_BIG_ENDIAN 1
+
+CONSTANT: CPU_THREADTYPE_NONE 0
+
+CONSTANT: CPU_SUBTYPE_VAX_ALL 0
+CONSTANT: CPU_SUBTYPE_VAX780 1
+CONSTANT: CPU_SUBTYPE_VAX785 2
+CONSTANT: CPU_SUBTYPE_VAX750 3
+CONSTANT: CPU_SUBTYPE_VAX730 4
+CONSTANT: CPU_SUBTYPE_UVAXI 5
+CONSTANT: CPU_SUBTYPE_UVAXII 6
+CONSTANT: CPU_SUBTYPE_VAX8200 7
+CONSTANT: CPU_SUBTYPE_VAX8500 8
+CONSTANT: CPU_SUBTYPE_VAX8600 9
+CONSTANT: CPU_SUBTYPE_VAX8650 10
+CONSTANT: CPU_SUBTYPE_VAX8800 11
+CONSTANT: CPU_SUBTYPE_UVAXIII 12
+
+CONSTANT: CPU_SUBTYPE_MC680x0_ALL 1
+CONSTANT: CPU_SUBTYPE_MC68030 1
+CONSTANT: CPU_SUBTYPE_MC68040 2
+CONSTANT: CPU_SUBTYPE_MC68030_ONLY 3
+
+: CPU_SUBTYPE_INTEL ( f m -- subtype ) 4 shift + ; inline
+
+CONSTANT: CPU_SUBTYPE_I386_ALL 3
+CONSTANT: CPU_SUBTYPE_386 3
+CONSTANT: CPU_SUBTYPE_486 4
+CONSTANT: CPU_SUBTYPE_486SX 132
+CONSTANT: CPU_SUBTYPE_586 5
+CONSTANT: CPU_SUBTYPE_PENT 5
+CONSTANT: CPU_SUBTYPE_PENTPRO 22
+CONSTANT: CPU_SUBTYPE_PENTII_M3 54
+CONSTANT: CPU_SUBTYPE_PENTII_M5 86
+CONSTANT: CPU_SUBTYPE_CELERON 103
+CONSTANT: CPU_SUBTYPE_CELERON_MOBILE 119
+CONSTANT: CPU_SUBTYPE_PENTIUM_3 8
+CONSTANT: CPU_SUBTYPE_PENTIUM_3_M 24
+CONSTANT: CPU_SUBTYPE_PENTIUM_3_XEON 40
+CONSTANT: CPU_SUBTYPE_PENTIUM_M 9
+CONSTANT: CPU_SUBTYPE_PENTIUM_4 10
+CONSTANT: CPU_SUBTYPE_PENTIUM_4_M 26
+CONSTANT: CPU_SUBTYPE_ITANIUM 11
+CONSTANT: CPU_SUBTYPE_ITANIUM_2 27
+CONSTANT: CPU_SUBTYPE_XEON 12
+CONSTANT: CPU_SUBTYPE_XEON_MP 28
+
+: CPU_SUBTYPE_INTEL_FAMILY ( x -- family ) 15 bitand ; inline
+
+CONSTANT: CPU_SUBTYPE_INTEL_FAMILY_MAX 15
+
+: CPU_SUBTYPE_INTEL_MODEL ( x -- model ) -4 shift ; inline
+
+CONSTANT: CPU_SUBTYPE_INTEL_MODEL_ALL 0
+CONSTANT: CPU_SUBTYPE_X86_ALL 3
+CONSTANT: CPU_SUBTYPE_X86_64_ALL 3
+CONSTANT: CPU_SUBTYPE_X86_ARCH1 4
+CONSTANT: CPU_THREADTYPE_INTEL_HTT 1
+
+CONSTANT: CPU_SUBTYPE_MIPS_ALL 0
+CONSTANT: CPU_SUBTYPE_MIPS_R2300 1
+CONSTANT: CPU_SUBTYPE_MIPS_R2600 2
+CONSTANT: CPU_SUBTYPE_MIPS_R2800 3
+CONSTANT: CPU_SUBTYPE_MIPS_R2000a 4
+CONSTANT: CPU_SUBTYPE_MIPS_R2000 5
+CONSTANT: CPU_SUBTYPE_MIPS_R3000a 6
+CONSTANT: CPU_SUBTYPE_MIPS_R3000 7
+
+CONSTANT: CPU_SUBTYPE_MC98000_ALL 0
+CONSTANT: CPU_SUBTYPE_MC98601 1
+
+CONSTANT: CPU_SUBTYPE_HPPA_ALL 0
+CONSTANT: CPU_SUBTYPE_HPPA_7100 0
+CONSTANT: CPU_SUBTYPE_HPPA_7100LC 1
+
+CONSTANT: CPU_SUBTYPE_MC88000_ALL 0
+CONSTANT: CPU_SUBTYPE_MC88100 1
+CONSTANT: CPU_SUBTYPE_MC88110 2
+
+CONSTANT: CPU_SUBTYPE_SPARC_ALL 0
+
+CONSTANT: CPU_SUBTYPE_I860_ALL 0
+CONSTANT: CPU_SUBTYPE_I860_860 1
+
+CONSTANT: CPU_SUBTYPE_POWERPC_ALL 0
+CONSTANT: CPU_SUBTYPE_POWERPC_601 1
+CONSTANT: CPU_SUBTYPE_POWERPC_602 2
+CONSTANT: CPU_SUBTYPE_POWERPC_603 3
+CONSTANT: CPU_SUBTYPE_POWERPC_603e 4
+CONSTANT: CPU_SUBTYPE_POWERPC_603ev 5
+CONSTANT: CPU_SUBTYPE_POWERPC_604 6
+CONSTANT: CPU_SUBTYPE_POWERPC_604e 7
+CONSTANT: CPU_SUBTYPE_POWERPC_620 8
+CONSTANT: CPU_SUBTYPE_POWERPC_750 9
+CONSTANT: CPU_SUBTYPE_POWERPC_7400 10
+CONSTANT: CPU_SUBTYPE_POWERPC_7450 11
+CONSTANT: CPU_SUBTYPE_POWERPC_970 100
+
+CONSTANT: CPU_SUBTYPE_ARM_ALL 0
+CONSTANT: CPU_SUBTYPE_ARM_V4T 5
+CONSTANT: CPU_SUBTYPE_ARM_V6 6
+CONSTANT: CPU_SUBTYPE_ARM_V5TEJ 7
+CONSTANT: CPU_SUBTYPE_ARM_XSCALE 8
+CONSTANT: CPU_SUBTYPE_ARM_V7 9
+
+CONSTANT: CPUFAMILY_UNKNOWN 0
+CONSTANT: CPUFAMILY_POWERPC_G3 HEX: cee41549
+CONSTANT: CPUFAMILY_POWERPC_G4 HEX: 77c184ae
+CONSTANT: CPUFAMILY_POWERPC_G5 HEX: ed76d8aa
+CONSTANT: CPUFAMILY_INTEL_6_13 HEX: aa33392b
+CONSTANT: CPUFAMILY_INTEL_6_14 HEX: 73d67300
+CONSTANT: CPUFAMILY_INTEL_6_15 HEX: 426f69ef
+CONSTANT: CPUFAMILY_INTEL_6_23 HEX: 78ea4fbc
+CONSTANT: CPUFAMILY_INTEL_6_26 HEX: 6b5a4cd2
+CONSTANT: CPUFAMILY_ARM_9 HEX: e73283ae
+CONSTANT: CPUFAMILY_ARM_11 HEX: 8ff620d8
+CONSTANT: CPUFAMILY_ARM_XSCALE HEX: 53b005f5
+CONSTANT: CPUFAMILY_ARM_13 HEX: 0cc90e64
+
+ALIAS: CPUFAMILY_INTEL_YONAH CPUFAMILY_INTEL_6_14
+ALIAS: CPUFAMILY_INTEL_MEROM CPUFAMILY_INTEL_6_15
+ALIAS: CPUFAMILY_INTEL_PENRYN CPUFAMILY_INTEL_6_23
+ALIAS: CPUFAMILY_INTEL_NEHALEM CPUFAMILY_INTEL_6_26
+
+ALIAS: CPUFAMILY_INTEL_CORE CPUFAMILY_INTEL_6_14
+ALIAS: CPUFAMILY_INTEL_CORE2 CPUFAMILY_INTEL_6_15
+
+! fat.h
+CONSTANT: FAT_MAGIC HEX: cafebabe
+CONSTANT: FAT_CIGAM HEX: bebafeca
+
+STRUCT: fat_header
+ { magic uint }
+ { nfat_arch uint } ;
+
+STRUCT: fat_arch
+ { cputype cpu_type_t }
+ { cpusubtype cpu_subtype_t }
+ { offset uint }
+ { size uint }
+ { align uint } ;
+
+! nlist.h
+STRUCT: nlist
+ { n_strx int }
+ { n_type uchar }
+ { n_sect uchar }
+ { n_desc short }
+ { n_value uint } ;
+
+STRUCT: nlist_64
+ { n_strx uint }
+ { n_type uchar }
+ { n_sect uchar }
+ { n_desc ushort }
+ { n_value ulonglong } ;
+
+CONSTANT: N_STAB HEX: e0
+CONSTANT: N_PEXT HEX: 10
+CONSTANT: N_TYPE HEX: 0e
+CONSTANT: N_EXT HEX: 01
+
+CONSTANT: N_UNDF HEX: 0
+CONSTANT: N_ABS HEX: 2
+CONSTANT: N_SECT HEX: e
+CONSTANT: N_PBUD HEX: c
+CONSTANT: N_INDR HEX: a
+
+CONSTANT: NO_SECT 0
+CONSTANT: MAX_SECT 255
+
+: GET_COMM_ALIGN ( n_desc -- align )
+ -8 shift HEX: 0f bitand ; inline
+
+: SET_COMM_ALIGN ( n_desc align -- n_desc )
+ [ HEX: f0ff bitand ]
+ [ HEX: 000f bitand 8 shift ] bi* bitor ; inline
+
+CONSTANT: REFERENCE_TYPE 7
+CONSTANT: REFERENCE_FLAG_UNDEFINED_NON_LAZY 0
+CONSTANT: REFERENCE_FLAG_UNDEFINED_LAZY 1
+CONSTANT: REFERENCE_FLAG_DEFINED 2
+CONSTANT: REFERENCE_FLAG_PRIVATE_DEFINED 3
+CONSTANT: REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY 4
+CONSTANT: REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY 5
+
+CONSTANT: REFERENCED_DYNAMICALLY HEX: 0010
+
+: GET_LIBRARY_ORDINAL ( n_desc -- ordinal )
+ -8 shift HEX: ff bitand ; inline
+
+: SET_LIBRARY_ORDINAL ( n_desc ordinal -- n_desc )
+ [ HEX: 00ff bitand ]
+ [ HEX: 00ff bitand 8 shift ] bi* bitor ; inline
+
+CONSTANT: SELF_LIBRARY_ORDINAL HEX: 0
+CONSTANT: MAX_LIBRARY_ORDINAL HEX: fd
+CONSTANT: DYNAMIC_LOOKUP_ORDINAL HEX: fe
+CONSTANT: EXECUTABLE_ORDINAL HEX: ff
+
+CONSTANT: N_NO_DEAD_STRIP HEX: 0020
+CONSTANT: N_DESC_DISCARDED HEX: 0020
+CONSTANT: N_WEAK_REF HEX: 0040
+CONSTANT: N_WEAK_DEF HEX: 0080
+CONSTANT: N_REF_TO_WEAK HEX: 0080
+CONSTANT: N_ARM_THUMB_DEF HEX: 0008
+
+! ranlib.h
+CONSTANT: SYMDEF "__.SYMDEF"
+CONSTANT: SYMDEF_SORTED "__.SYMDEF SORTED"
+
+STRUCT: ranlib
+ { ran_strx uint }
+ { ran_off uint } ;
+
+! reloc.h
+STRUCT: relocation_info
+ { r_address int }
+ { r_symbolnum_pcrel_length_extern_type uint } ;
+
+CONSTANT: R_ABS 0
+CONSTANT: R_SCATTERED HEX: 80000000
+
+STRUCT: scattered_relocation_info_big_endian
+ { r_scattered_pcrel_length_type_address uint }
+ { r_value int } ;
+
+STRUCT: scattered_relocation_info_little_endian
+ { r_address_type_length_pcrel_scattered uint }
+ { r_value int } ;
+
+C-ENUM: reloc_type_generic
+ GENERIC_RELOC_VANILLA
+ GENERIC_RELOC_PAIR
+ GENERIC_RELOC_SECTDIFF
+ GENERIC_RELOC_PB_LA_PTR
+ GENERIC_RELOC_LOCAL_SECTDIFF ;
+
+C-ENUM: reloc_type_x86_64
+ X86_64_RELOC_UNSIGNED
+ X86_64_RELOC_SIGNED
+ X86_64_RELOC_BRANCH
+ X86_64_RELOC_GOT_LOAD
+ X86_64_RELOC_GOT
+ X86_64_RELOC_SUBTRACTOR
+ X86_64_RELOC_SIGNED_1
+ X86_64_RELOC_SIGNED_2
+ X86_64_RELOC_SIGNED_4 ;
+
+C-ENUM: reloc_type_ppc
+ PPC_RELOC_VANILLA
+ PPC_RELOC_PAIR
+ PPC_RELOC_BR14
+ PPC_RELOC_BR24
+ PPC_RELOC_HI16
+ PPC_RELOC_LO16
+ PPC_RELOC_HA16
+ PPC_RELOC_LO14
+ PPC_RELOC_SECTDIFF
+ PPC_RELOC_PB_LA_PTR
+ PPC_RELOC_HI16_SECTDIFF
+ PPC_RELOC_LO16_SECTDIFF
+ PPC_RELOC_HA16_SECTDIFF
+ PPC_RELOC_JBSR
+ PPC_RELOC_LO14_SECTDIFF
+ PPC_RELOC_LOCAL_SECTDIFF ;
+
+! Low-level interface
+SPECIALIZED-ARRAYS: section section_64 nlist nlist_64 ;
+UNION: mach_header_32/64 mach_header mach_header_64 ;
+UNION: segment_command_32/64 segment_command segment_command_64 ;
+UNION: load-command segment_command segment_command_64
+ dylib_command sub_framework_command
+ sub_client_command sub_umbrella_command sub_library_command
+ prebound_dylib_command dylinker_command thread_command
+ routines_command routines_command_64 symtab_command
+ dysymtab_command twolevel_hints_command uuid_command ;
+UNION: section_32/64 section section_64 ;
+UNION: section_32/64-array section-array section_64-array ;
+UNION: nlist_32/64 nlist nlist_64 ;
+UNION: nlist_32/64-array nlist-array nlist_64-array ;
+
+TYPED: 64-bit? ( macho: mach_header_32/64 -- ? )
+ magic>> {
+ { MH_MAGIC_64 [ t ] }
+ { MH_CIGAM_64 [ t ] }
+ [ drop f ]
+ } case ;
+
+TYPED: macho-header ( c-ptr -- macho: mach_header_32/64 )
+ dup mach_header_64 memory>struct 64-bit?
+ [ mach_header_64 memory>struct ]
+ [ mach_header memory>struct ] if ;
+
+: cmd>load-command ( cmd -- load-command )
+ {
+ { LC_UUID [ uuid_command ] }
+ { LC_SEGMENT [ segment_command ] }
+ { LC_SEGMENT_64 [ segment_command_64 ] }
+ { LC_SYMTAB [ symtab_command ] }
+ { LC_DYSYMTAB [ dysymtab_command ] }
+ { LC_THREAD [ thread_command ] }
+ { LC_UNIXTHREAD [ thread_command ] }
+ { LC_LOAD_DYLIB [ dylib_command ] }
+ { LC_ID_DYLIB [ dylib_command ] }
+ { LC_PREBOUND_DYLIB [ prebound_dylib_command ] }
+ { LC_LOAD_DYLINKER [ dylinker_command ] }
+ { LC_ID_DYLINKER [ dylinker_command ] }
+ { LC_ROUTINES [ routines_command ] }
+ { LC_ROUTINES_64 [ routines_command_64 ] }
+ { LC_TWOLEVEL_HINTS [ twolevel_hints_command ] }
+ { LC_SUB_FRAMEWORK [ sub_framework_command ] }
+ { LC_SUB_UMBRELLA [ sub_umbrella_command ] }
+ { LC_SUB_LIBRARY [ sub_library_command ] }
+ { LC_SUB_CLIENT [ sub_client_command ] }
+ { LC_DYLD_INFO [ dyld_info_command ] }
+ { LC_DYLD_INFO_ONLY [ dyld_info_command ] }
+ } case ;
+
+: read-command ( cmd -- next-cmd )
+ dup load_command memory>struct
+ [ cmd>> cmd>load-command memory>struct , ]
+ [ cmdsize>> swap <displaced-alien> ] 2bi ;
+
+TYPED: load-commands ( macho: mach_header_32/64 -- load-commands )
+ [
+ [ class heap-size ]
+ [ >c-ptr <displaced-alien> ]
+ [ ncmds>> ] tri iota [
+ drop read-command
+ ] each drop
+ ] { } make ;
+
+: segment-commands ( load-commands -- segment-commands )
+ [ segment_command_32/64? ] filter ; inline
+
+: symtab-commands ( load-commands -- segment-commands )
+ [ symtab_command? ] filter ; inline
+
+: read-array-string ( uchar-array -- string )
+ ascii decode [ 0 = not ] filter ;
+
+: segment-sections ( segment-command -- sections )
+ {
+ [ class heap-size ]
+ [ >c-ptr <displaced-alien> ]
+ [ nsects>> ]
+ [ segment_command_64? ]
+ } cleave
+ [ <direct-section_64-array> ]
+ [ <direct-section-array> ] if ;
+
+: sections-array ( segment-commands -- sections-array )
+ [
+ dup first segment_command_64?
+ [ section_64 ] [ section ] if <struct> ,
+ segment-commands [ segment-sections [ , ] each ] each
+ ] { } make ;
+
+: symbols ( mach-header symtab-command -- symbols string-table )
+ [ symoff>> swap >c-ptr <displaced-alien> ]
+ [ nsyms>> swap 64-bit?
+ [ <direct-nlist_64-array> ]
+ [ <direct-nlist-array> ] if ]
+ [ stroff>> swap >c-ptr <displaced-alien> ] 2tri ;
+
+: symbol-name ( symbol string-table -- name )
+ [ n_strx>> ] dip <displaced-alien> ascii alien>string ;
+
+: c-symbol-name ( symbol string-table -- name )
+ symbol-name "_" ?head drop ;
+
+: with-mapped-macho ( path quot -- )
+ '[
+ address>> macho-header @
+ ] with-mapped-file-reader ; inline
+
+: macho-nm ( path -- )
+ [| macho |
+ macho load-commands segment-commands sections-array :> sections
+
+ macho load-commands symtab-commands [| symtab |
+ macho symtab symbols [
+ [ drop n_value>> "%016x " printf ]
+ [ drop n_sect>> sections nth sectname>>
+ read-array-string "%-16s" printf ]
+ [ symbol-name "%s\n" printf ] 2tri
+ ] curry each
+ ] each
+ ] with-mapped-macho ;
+
+: dylib-export? ( symtab-entry -- ? )
+ n_type>> {
+ [ N_EXT bitand zero? not ]
+ [ N_TYPE bitand N_UNDF = not ]
+ } 1&& ;
+
+: dylib-exports ( path -- symbol-names )
+ [| macho |
+ macho load-commands symtab-commands [| symtab |
+ macho symtab symbols
+ [ [ dylib-export? ] filter ]
+ [ [ c-symbol-name ] curry { } map-as ] bi*
+ ] { } map-as concat
+ ] with-mapped-macho ;
--- /dev/null
+Constants and structs related to the Mach object format.
IN: mason.child.tests
USING: mason.child mason.config tools.test namespaces io kernel sequences ;
-[ { "nmake" "/f" "nmakefile" } ] [
+[ { "nmake" "/f" "nmakefile" "x86-32" } ] [
[
"winnt" target-os set
"x86.32" target-cpu set
continuations debugger io.directories io.files io.launcher
io.pathnames io.encodings.ascii kernel make mason.common mason.config
mason.platform mason.report mason.notify namespaces sequences
-quotations macros system combinators ;
+quotations macros system combinators splitting ;
IN: mason.child
+: nmake-cmd ( -- args )
+ { "nmake" "/f" "nmakefile" }
+ target-cpu get "." split "-" join suffix ;
+
+: gnu-make-cmd ( -- args )
+ gnu-make platform 2array ;
+
: make-cmd ( -- args )
{
- { [ target-os get "winnt" = ] [ { "nmake" "/f" "nmakefile" } ] }
- [ gnu-make platform 2array ]
+ { [ target-os get "winnt" = ] [ nmake-cmd ] }
+ [ gnu-make-cmd ]
} cond ;
: make-vm ( -- )
"linux" target-os set
"x86.64" target-cpu set
"12345" current-git-id set
- status-error subject prefix-subject
+ status-error report-subject
] with-scope
] unit-test
-! Copyright (C) 2008, 2009 Eduardo Cavazos, Slava Pestov.
+! Copyright (C) 2008, 2010 Eduardo Cavazos, Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel namespaces accessors combinators make smtp debugger
prettyprint sequences io io.streams.string io.encodings.utf8 io.files
io.sockets mason.common mason.platform mason.config ;
IN: mason.email
-: prefix-subject ( str -- str' )
- [ "mason on " % platform % ": " % % ] "" make ;
-
-: email-status ( body content-type subject -- )
+: mason-email ( body content-type subject -- )
<email>
builder-from get >>from
builder-recipients get >>to
- swap prefix-subject >>subject
+ swap >>subject
swap >>content-type
swap >>body
send-email ;
-: subject ( status -- str )
- [ current-git-id get 7 short head " -- " ] dip {
- { status-clean [ "clean" ] }
- { status-dirty [ "dirty" ] }
- { status-error [ "error" ] }
- } case 3append ;
+: subject-prefix ( -- string )
+ "mason on " platform ": " 3append ;
+
+: report-subject ( status -- string )
+ [
+ subject-prefix %
+ current-git-id get 7 short head %
+ " -- " %
+ {
+ { status-clean [ "clean" ] }
+ { status-dirty [ "dirty" ] }
+ { status-error [ "error" ] }
+ } case %
+ ] "" make ;
: email-report ( report status -- )
- [ "text/html" ] dip subject email-status ;
+ [ "text/html" ] dip report-subject mason-email ;
: email-error ( error callstack -- )
[
"Fatal error on " write host-name print nl
[ error. ] [ callstack. ] bi*
- ] with-string-writer "text/plain" "fatal error"
- email-status ;
+ ] with-string-writer
+ "text/plain"
+ subject-prefix "fatal error" append
+ mason-email ;
-! Copyright (C) 2008 Eduardo Cavazos, Slava Pestov.
+! Copyright (C) 2008, 2010 Eduardo Cavazos, Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors calendar continuations debugger io
io.directories io.files kernel mason.common
-mason.email mason.updates namespaces threads ;
+mason.email mason.updates mason.notify namespaces threads ;
FROM: mason.build => build ;
IN: mason
: build-loop ( -- )
?prepare-build-machine
[
+ notify-heartbeat
[
builds/factor set-current-directory
new-code-available? [ build ] when
-! Copyright (C) 2009 Slava Pestov.
+! Copyright (C) 2009, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: arrays accessors io io.sockets io.encodings.utf8 io.files
io.launcher kernel make mason.config mason.common mason.email
] retry
] [ 2drop ] if ;
+: notify-heartbeat ( -- )
+ f { "heartbeat" } status-notify ;
+
: notify-begin-build ( git-id -- )
[ "Starting build of GIT ID " write print flush ]
[ f swap "git-id" swap 2array status-notify ]
target-cpu get >>cpu
dup select-tuple [ ] [ dup insert-tuple ] ?if ;
-: git-id ( builder id -- )
- >>current-git-id +starting+ >>status drop ;
+: heartbeat ( builder -- ) now >>heartbeat-timestamp drop ;
+
+: git-id ( builder id -- ) >>current-git-id +starting+ >>status drop ;
: make-vm ( builder -- ) +make-vm+ >>status drop ;
: update-builder ( builder -- )
message get {
+ { "heartbeat" [ heartbeat ] }
{ "git-id" [ message-arg get git-id ] }
{ "make-vm" [ make-vm ] }
{ "boot" [ boot ] }
+++ /dev/null
-Slava Pestov
\ No newline at end of file
+++ /dev/null
-! Copyright (C) 2010 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors calendar db db.tuples db.types grouping io
-io.encodings.ascii io.launcher kernel locals make
-mason.release.archive mason.config mason.platform mason.server
-namespaces sequences ;
-IN: mason.server.release
-
-: platform ( builder -- string )
- [ os>> ] [ cpu>> ] bi (platform) ;
-
-: package-name ( builder -- string )
- [ platform ] [ last-release>> ] bi "/" glue ;
-
-: release-name ( version builder -- string )
- [
- "releases/" %
- over % "/" %
- [ "factor-" % platform % "-" % % ]
- [ os>> extension % ]
- bi
- ] "" make ;
-
-: release-command ( version builder -- command )
- [
- "cp " %
- [ nip package-name % " " % ] [ release-name % ] 2bi
- ] "" make ;
-
-TUPLE: release
-host-name os cpu
-last-release release-git-id ;
-
-release "RELEASES" {
- { "host-name" "HOST_NAME" TEXT +user-assigned-id+ }
- { "os" "OS" TEXT +user-assigned-id+ }
- { "cpu" "CPU" TEXT +user-assigned-id+ }
- { "last-release" "LAST_RELEASE" TEXT }
- { "release-git-id" "RELEASE_GIT_ID" TEXT }
-} define-persistent
-
-:: <release> ( version builder -- release )
- release new
- builder host-name>> >>host-name
- builder os>> >>os
- builder cpu>> >>cpu
- builder release-git-id>> >>release-git-id
- version builder release-name >>last-release ;
-
-: execute-on-server ( string -- )
- [ "ssh" , upload-host get , "-l" , upload-username get , ] { } make
- <process>
- swap >>command
- 5 minutes >>timeout
- ascii [ write ] with-process-writer ;
-
-: release-script ( version builders -- string )
- [ upload-directory get "cd " "\n" surround ] 2dip
- [ release-command ] with map "\n" join
- append ;
-
-: create-releases ( version builders -- )
- release-script execute-on-server ;
-
-: update-releases ( version builders -- )
- [
- release new delete-tuples
- [ <release> insert-tuple ] with each
- ] with-transaction ;
-
-: check-releases ( builders -- )
- [ release-git-id>> ] map all-equal?
- [ "Not all builders are up to date" throw ] unless ;
-
-: do-release ( version -- )
- [
- builder new select-tuples
- [ nip check-releases ]
- [ create-releases ]
- [ update-releases ]
- 2tri
- ] with-mason-db ;
last-release release-git-id
last-git-id last-timestamp last-report
current-git-id current-timestamp
-status ;
+status
+heartbeat-timestamp ;
builder "BUILDERS" {
{ "host-name" "HOST_NAME" TEXT +user-assigned-id+ }
! Can't name it CURRENT_TIMESTAMP because of bug in db library
{ "current-timestamp" "CURR_TIMESTAMP" TIMESTAMP }
{ "status" "STATUS" TEXT }
+
+ { "heartbeat-timestamp" "HEARTBEAT_TIMESTAMP" TIMESTAMP }
} define-persistent
: mason-db ( -- db ) "resource:mason.db" <sqlite-db> ;
+++ /dev/null
-Slava Pestov
\ No newline at end of file
+++ /dev/null
-! Copyright (C) 2010 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: bootstrap.image bootstrap.image.download io io.directories
-io.directories.hierarchy io.files.unique io.launcher
-io.pathnames kernel sequences namespaces mason.common mason.config ;
-IN: mason.source
-
-: clone-factor ( -- )
- { "git" "clone" } home "factor" append-path suffix try-process ;
-
-: save-git-id ( -- )
- git-id "git-id" to-file ;
-
-: delete-git-tree ( -- )
- ".git" delete-tree ;
-
-: download-images ( -- )
- images [ download-image ] each ;
-
-: prepare-source ( -- )
- "factor" [ save-git-id delete-git-tree download-images ] with-directory ;
-
-: package-name ( version -- string )
- "factor-src-" ".zip" surround ;
-
-: make-tarball ( version -- path )
- [ { "zip" "-qr9" } ] dip package-name
- [ suffix "factor" suffix try-process ] keep ;
-
-: make-package ( version -- path )
- unique-directory
- [
- clone-factor prepare-source make-tarball
- "Package created: " write absolute-path dup print
- ] with-directory ;
-
-: remote-location ( version -- dest )
- [ upload-directory get "/releases/" ] dip 3append ;
-
-: remote-archive-name ( version -- dest )
- [ remote-location ] [ package-name ] bi "/" glue ;
-
-: upload-package ( package version -- )
- [ upload-username get upload-host get ] dip
- remote-archive-name
- upload-safely ;
-
-: release-source-package ( version -- )
- [ make-package ] [ upload-package ] bi ;
! Copyright (C) 2008, 2010 Eduardo Cavazos, Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs benchmark bootstrap.stage2
-compiler.errors source-files.errors generic help.html help.lint
-io.directories io.encodings.utf8 io.files kernel mason.common
-math namespaces prettyprint sequences sets sorting tools.test
-tools.time words system io tools.errors vocabs vocabs.files
-vocabs.hierarchy vocabs.errors vocabs.refresh locals
-source-files compiler.units ;
+compiler.errors generic help.html help.lint io io.directories
+io.encodings.utf8 io.files kernel locals mason.common
+namespaces sequences sets sorting source-files.errors system
+tools.errors tools.test tools.time vocabs.errors
+vocabs.hierarchy vocabs.refresh words ;
IN: mason.test
: do-load ( -- )
errors details-file utf8 [ errors. ] with-file-writer ;
: do-tests ( -- )
+ forget-tests? on
test-all test-failures get
test-all-vocabs-file
test-all-errors-file
do-step ;
-: cleanup-tests ( -- )
- ! Free up some code heap space
- [
- vocabs [ vocab-tests [ forget-source ] each ] each
- ] with-compilation-unit ;
-
: do-help-lint ( -- )
help-lint-all lint-failures get values
help-lint-vocabs-file
[ do-load ] benchmark load-time-file to-file
[ generate-help ] benchmark html-help-time-file to-file
[ do-tests ] benchmark test-time-file to-file
- cleanup-tests
[ do-help-lint ] benchmark help-lint-time-file to-file
[ do-benchmarks ] benchmark benchmark-time-file to-file
do-compile-errors
--- /dev/null
+Slava Pestov
--- /dev/null
+Slava Pestov
--- /dev/null
+! Copyright (C) 2010 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: io kernel make mason.version.common mason.version.files
+sequences ;
+IN: mason.version.binary
+
+: binary-release-command ( version builder -- command )
+ [
+ "cp " %
+ [ nip binary-package-name % " " % ]
+ [ remote-binary-release-name % ]
+ 2bi
+ ] "" make ;
+
+: binary-release-script ( version builders -- string )
+ [ binary-release-command ] with map "\n" join ;
+
+: do-binary-release ( version builders -- )
+ "Copying binary releases to release directory..." print flush
+ binary-release-script execute-on-server ;
--- /dev/null
+Slava Pestov
--- /dev/null
+! Copyright (C) 2010 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors calendar io io.encodings.ascii io.launcher
+kernel make mason.config namespaces ;
+IN: mason.version.common
+
+: execute-on-server ( string -- )
+ [ "ssh" , upload-host get , "-l" , upload-username get , ] { } make
+ <process>
+ swap >>command
+ 5 minutes >>timeout
+ ascii [ write ] with-process-writer ;
--- /dev/null
+Slava Pestov
--- /dev/null
+! Copyright (C) 2010 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors calendar db db.tuples db.types kernel locals
+mason.version.files sequences ;
+IN: mason.version.data
+
+TUPLE: release
+host-name os cpu
+last-release release-git-id ;
+
+release "RELEASES" {
+ { "host-name" "HOST_NAME" TEXT +user-assigned-id+ }
+ { "os" "OS" TEXT +user-assigned-id+ }
+ { "cpu" "CPU" TEXT +user-assigned-id+ }
+ { "last-release" "LAST_RELEASE" TEXT }
+ { "release-git-id" "RELEASE_GIT_ID" TEXT }
+} define-persistent
+
+:: <release> ( version builder -- release )
+ release new
+ builder host-name>> >>host-name
+ builder os>> >>os
+ builder cpu>> >>cpu
+ builder release-git-id>> >>release-git-id
+ version builder binary-release-name >>last-release ;
+
+: update-binary-releases ( version builders -- )
+ [
+ release new delete-tuples
+ [ <release> insert-tuple ] with each
+ ] with-transaction ;
+
+TUPLE: version
+id version git-id timestamp source-path announcement-url ;
+
+version "VERSIONS" {
+ { "id" "ID" INTEGER +db-assigned-id+ }
+ { "version" "VERSION" TEXT }
+ { "git-id" "GIT_ID" TEXT }
+ { "timestamp" "TIMESTAMP" TIMESTAMP }
+ { "source-path" "SOURCE_PATH" TEXT }
+ { "announcement-url" "ANNOUNCEMENT_URL" TEXT }
+} define-persistent
+
+: update-version ( version git-id announcement-url -- )
+ version new
+ swap >>announcement-url
+ swap >>git-id
+ swap [ >>version ] [ source-release-name >>source-path ] bi
+ now >>timestamp
+ insert-tuple ;
+
+: latest-version ( -- version )
+ version new select-tuples last ;
--- /dev/null
+Slava Pestov
--- /dev/null
+! Copyright (C) 2010 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors fry kernel make mason.config mason.platform
+mason.release.archive namespaces sequences ;
+IN: mason.version.files
+
+: release-directory ( string version -- string )
+ [ "releases/" % % "/" % % ] "" make ;
+
+: remote-directory ( string -- string' )
+ [ upload-directory get ] dip "/" glue ;
+
+: remote ( string version -- string )
+ remote-directory swap "/" glue ;
+
+: platform ( builder -- string )
+ [ os>> ] [ cpu>> ] bi (platform) ;
+
+: binary-package-name ( builder -- string )
+ [ [ platform % "/" % ] [ last-release>> % ] bi ] "" make
+ remote-directory ;
+
+: binary-release-name ( version builder -- string )
+ [
+ [
+ [ "factor-" % platform % "-" % % ]
+ [ os>> extension % ]
+ bi
+ ] "" make
+ ] [ drop ] 2bi release-directory ;
+
+: remote-binary-release-name ( version builder -- string )
+ [ binary-release-name ] [ drop ] 2bi remote ;
+
+: source-release-name ( version -- string )
+ [ "factor-src-" ".zip" surround ] keep release-directory ;
+
+: remote-source-release-name ( version -- string )
+ [ source-release-name ] keep remote ;
--- /dev/null
+Slava Pestov
--- /dev/null
+! Copyright (C) 2010 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: bootstrap.image bootstrap.image.download io
+io.directories io.directories.hierarchy io.files.unique
+io.launcher io.pathnames kernel mason.common mason.config
+mason.version.files namespaces sequences ;
+IN: mason.version.source
+
+: clone-factor ( -- )
+ { "git" "clone" "git://factorcode.org/git/factor.git" } try-process ;
+
+: git-reset ( git-id -- )
+ { "git" "reset" "--hard" } swap suffix try-process ;
+
+: save-git-id ( git-id -- )
+ "git-id" to-file ;
+
+: delete-git-tree ( -- )
+ ".git" delete-tree
+ ".gitignore" delete-file ;
+
+: download-images ( -- )
+ images [ download-image ] each ;
+
+: prepare-source ( git-id -- )
+ "factor" [
+ [ git-reset ] [ save-git-id ] bi
+ delete-git-tree
+ download-images
+ ] with-directory ;
+
+: (make-source-release) ( version -- path )
+ [ { "zip" "-qr9" } ] dip source-release-name file-name
+ [ suffix "factor" suffix try-process ] keep ;
+
+: make-source-release ( version git-id -- path )
+ "Creating source release..." print flush
+ unique-directory
+ [
+ clone-factor prepare-source (make-source-release)
+ "Package created: " write absolute-path dup print
+ ] with-directory ;
+
+: upload-source-release ( package version -- )
+ "Uploading source release..." print flush
+ [ upload-username get upload-host get ] dip
+ remote-source-release-name
+ upload-safely ;
+
+: do-source-release ( version git-id -- )
+ [ make-source-release ] [ drop upload-source-release ] 2bi ;
--- /dev/null
+! Copyright (C) 2010 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors bit.ly combinators db.tuples debugger fry
+grouping io io.streams.string kernel locals make mason.email
+mason.server mason.twitter mason.version.binary
+mason.version.common mason.version.data mason.version.files
+mason.version.source sequences threads ;
+IN: mason.version
+
+: check-releases ( builders -- )
+ [ release-git-id>> ] map all-equal?
+ [ "Some builders are out of date" throw ] unless ;
+
+: make-release-directory ( version -- )
+ "Creating release directory..." print flush
+ [ "mkdir -p " % "" release-directory % "\n" % ] "" make
+ execute-on-server ;
+
+: tweet-release ( version announcement-url -- )
+ [
+ "Factor " %
+ [ % " released -- " % ] [ shorten-url % ] bi*
+ ] "" make mason-tweet ;
+
+:: (do-release) ( version announcement-url -- )
+ [
+ builder new select-tuples :> builders
+ builders first release-git-id>> :> git-id
+
+ builders check-releases
+ version make-release-directory
+ version builders do-binary-release
+ version builders update-binary-releases
+ version git-id do-source-release
+ version git-id announcement-url update-version
+ version announcement-url tweet-release
+
+ "Done." print flush
+ ] with-mason-db ;
+
+: send-release-email ( string version -- )
+ [ "text/plain" ] dip "Release output: " prepend mason-email ;
+
+:: do-release ( version announcement-url -- )
+ [
+ [
+ [
+ version announcement-url (do-release)
+ ] try
+ ] with-string-writer
+ version send-release-email
+ ] "Mason release" spawn drop ;
{ [ os winnt? ] [ "ogg.dll" ] }
{ [ os macosx? ] [ "libogg.0.dylib" ] }
{ [ os unix? ] [ "libogg.so" ] }
-} cond "cdecl" add-library
+} cond cdecl add-library
"ogg" deploy-library
>>
{ [ os winnt? ] [ "theoradec.dll" ] }
{ [ os macosx? ] [ "libtheoradec.0.dylib" ] }
{ [ os unix? ] [ "libtheoradec.so" ] }
-} cond "cdecl" add-library
+} cond cdecl add-library
"theoraenc" {
{ [ os winnt? ] [ "theoraenc.dll" ] }
{ [ os macosx? ] [ "libtheoraenc.0.dylib" ] }
{ [ os unix? ] [ "libtheoraenc.so" ] }
-} cond "cdecl" add-library
+} cond cdecl add-library
>>
CONSTANT: TH-EFAULT -1
{ [ os winnt? ] [ "vorbis.dll" ] }
{ [ os macosx? ] [ "libvorbis.0.dylib" ] }
{ [ os unix? ] [ "libvorbis.so" ] }
-} cond "cdecl" add-library
+} cond cdecl add-library
"vorbis" deploy-library
>>
"/System/Library/Frameworks/OpenAL.framework/OpenAL"
] }
{ [ os unix? ] [ "libalut.so" ] }
- } cond "cdecl" add-library >>
+ } cond cdecl add-library >>
<< os macosx? [ "alut" deploy-library ] unless >>
"/System/Library/Frameworks/OpenAL.framework/OpenAL"
] }
{ [ os unix? ] [ "libopenal.so" ] }
- } cond "cdecl" add-library >>
+ } cond cdecl add-library >>
<< os macosx? [ "openal" deploy-library ] unless >>
! Copyright (C) 2010 Erik Charlebois.
! See http://factorcode.org/license.txt for BSD license.
-USING: alien.c-types alien.libraries alien.syntax classes.struct
-combinators system alien.accessors byte-arrays kernel ;
+USING: alien alien.c-types alien.libraries alien.syntax
+classes.struct combinators system alien.accessors byte-arrays
+kernel ;
IN: opencl.ffi
<< "opencl" {
- { [ os windows? ] [ "OpenCL.dll" ] }
- { [ os macosx? ] [ "/System/Library/Frameworks/OpenCL.framework/OpenCL" ] }
- { [ os unix? ] [ "libOpenCL.so" ] }
- } cond "stdcall" add-library >>
+ { [ os windows? ] [ "OpenCL.dll" stdcall ] }
+ { [ os macosx? ] [ "/System/Library/Frameworks/OpenCL.framework/OpenCL" cdecl ] }
+ { [ os unix? ] [ "libOpenCL.so" cdecl ] }
+ } cond add-library >>
LIBRARY: opencl
! cl_platform.h
bindings
-untested
+not tested
! Copyright (C) 2010 Erik Charlebois.
! See http://factorcode.org/license.txt for BSD license.
-USING: accessors alien alien.accessors alien.c-types arrays
-byte-arrays combinators combinators.smart continuations destructors
-fry io.encodings.ascii io.encodings.string kernel libc locals macros
-math math.order multiline opencl.ffi prettyprint sequences
-specialized-arrays typed variants namespaces ;
+USING: accessors alien alien.c-types arrays byte-arrays combinators
+combinators.smart destructors io.encodings.ascii io.encodings.string
+kernel libc locals math namespaces opencl.ffi sequences shuffle
+specialized-arrays variants ;
IN: opencl
SPECIALIZED-ARRAYS: void* char size_t ;
: cl-not-null ( err -- )
dup f = [ cl-error ] [ drop ] if ; inline
+
+: info-data-size ( handle name info-quot -- size_t )
+ [ 0 f 0 <size_t> ] dip [ call cl-success ] 2keep drop *size_t ; inline
+
+: info-data-bytes ( handle name info-quot size -- bytes )
+ swap [ dup <byte-array> f ] dip [ call cl-success ] 3keep 2drop ; inline
+
+: info ( handle name info-quot lift-quot -- value )
+ [ 3dup info-data-size info-data-bytes ] dip call ; inline
+
+: 2info-data-size ( handle1 handle2 name info-quot -- size_t )
+ [ 0 f 0 <size_t> ] dip [ call cl-success ] 2keep drop *size_t ; inline
-MACRO: info ( info-quot lift-quot -- quot )
- [ dup ] dip '[ 2dup 0 f 0 <size_t> _ '[ _ call cl-success ] keep
- *size_t dup <byte-array> _ '[ f _ call cl-success ] keep
- _ call ] ;
-
-MACRO: 2info ( info-quot lift-quot -- quot )
- [ dup ] dip '[ 3dup 0 f 0 <size_t> _ '[ _ call cl-success ] keep
- *size_t dup <byte-array> _ '[ f _ call cl-success ] keep
- _ call ] ;
-
+: 2info-data-bytes ( handle1 handle2 name info-quot size -- bytes )
+ swap [ dup <byte-array> f ] dip [ call cl-success ] 3keep 2drop ; inline
+
+: 2info ( handle1 handle2 name info_quot lift_quot -- value )
+ [ 4dup 2info-data-size 2info-data-bytes ] dip call ; inline
+
: info-bool ( handle name quot -- ? )
[ *uint CL_TRUE = ] info ; inline
SYMBOLS: cl-current-context cl-current-queue cl-current-device ;
<PRIVATE
+
: (current-cl-context) ( -- cl-context )
cl-current-context get ; inline
} case ; inline
: platform-info-string ( handle name -- string )
- [ clGetPlatformInfo ] info-string ; inline
+ [ clGetPlatformInfo ] info-string ;
: platform-info ( id -- profile version name vendor extensions )
{
} case ; inline
: device-info-bool ( handle name -- ? )
- [ clGetDeviceInfo ] info-bool ; inline
+ [ clGetDeviceInfo ] info-bool ;
: device-info-ulong ( handle name -- ulong )
- [ clGetDeviceInfo ] info-ulong ; inline
+ [ clGetDeviceInfo ] info-ulong ;
: device-info-uint ( handle name -- uint )
- [ clGetDeviceInfo ] info-uint ; inline
+ [ clGetDeviceInfo ] info-uint ;
: device-info-string ( handle name -- string )
- [ clGetDeviceInfo ] info-string ; inline
+ [ clGetDeviceInfo ] info-string ;
: device-info-size_t ( handle name -- size_t )
- [ clGetDeviceInfo ] info-size_t ; inline
+ [ clGetDeviceInfo ] info-size_t ;
: device-info-size_t-array ( handle name -- size_t-array )
- [ clGetDeviceInfo ] info-size_t-array ; inline
+ [ clGetDeviceInfo ] info-size_t-array ;
: device-info ( device-id -- device )
dup {
] 2bi ; inline
: command-queue-info-ulong ( handle name -- ulong )
- [ clGetCommandQueueInfo ] info-ulong ; inline
+ [ clGetCommandQueueInfo ] info-ulong ;
: sampler-info-bool ( handle name -- ? )
- [ clGetSamplerInfo ] info-bool ; inline
+ [ clGetSamplerInfo ] info-bool ;
: sampler-info-uint ( handle name -- uint )
- [ clGetSamplerInfo ] info-uint ; inline
+ [ clGetSamplerInfo ] info-uint ;
: program-build-info-string ( program-handle device-handle name -- string )
- [ clGetProgramBuildInfo ] 2info-string ; inline
+ [ clGetProgramBuildInfo ] 2info-string ;
: program-build-log ( program-handle device-handle -- string )
- CL_PROGRAM_BUILD_LOG program-build-info-string ; inline
+ CL_PROGRAM_BUILD_LOG program-build-info-string ;
: strings>char*-array ( strings -- char*-array )
[ ascii encode dup length dup malloc [ cl-not-null ]
- keep &free [ -rot memcpy ] keep ] void*-array{ } map-as ; inline
+ keep &free [ -rot memcpy ] keep ] void*-array{ } map-as ;
: (program) ( cl-context sources -- program-handle )
[ handle>> ] dip [
} case ;
: kernel-info-string ( handle name -- string )
- [ clGetKernelInfo ] info-string ; inline
+ [ clGetKernelInfo ] info-string ;
: kernel-info-uint ( handle name -- uint )
- [ clGetKernelInfo ] info-uint ; inline
+ [ clGetKernelInfo ] info-uint ;
: kernel-work-group-info-size_t ( handle1 handle2 name -- size_t )
- [ clGetKernelWorkGroupInfo ] 2info-size_t ; inline
+ [ clGetKernelWorkGroupInfo ] 2info-size_t ;
: event-info-uint ( handle name -- uint )
- [ clGetEventInfo ] info-uint ; inline
+ [ clGetEventInfo ] info-uint ;
: event-info-int ( handle name -- int )
- [ clGetEventInfo ] info-int ; inline
+ [ clGetEventInfo ] info-int ;
: cl_command_type>command-type ( cl_command-type -- command-type )
{
} case ; inline
: profiling-info-ulong ( handle name -- ulong )
- [ clGetEventProfilingInfo ] info-ulong ; inline
-
+ [ clGetEventProfilingInfo ] info-ulong ;
: bind-kernel-arg-buffer ( kernel index buffer -- )
[ handle>> ] [ cl_mem heap-size ] [ handle>> <void*> ] tri*
cl-kernel new-disposable swap >>handle ; inline
: cl-kernel-name ( kernel -- string )
- handle>> CL_KERNEL_FUNCTION_NAME kernel-info-string ; inline
+ handle>> CL_KERNEL_FUNCTION_NAME kernel-info-string ;
: cl-kernel-arity ( kernel -- arity )
- handle>> CL_KERNEL_NUM_ARGS kernel-info-uint ; inline
+ handle>> CL_KERNEL_NUM_ARGS kernel-info-uint ;
: cl-kernel-local-size ( kernel -- size )
(current-cl-device) [ handle>> ] bi@ CL_KERNEL_WORK_GROUP_SIZE kernel-work-group-info-size_t ; inline
bindings
-untested
+not tested
os {
{ [ dup macosx? ] [ drop ] }
{ [ dup windows? ] [ drop ] }
- { [ dup unix? ] [ drop "glu" "libGLU.so.1" "cdecl" add-library ] }
+ { [ dup unix? ] [ drop "glu" "libGLU.so.1" cdecl add-library ] }
} cond
>>
TYPEDEF: void* TCADB
-C-ENUM:
+C-ENUM: f
ADBOVOID
ADBOMDB
ADBONDB
TYPEDEF: void* BDBCUR
-C-ENUM:
+C-ENUM: f
BDBCPCURRENT
BDBCPBEFORE
BDBCPAFTER ;
{ [ os macosx? ] [ "/opt/local/lib/libtokyotyrant.dylib" ] }
{ [ os unix? ] [ "libtokyotyrant.so" ] }
{ [ os windows? ] [ "tokyotyrant.dll" ] }
-} cond "cdecl" add-library >>
+} cond cdecl add-library >>
LIBRARY: tokyotyrant
! { timeout double }
! { opts int } ;
-C-ENUM:
+C-ENUM: f
TTESUCCESS
TTEINVALID
TTENOHOST
CONSTANT: TDBOLCKNB 32
CONSTANT: TDBOTSYNC 64
-C-ENUM:
+C-ENUM: f
TDBITLEXICAL
TDBITDECIMAL ;
C-TYPE: TDBCOND
C-TYPE: TDBQRY
-C-ENUM:
+C-ENUM: f
TDBQCSTREQ
TDBQCSTRINC
TDBQCSTRBW
CONSTANT: TDBQCNEGATE 16777216
CONSTANT: TDBQCNOIDX 33554432
-C-ENUM:
+C-ENUM: f
TDBQOSTRASC
TDBQOSTRDESC
TDBQONUMASC
{ [ os macosx? ] [ "/opt/local/lib/libtokyocabinet.dylib" ] }
{ [ os unix? ] [ "libtokyocabinet.so" ] }
{ [ os windows? ] [ "tokyocabinet.dll" ] }
-} cond "cdecl" add-library >>
+} cond cdecl add-library >>
LIBRARY: tokyocabinet
-C-ENUM:
+C-ENUM: f
TCDBTHASH
TCDBTBTREE
TCDBTFIXED
--- /dev/null
+Wrapper for Twitter web service
--- /dev/null
+web services
<table border="1">
<tr><td>Host name:</td><td><t:xml t:name="host-name" /></td></tr>
+ <tr><td>Last heartbeat:</td><td><t:xml t:name="last-heartbeat" /></td></tr>
<tr><td>Current status:</td><td><t:xml t:name="status" /></td></tr>
<tr><td>Last build:</td><td><t:xml t:name="last-build" /></td></tr>
<tr><td>Last clean build:</td><td><t:xml t:name="last-clean-build" /></td></tr>
--- /dev/null
+<?xml version='1.0' ?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
+
+<h2>Stable release: <t:link t:name="stable-release" /></h2>
+
+<table id="mytable" cellspacing="0" summary="Stable releases">
+ <t:xml t:name="release-grid" />
+</table>
+
+<p><b>Source code</b>: <t:link t:name="source-release" /></p>
+
+<h2>Development release</h2>
+
+<table id="mytable" cellspacing="0" summary="Development releases">
+ <t:xml t:name="package-grid" />
+</table>
+
+</t:chloe>
--- /dev/null
+Slava Pestov
--- /dev/null
+! Copyright (C) 2010 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors furnace.actions html.components html.forms
+kernel mason.server mason.version.data webapps.mason.grids
+webapps.mason.utils ;
+IN: webapps.mason.downloads
+
+: stable-release ( version -- link )
+ [ version>> ] [ announcement-url>> ] bi <simple-link> ;
+
+: source-release ( version -- link )
+ [ version>> ] [ source-path>> download-url ] bi <simple-link> ;
+
+: <downloads-action> ( -- action )
+ <page-action>
+ [
+ [
+ package-grid "package-grid" set-value
+ release-grid "release-grid" set-value
+
+ latest-version
+ [ stable-release "stable-release" set-value ]
+ [ source-release "source-release" set-value ] bi
+ ] with-mason-db
+ ] >>init ;
! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs db.tuples furnace.actions
furnace.utilities http.server.responses kernel locals
-mason.server mason.server.release sequences splitting urls
+mason.server mason.version.data sequences splitting urls
webapps.mason.utils xml.syntax xml.writer ;
IN: webapps.mason.grids
{ "macosx" "Mac OS X" }
{ "linux" "Linux" }
{ "freebsd" "FreeBSD" }
- { "netbsd" "NetBSD" }
{ "openbsd" "OpenBSD" }
}
:: render-grid-row ( cpu quot -- xml )
cpu second oses keys [| os | cpu os quot render-grid-cell ] map
[XML <tr><th align='center' scope='row'><-></th><-></tr> XML] ;
-
+
:: render-grid ( quot -- xml )
render-grid-header
cpus [ quot render-grid-row ] map
</head>
<body>
<t:form t:action="$mason-app/make-release">
- Version: <t:field t:name="version" />
- <button type="submit">Go</button>
+ <table>
+ <tr><td>Version:</td><td><t:field t:name="version" /></td></tr>
+ <tr><td>Announcement URL:</td><td><t:field t:name="announcement-url" /></td></tr>
+ </table>
+
+ <p><button type="submit">Go</button></p>
</t:form>
</body>
</html>
! Copyright (C) 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors furnace.actions html.forms
-http.server.responses mason.server mason.server.release
-validators ;
+http.server.responses mason.server mason.version validators ;
IN: webapps.mason.make-release
: <make-release-action> ( -- action )
[ { { "version" [ v-one-line ] } } validate-params ] >>validate
[
[
- "version" value do-release
+ "version" value "announcement-url" value do-release
"OK" "text/html" <content>
] with-mason-db
] >>submit ;
USING: accessors furnace.auth furnace.db
http.server.dispatchers mason.server webapps.mason.grids
webapps.mason.make-release webapps.mason.package
-webapps.mason.release webapps.mason.report ;
+webapps.mason.release webapps.mason.report
+webapps.mason.downloads ;
IN: webapps.mason
TUPLE: mason-app < dispatcher ;
{ mason-app "download-package" } >>template
"package" add-responder
- <package-grid-action>
- "packages" add-responder
-
<download-release-action>
{ mason-app "download-release" } >>template
"release" add-responder
- <release-grid-action>
- "releases" add-responder
+ <downloads-action>
+ { mason-app "downloads" } >>template
+ "downloads" add-responder
<make-release-action>
{ mason-app "make-release" } >>template
-
<protected>
"make releases" >>description
{ can-make-releases? } >>capabilities
! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays combinators furnace.actions html.forms
kernel mason.platform mason.report mason.server present
-sequences webapps.mason webapps.mason.report
-webapps.mason.utils xml.syntax ;
+sequences webapps.mason webapps.mason.report webapps.mason.utils
+xml.syntax ;
+FROM: mason.version.files => platform ;
IN: webapps.mason.package
: building ( builder string -- xml )
over [ [ git-link ] [ present ] bi* " (built on " ")" surround 2array ] [ 2drop f ] if ;
: packages-url ( builder -- url )
- [ os>> ] [ cpu>> ] bi (platform) "http://downloads.factorcode.org/" prepend ;
+ platform download-url ;
: package-link ( builder -- xml )
[ packages-url ] [ last-release>> ] bi [ "/" glue ] keep link ;
packages-url dup link ;
: clean-image-url ( builder -- url )
- [ os>> ] [ cpu>> ] bi (platform) "http://factorcode.org/images/clean/" prepend ;
+ platform "http://factorcode.org/images/clean/" prepend ;
: clean-image-link ( builder -- link )
clean-image-url dup link ;
[ current-status "status" set-value ]
[ last-build-status "last-build" set-value ]
[ clean-build-status "last-clean-build" set-value ]
+ [ heartbeat-timestamp>> "heartbeat-timestamp" set-value ]
[ packages-link "binaries" set-value ]
[ clean-image-link "clean-images" set-value ]
[ report-link "last-report" set-value ]
IN: webapps.mason.release
: release-link ( builder -- xml )
- [ "http://downloads.factorcode.org/" ] dip
- last-release>> [ "/" glue ] [ file-name ] bi link ;
+ last-release>> [ download-url ] [ file-name ] bi link ;
: <download-release-action> ( -- action )
<page-action>
! Copyright (C) 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays assocs db.tuples furnace.actions
-html.forms kernel mason.server mason.server.release sequences
+html.forms kernel mason.server mason.version.data sequences
validators xml.syntax ;
IN: webapps.mason.utils
] [ drop f ] if
] bi
2array sift [ [XML <li><-></li> XML] ] map [XML <ul><-></ul> XML] ;
+
+: download-url ( string -- string' )
+ "http://downloads.factorcode.org/" prepend ;
(,fuel-syntax--type-definition-regex 2 'factor-font-lock-type-name)
(,fuel-syntax--method-definition-regex (1 'factor-font-lock-type-name)
(2 'factor-font-lock-word))
+ (,fuel-syntax--before-definition-regex (1 'factor-font-lock-type-name)
+ (2 'factor-font-lock-word))
+ (,fuel-syntax--after-definition-regex (1 'factor-font-lock-type-name)
+ (2 'factor-font-lock-word))
(,fuel-syntax--tuple-decl-regex 2 'factor-font-lock-type-name)
(,fuel-syntax--constructor-regex . 'factor-font-lock-constructor)
(,fuel-syntax--setter-regex . 'factor-font-lock-setter-word)
\r
(defconst fuel-syntax--parsing-words\r
'(":" "::" ";" "&:" "<<" "<PRIVATE" ">>"\r
- "ABOUT:" "ALIAS:" "ALIEN:" "ARTICLE:"\r
- "B" "BIN:"\r
+ "ABOUT:" "AFTER:" "ALIAS:" "ALIEN:" "ARTICLE:"\r
+ "B" "BEFORE:" "BIN:"\r
"C:" "CALLBACK:" "C-ENUM:" "C-STRUCT:" "C-TYPE:" "C-UNION:" "CHAR:" "COM-INTERFACE:" "CONSTANT:" "call-next-method"\r
"DEFER:"\r
"EBNF:" ";EBNF" "ERROR:" "EXCLUDE:"\r
(defconst fuel-syntax--method-definition-regex\r
"^M::? +\\([^ ]+\\) +\\([^ ]+\\)")\r
\r
+(defconst fuel-syntax--before-definition-regex\r
+ "^BEFORE: +\\([^ ]+\\) +\\([^ ]+\\)")\r
+\r
+(defconst fuel-syntax--after-definition-regex\r
+ "^AFTER: +\\([^ ]+\\) +\\([^ ]+\\)")\r
+\r
(defconst fuel-syntax--integer-regex\r
"\\_<-?[0-9]+\\_>")\r
\r
(format "\\_<\\(%s\\)?: +\\_<\\(\\w+\\)\\_>"\r
(regexp-opt\r
'(":" "GENERIC" "DEFER" "HOOK" "MAIN" "MATH" "POSTPONE"\r
- "SYMBOL" "SYNTAX" "TYPED" "RENAME"))))\r
+ "SYMBOL" "SYNTAX" "TYPED" "TYPED:" "RENAME"))))\r
\r
(defconst fuel-syntax--alias-definition-regex\r
"^ALIAS: +\\(\\_<.+?\\_>\\) +\\(\\_<.+?\\_>\\)")\r
"\\_<CALLBACK: \\(\\w+\\) \\(\\w+\\)")\r
\r
(defconst fuel-syntax--indent-def-starts '("" ":"\r
+ "AFTER" "BEFORE"\r
"C-ENUM" "C-STRUCT" "C-UNION" "COM-INTERFACE"\r
"FROM" "FUNCTION:"\r
"INTERSECTION:"\r
: compile-c-library ( -- )
compile-library? [ compile-library ] when
- c-library get dup library-path "cdecl" add-library ;
+ c-library get dup library-path cdecl add-library ;
: define-c-function ( function types effect body -- )
[
IN: cryptlib.libcl
<< "libcl" {
- { [ win32? ] [ "cl32.dll" "stdcall" ] }
- { [ macosx? ] [ "libcl.dylib" "cdecl" ] }
- { [ unix? ] [ "libcl.so" "cdecl" ] }
+ { [ win32? ] [ "cl32.dll" stdcall ] }
+ { [ macosx? ] [ "libcl.dylib" cdecl ] }
+ { [ unix? ] [ "libcl.so" cdecl ] }
} cond add-library >>
! ===============================================
! Internal keyset options
! (As _NONE but open for exclusive access, _CRYPT_DEFINED
! Last possible key option type, _CRYPT_DEFINED Last external keyset option)
-C-ENUM:
+C-ENUM: f
CRYPT_KEYOPT_NONE
CRYPT_KEYOPT_READONLY
CRYPT_KEYOPT_CREATE
IN: db.mysql.ffi
<< "mysql" {
- { [ os winnt? ] [ "libmySQL.dll" "stdcall" ] }
- { [ os macosx? ] [ "libmysqlclient.14.dylib" "cdecl" ] }
- { [ os unix? ] [ "libmysqlclient.so.14" "cdecl" ] }
+ { [ os winnt? ] [ "libmySQL.dll" stdcall ] }
+ { [ os macosx? ] [ "libmysqlclient.14.dylib" cdecl ] }
+ { [ os unix? ] [ "libmysqlclient.so.14" cdecl ] }
} cond add-library >>
LIBRARY: mysql
] when ;
: (destroy-java-vm)
- "int" { "void*" } "cdecl" alien-indirect ;
+ "int" { "void*" } cdecl alien-indirect ;
: (attach-current-thread)
- "int" { "void*" "void*" "void*" } "cdecl" alien-indirect ;
+ "int" { "void*" "void*" "void*" } cdecl alien-indirect ;
: (detach-current-thread)
- "int" { "void*" } "cdecl" alien-indirect ;
+ "int" { "void*" } cdecl alien-indirect ;
: (get-env)
- "int" { "void*" "void*" "int" } "cdecl" alien-indirect ;
+ "int" { "void*" "void*" "int" } cdecl alien-indirect ;
: (attach-current-thread-as-daemon)
- "int" { "void*" "void*" "void*" } "cdecl" alien-indirect ;
+ "int" { "void*" "void*" "void*" } cdecl alien-indirect ;
: destroy-java-vm ( javavm -- int )
dup JavaVM-functions JNIInvokeInterface-DestroyJavaVM (destroy-java-vm) ;
: (get-version)
- "jint" { "JNIEnv*" } "cdecl" alien-indirect ;
+ "jint" { "JNIEnv*" } cdecl alien-indirect ;
: get-version ( jnienv -- int )
dup JNIEnv-functions JNINativeInterface-GetVersion (get-version) ;
: (find-class)
- "void*" { "JNINativeInterface*" "char*" } "cdecl" alien-indirect ;
+ "void*" { "JNINativeInterface*" "char*" } cdecl alien-indirect ;
: find-class ( name jnienv -- int )
dup swapd JNIEnv-functions JNINativeInterface-FindClass (find-class) ;
: (get-static-field-id)
- "void*" { "JNINativeInterface*" "void*" "char*" "char*" } "cdecl" alien-indirect ;
+ "void*" { "JNINativeInterface*" "void*" "char*" "char*" } cdecl alien-indirect ;
: get-static-field-id ( class name sig jnienv -- int )
dup >r >r 3array r> swap first3 r> JNIEnv-functions JNINativeInterface-GetStaticFieldID (get-static-field-id) ;
: (get-static-object-field)
- "void*" { "JNINativeInterface*" "void*" "void*" } "cdecl" alien-indirect ;
+ "void*" { "JNINativeInterface*" "void*" "void*" } cdecl alien-indirect ;
: get-static-object-field ( class id jnienv -- int )
dup >r >r 2array r> swap first2 r> JNIEnv-functions JNINativeInterface-GetStaticObjectField (get-static-object-field) ;
: (get-method-id)
- "void*" { "JNINativeInterface*" "void*" "char*" "char*" } "cdecl" alien-indirect ;
+ "void*" { "JNINativeInterface*" "void*" "char*" "char*" } cdecl alien-indirect ;
: get-method-id ( class name sig jnienv -- int )
dup >r >r 3array r> swap first3 r> JNIEnv-functions JNINativeInterface-GetMethodID (get-method-id) ;
: (new-string)
- "void*" { "JNINativeInterface*" "char*" "int" } "cdecl" alien-indirect ;
+ "void*" { "JNINativeInterface*" "char*" "int" } cdecl alien-indirect ;
: new-string ( str jnienv -- str )
dup >r >r dup length 2array r> swap first2 r> JNIEnv-functions JNINativeInterface-NewString (new-string) ;
: (call1)
- "void" { "JNINativeInterface*" "void*" "void*" "int" } "cdecl" alien-indirect ;
+ "void" { "JNINativeInterface*" "void*" "void*" "int" } cdecl alien-indirect ;
: call1 ( obj method-id jstr jnienv -- )
dup >r >r 3array r> swap first3 r> JNIEnv-functions JNINativeInterface-CallObjectMethod (call1) ;
IN: ldap.libldap
<< "libldap" {
- { [ win32? ] [ "libldap.dll" "stdcall" ] }
- { [ macosx? ] [ "libldap.dylib" "cdecl" ] }
- { [ unix? ] [ "libldap.so" "cdecl" ] }
+ { [ win32? ] [ "libldap.dll" stdcall ] }
+ { [ macosx? ] [ "libldap.dylib" cdecl ] }
+ { [ unix? ] [ "libldap.so" cdecl ] }
} cond add-library >>
: LDAP_VERSION1 1 ; inline
[ t ] [ f ]
[ { } ]
[ drop f ]
- [ "cdecl" ]
+ [ cdecl ]
[ first ] [ second ] [ third ] [ fourth ]
[ ">" write ] [ "/>" write ]
} ;
words math threads io.encodings.ascii ;
IN: odbc
-<< "odbc" "odbc32.dll" "stdcall" add-library >>
+<< "odbc" "odbc32.dll" stdcall add-library >>
LIBRARY: odbc
IN: oracle.liboci
"oci" {
- { [ os winnt? ] [ "oci.dll" "stdcall" ] }
- { [ os macosx? ] [ "$DYLD_LIBRARY_PATH/libclntsh.dylib" "cdecl" ] }
- { [ os unix? ] [ "$DYLD_LIBRARY_PATH/libclntsh.so.10.1" "cdecl" ] }
+ { [ os winnt? ] [ "oci.dll" stdcall ] }
+ { [ os macosx? ] [ "$DYLD_LIBRARY_PATH/libclntsh.dylib" cdecl ] }
+ { [ os unix? ] [ "$DYLD_LIBRARY_PATH/libclntsh.so.10.1" cdecl ] }
} cond add-library
! ===============================================
IN: pdf.libhpdf
<< "libhpdf" {
- { [ win32? ] [ "libhpdf.dll" "stdcall" ] }
- { [ macosx? ] [ "libhpdf.dylib" "cdecl" ] }
- { [ unix? ] [ "$LD_LIBRARY_PATH/libhpdf.so" "cdecl" ] }
+ { [ win32? ] [ "libhpdf.dll" stdcall ] }
+ { [ macosx? ] [ "libhpdf.dylib" cdecl ] }
+ { [ unix? ] [ "$LD_LIBRARY_PATH/libhpdf.so" cdecl ] }
} cond add-library >>
! compression mode
: HPDF_COMP_MASK HEX: FF ; inline
! page mode
-C-ENUM:
+C-ENUM: f
HPDF_PAGE_MODE_USE_NONE
HPDF_PAGE_MODE_USE_OUTLINE
HPDF_PAGE_MODE_USE_THUMBS
+PLAF_DLL_OBJS += vm/os-windows-nt-x86.32.o
DLL_PATH=http://factorcode.org/dlls
WINDRES=windres
include vm/Config.windows.nt
+PLAF_DLL_OBJS += vm/os-windows-nt-x86.64.o
DLL_PATH=http://factorcode.org/dlls/64
CC=$(WIN64_PATH)-gcc.exe
WINDRES=$(WIN64_PATH)-windres.exe
if(obj.type_p(QUOTATION_TYPE))
{
char *return_addr = (char *)FRAME_RETURN_ADDRESS(frame,this);
- char *quot_entry_point = (char *)(frame_code(frame) + 1);
+ char *quot_entry_point = (char *)frame_code(frame)->entry_point();
return tag_fixnum(quot_code_offset_to_scan(
obj.value(),(cell)(return_addr - quot_entry_point)));
{
if(size > ((u64)1 << (sizeof(cell) * 8 - 6))) fatal_error("Heap too large",size);
seg = new segment(align_page(size),true);
- if(!seg) fatal_error("Out of memory in heap allocator",size);
- allocator = new free_list_allocator<code_block>(size,seg->start);
+ if(!seg) fatal_error("Out of memory in code_heap constructor",size);
+
+ cell start = seg->start + seh_area_size;
+
+ allocator = new free_list_allocator<code_block>(seg->end - start,start);
+
+ /* See os-windows-nt-x86.64.cpp for seh_area usage */
+ seh_area = (char *)seg->start;
}
code_heap::~code_heap()
namespace factor
{
+#if defined(WINDOWS) && defined(FACTOR_64)
+ const cell seh_area_size = 1024;
+#else
+ const cell seh_area_size = 0;
+#endif
+
struct code_heap {
/* The actual memory area */
segment *seg;
+ /* Memory area reserved for SEH. Only used on Windows */
+ char *seh_area;
+
/* Memory allocator */
free_list_allocator<code_block> *allocator;
data_root<array> methods(methods_,parent);
data_root<array> cache(cache_,parent);
- /* Generate machine code to determine the object's class. */
- emit_class_lookup(index,PIC_TUPLE);
+ /* Load the object from the datastack. */
+ emit_with_literal(parent->special_objects[PIC_LOAD],tag_fixnum(-index * sizeof(cell)));
/* Do a cache lookup. */
emit_with_literal(parent->special_objects[MEGA_LOOKUP],cache.value());
p->datastack_size = 32 * sizeof(cell);
p->retainstack_size = 32 * sizeof(cell);
-#ifdef FACTOR_PPC
+#if defined(__OpenBSD__) && defined(FACTOR_X86)
+ p->callstack_size = 64 * sizeof(cell);
+#elif defined(FACTOR_PPC)
p->callstack_size = 256 * sizeof(cell);
#else
p->callstack_size = 128 * sizeof(cell);
int ffi_test_10(int a, int b, double c, int d, float e, int f, int g, int h)
{
- return a - b - c - d - e - f - g - h;
+ return (int)(a - b - c - d - e - f - g - h);
}
int ffi_test_11(int a, struct foo b, int c)
int ffi_test_12(int a, int b, struct rect c, int d, int e, int f)
{
- return a + b + c.x + c.y + c.w + c.h + d + e + f;
+ return (int)(a + b + c.x + c.y + c.w + c.h + d + e + f);
}
int ffi_test_13(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k)
long ffi_test_22(long x, long long y, long long z)
{
- return x + y / z;
+ return (long)(x + y / z);
}
float ffi_test_23(float x[3], float y[3])
int ffi_test_39(long a, long b, struct test_struct_13 s)
{
assert(a == b);
- return s.x1 + s.x2 + s.x3 + s.x4 + s.x5 + s.x6;
+ return (int)(s.x1 + s.x2 + s.x3 + s.x4 + s.x5 + s.x6);
}
struct test_struct_14 ffi_test_40(double x1, double x2)
}
#endif
+
+FACTOR_FASTCALL(int) ffi_test_49(int x)
+{
+ return x + 1;
+}
+
+FACTOR_FASTCALL(int) ffi_test_50(int x, int y)
+{
+ return x + y + 1;
+}
+
+FACTOR_FASTCALL(int) ffi_test_51(int x, int y, int z)
+{
+ return x + y + z + 1;
+}
+
+FACTOR_FASTCALL(int) ffi_test_52(int x, float y, int z)
+{
+ return (int)(x + y + z + 1);
+}
+
+FACTOR_FASTCALL(int) ffi_test_53(int x, float y, int z, int w)
+{
+ return (int)(x + y + z + w + 1);
+}
+
+FACTOR_FASTCALL(int) ffi_test_54(struct test_struct_11 x, int y)
+{
+ return x.x + x.y + y + 1;
+}
+
+FACTOR_FASTCALL(int) ffi_test_55(struct test_struct_11 x, int y, int z)
+{
+ return x.x + x.y + y + z + 1;
+}
+
+FACTOR_FASTCALL(int) ffi_test_56(struct test_struct_11 x, int y, int z, int w)
+{
+ return x.x + x.y + y + z + w + 1;
+}
+
+FACTOR_FASTCALL(struct test_struct_11) ffi_test_57(int x, int y)
+{
+ struct test_struct_11 r = { x + y, x - y };
+ return r;
+}
+
+FACTOR_FASTCALL(struct test_struct_11) ffi_test_58(int x, int y, int z)
+{
+ struct test_struct_11 r = { x + y, y - z };
+ return r;
+}
#if defined(_MSC_VER)
#define FACTOR_STDCALL(return_type) return_type __stdcall
+ #define FACTOR_FASTCALL(return_type) return_type __fastcall
#elif defined(i386) || defined(__i386) || defined(__i386__)
#define FACTOR_STDCALL(return_type) __attribute__((stdcall)) return_type
+ #define FACTOR_FASTCALL(return_type) __attribute__((fastcall)) return_type
#else
#define FACTOR_STDCALL(return_type) return_type
+ #define FACTOR_FASTCALL(return_type) return_type
#endif
#if defined(__APPLE__)
FACTOR_EXPORT short ffi_test_48(struct bool_field_test x);
#endif
+
+FACTOR_EXPORT FACTOR_FASTCALL(int) ffi_test_49(int x);
+FACTOR_EXPORT FACTOR_FASTCALL(int) ffi_test_50(int x, int y);
+FACTOR_EXPORT FACTOR_FASTCALL(int) ffi_test_51(int x, int y, int z);
+FACTOR_EXPORT FACTOR_FASTCALL(int) ffi_test_52(int x, float y, int z);
+FACTOR_EXPORT FACTOR_FASTCALL(int) ffi_test_53(int x, float y, int z, int w);
+FACTOR_EXPORT FACTOR_FASTCALL(int) ffi_test_54(struct test_struct_11 x, int y);
+FACTOR_EXPORT FACTOR_FASTCALL(int) ffi_test_55(struct test_struct_11 x, int y, int z);
+FACTOR_EXPORT FACTOR_FASTCALL(int) ffi_test_56(struct test_struct_11 x, int y, int z, int w);
+FACTOR_EXPORT FACTOR_FASTCALL(struct test_struct_11) ffi_test_57(int x, int y);
+FACTOR_EXPORT FACTOR_FASTCALL(struct test_struct_11) ffi_test_58(int x, int y, int z);
init_objects(&h);
cell data_offset = data->tenured->start - h.data_relocation_base;
- cell code_offset = code->seg->start - h.code_relocation_base;
+ cell code_offset = code->allocator->start - h.code_relocation_base;
fixup_data(data_offset,code_offset);
fixup_code(data_offset,code_offset);
h.version = image_version;
h.data_relocation_base = data->tenured->start;
h.data_size = data->tenured->occupied_space();
- h.code_relocation_base = code->seg->start;
+ h.code_relocation_base = code->allocator->start;
h.code_size = code->allocator->occupied_space();
h.true_object = true_object;
parent->update_pic_count(inline_cache_type);
/* Generate machine code to determine the object's class. */
- emit_class_lookup(index,inline_cache_type);
+ emit_with_literal(parent->special_objects[PIC_LOAD],tag_fixnum(-index * sizeof(cell)));
+ emit(parent->special_objects[inline_cache_type]);
/* Generate machine code to check, in turn, if the class is one of the cached entries. */
cell i;
return load_value_masked(rel_indirect_arm_mask,20,0) + relative_to + sizeof(cell);
case RC_ABSOLUTE_2:
return *(u16 *)(pointer - sizeof(u16));
+ case RC_ABSOLUTE_1:
+ return *(u8 *)(pointer - sizeof(u8));
default:
critical_error("Bad rel class",rel.rel_class());
return 0;
case RC_ABSOLUTE_2:
*(u16 *)(pointer - sizeof(u16)) = (u16)absolute_value;
break;
+ case RC_ABSOLUTE_1:
+ *(u8 *)(pointer - sizeof(u8)) = (u8)absolute_value;
+ break;
default:
critical_error("Bad rel class",rel.rel_class());
break;
};
enum relocation_class {
- /* absolute address in a 64-bit location */
+ /* absolute address in a pointer-width location */
RC_ABSOLUTE_CELL,
- /* absolute address in a 32-bit location */
+ /* absolute address in a 4 byte location */
RC_ABSOLUTE,
- /* relative address in a 32-bit location */
+ /* relative address in a 4 byte location */
RC_RELATIVE,
/* absolute address in a PowerPC LIS/ORI sequence */
RC_ABSOLUTE_PPC_2_2,
RC_INDIRECT_ARM,
/* pointer to address in an ARM LDR/STR instruction offset by 8 bytes */
RC_INDIRECT_ARM_PC,
- /* absolute address in a 16-bit location */
- RC_ABSOLUTE_2
+ /* absolute address in a 2 byte location */
+ RC_ABSOLUTE_2,
+ /* absolute address in a 1 byte location */
+ RC_ABSOLUTE_1,
};
static const cell rel_absolute_ppc_2_mask = 0xffff;
if(feof(file))
{
byte_array *new_buf = allot_byte_array(c);
- memcpy(new_buf + 1, buf.untagged() + 1,c);
+ memcpy(new_buf->data<char>(), buf->data<char>(),c);
buf = new_buf;
}
return false;
}
-void jit::emit_class_lookup(fixnum index, cell type)
-{
- emit_with_literal(parent->special_objects[PIC_LOAD],tag_fixnum(-index * sizeof(cell)));
- emit(parent->special_objects[type]);
-}
-
/* Facility to convert compiled code offsets to quotation offsets.
Call jit_compute_offset() with the compiled code offset, then emit
code, and at the end jit->position is the quotation position. */
bool emit_subprimitive(cell word_, bool tail_call_p, bool stack_frame_p);
- void emit_class_lookup(fixnum index, cell type);
-
fixnum get_position()
{
if(computing_offset_p)
ctx->replace(allot_float(bignum_to_float(ctx->peek())));
}
-void factor_vm::primitive_float_to_str()
+void factor_vm::primitive_format_float()
{
- byte_array *array = allot_byte_array(33);
- SNPRINTF((char *)(array + 1),32,"%.16g",untag_float_check(ctx->pop()));
+ byte_array *array = allot_byte_array(100);
+ char *format = alien_offset(ctx->pop());
+ double value = untag_float_check(ctx->pop());
+ SNPRINTF(array->data<char>(),99,format,value);
ctx->push(tag<byte_array>(array));
}
u64 nano_count()
{
struct timespec t;
- int ret;
- ret = clock_gettime(CLOCK_MONOTONIC,&t);
+ int ret = clock_gettime(CLOCK_MONOTONIC,&t);
if(ret != 0)
fatal_error("clock_gettime failed", 0);
return (u64)t.tv_sec * 1000000000 + t.tv_nsec;
u64 nano_count()
{
- u64 t = mach_absolute_time();
- mach_timebase_info_data_t info;
- kern_return_t ret = mach_timebase_info(&info);
- if(ret != 0)
- fatal_error("mach_timebase_info failed",ret);
- return t * (info.numer/info.denom);
+ u64 time = mach_absolute_time();
+
+ static u64 scaling_factor = 0;
+ if(!scaling_factor)
+ {
+ mach_timebase_info_data_t info;
+ kern_return_t ret = mach_timebase_info(&info);
+ if(ret != 0)
+ fatal_error("mach_timebase_info failed",ret);
+ scaling_factor = info.numer/info.denom;
+ }
+
+ return time * scaling_factor;
}
}
--- /dev/null
+#include "master.hpp"
+
+namespace factor
+{
+
+void factor_vm::c_to_factor_toplevel(cell quot)
+{
+ /* 32-bit Windows SEH is set up in basis/cpu/x86/32/winnt/bootstrap.factor */
+ c_to_factor(quot);
+}
+
+}
--- /dev/null
+#include "master.hpp"
+
+namespace factor {
+
+typedef unsigned char UBYTE;
+
+const UBYTE UNW_FLAG_EHANDLER = 0x1;
+
+struct UNWIND_INFO {
+ UBYTE Version:3;
+ UBYTE Flags:5;
+ UBYTE SizeOfProlog;
+ UBYTE CountOfCodes;
+ UBYTE FrameRegister:4;
+ UBYTE FrameOffset:4;
+ ULONG ExceptionHandler;
+ ULONG ExceptionData[1];
+};
+
+struct seh_data {
+ UNWIND_INFO unwind_info;
+ RUNTIME_FUNCTION func;
+ UBYTE handler[32];
+};
+
+void factor_vm::c_to_factor_toplevel(cell quot)
+{
+ /* The annoying thing about Win64 SEH is that the offsets in
+ * function tables are 32-bit integers, and the exception handler
+ * itself must reside between the start and end pointers, so
+ * we stick everything at the beginning of the code heap and
+ * generate a small trampoline that jumps to the real
+ * exception handler. */
+
+ seh_data *seh_area = (seh_data *)code->seh_area;
+ cell base = code->seg->start;
+
+ /* Should look at generating this with the Factor assembler */
+
+ /* mov rax,0 */
+ seh_area->handler[0] = 0x48;
+ seh_area->handler[1] = 0xb8;
+ seh_area->handler[2] = 0x0;
+ seh_area->handler[3] = 0x0;
+ seh_area->handler[4] = 0x0;
+ seh_area->handler[5] = 0x0;
+ seh_area->handler[6] = 0x0;
+ seh_area->handler[7] = 0x0;
+ seh_area->handler[8] = 0x0;
+ seh_area->handler[9] = 0x0;
+
+ /* jmp rax */
+ seh_area->handler[10] = 0x48;
+ seh_area->handler[11] = 0xff;
+ seh_area->handler[12] = 0xe0;
+
+ /* Store address of exception handler in the operand of the 'mov' */
+ cell handler = (cell)&factor::exception_handler;
+ memcpy(&seh_area->handler[2],&handler,sizeof(cell));
+
+ UNWIND_INFO *unwind_info = &seh_area->unwind_info;
+ unwind_info->Version = 1;
+ unwind_info->Flags = UNW_FLAG_EHANDLER;
+ unwind_info->SizeOfProlog = 0;
+ unwind_info->CountOfCodes = 0;
+ unwind_info->FrameRegister = 0;
+ unwind_info->FrameOffset = 0;
+ unwind_info->ExceptionHandler = (DWORD)((cell)&seh_area->handler[0] - base);
+ unwind_info->ExceptionData[0] = 0;
+
+ RUNTIME_FUNCTION *func = &seh_area->func;
+ func->BeginAddress = 0;
+ func->EndAddress = (DWORD)(code->seg->end - base);
+ func->UnwindData = (DWORD)((cell)&seh_area->unwind_info - base);
+
+ if(!RtlAddFunctionTable(func,1,base))
+ fatal_error("RtlAddFunctionTable() failed",0);
+
+ c_to_factor(quot);
+
+ if(!RtlDeleteFunctionTable(func))
+ fatal_error("RtlDeleteFunctionTable() failed",0);
+}
+
+}
u64 nano_count()
{
- LARGE_INTEGER count;
- LARGE_INTEGER frequency;
+ static double scale_factor;
+
static u32 hi = 0;
static u32 lo = 0;
- BOOL ret;
- ret = QueryPerformanceCounter(&count);
+
+ LARGE_INTEGER count;
+ BOOL ret = QueryPerformanceCounter(&count);
if(ret == 0)
fatal_error("QueryPerformanceCounter", 0);
- ret = QueryPerformanceFrequency(&frequency);
- if(ret == 0)
- fatal_error("QueryPerformanceFrequency", 0);
+
+ if(scale_factor == 0.0)
+ {
+ LARGE_INTEGER frequency;
+ BOOL ret = QueryPerformanceFrequency(&frequency);
+ if(ret == 0)
+ fatal_error("QueryPerformanceFrequency", 0);
+ scale_factor = (1000000000.0 / frequency.QuadPart);
+ }
#ifdef FACTOR_64
hi = count.HighPart;
#endif
lo = count.LowPart;
- return (u64)((((u64)hi << 32) | (u64)lo)*(1000000000.0/frequency.QuadPart));
+ return (u64)((((u64)hi << 32) | (u64)lo) * scale_factor);
}
void sleep_nanos(u64 nsec)
break;
}
- return ExceptionContinueExecution;
+ return 0;
}
-LONG exception_handler(PEXCEPTION_RECORD e, void *frame, PCONTEXT c, void *dispatch)
+VM_C_API LONG exception_handler(PEXCEPTION_RECORD e, void *frame, PCONTEXT c, void *dispatch)
{
return current_vm()->exception_handler(e,frame,c,dispatch);
}
-void factor_vm::c_to_factor_toplevel(cell quot)
-{
- c_to_factor(quot);
-}
-
void factor_vm::open_console()
{
}
#define FACTOR_DLL NULL
-LONG exception_handler(PEXCEPTION_RECORD e, void *frame, PCONTEXT c, void *dispatch);
+VM_C_API LONG exception_handler(PEXCEPTION_RECORD e, void *frame, PCONTEXT c, void *dispatch);
// SSE traps raise these exception codes, which are defined in internal NT headers
// but not winbase.h
#include "os-windows-ce.hpp"
#include "os-windows.hpp"
#elif defined(WINNT)
- #include "os-windows-nt.hpp"
#include "os-windows.hpp"
+ #include "os-windows-nt.hpp"
#if defined(FACTOR_AMD64)
#include "os-windows-nt.64.hpp"
_(float_subtract) \
_(float_to_bignum) \
_(float_to_fixnum) \
- _(float_to_str) \
_(fopen) \
+ _(format_float) \
_(fputc) \
_(fread) \
_(fseek) \
--- /dev/null
+.386\r
+.model flat\r
+exception_handler proto\r
+.safeseh exception_handler\r
+end\r
cell unbox_array_size_slow();
void primitive_fixnum_to_float();
void primitive_bignum_to_float();
- void primitive_float_to_str();
+ void primitive_format_float();
void primitive_float_eq();
void primitive_float_add();
void primitive_float_subtract();