// Generated by V
 #define linux (1) 
 #include <pthread.h>
    
#include <stdio.h>  // TODO remove all these includes, define all function signatures and types manually 
#include <stdlib.h>
#include <signal.h>
#include <stdarg.h> // for va_list 
#include <inttypes.h>  // int64_t etc 

//================================== TYPEDEFS ================================*/ 

typedef unsigned char byte;
typedef unsigned int uint;
typedef int64_t i64;
typedef int32_t i32;
typedef int16_t i16;
typedef int8_t i8;
typedef uint64_t u64;
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
typedef uint32_t rune;
typedef float f32;
typedef double f64; 
typedef unsigned char* byteptr;
typedef int* intptr;
typedef void* voidptr;
typedef struct array array;
typedef struct map map;
typedef array array_string; 
typedef array array_int; 
typedef array array_byte; 
typedef array array_uint; 
typedef array array_float; 
typedef map map_int; 
typedef map map_string; 
#ifndef bool
	typedef int bool;
	#define true 1
	#define false 0
#endif

//============================== HELPER C MACROS =============================*/ 

#define _PUSH(arr, val, tmp, tmp_typ) {tmp_typ tmp = (val); array__push(arr, &tmp);}
#define _IN(typ, val, arr) array_##typ##_contains(arr, val) 
#define ALLOC_INIT(type, ...) (type *)memdup((type[]){ __VA_ARGS__ }, sizeof(type)) 
#define UTF8_CHAR_LEN( byte ) (( 0xE5000000 >> (( byte >> 3 ) & 0x1e )) & 3 ) + 1 

//================================== GLOBALS =================================*/   
//int V_ZERO = 0; 
byteptr g_str_buf; 
int load_so(byteptr);
void reload_so();
void init_consts();
 i64 total_m = 0; // For counting total RAM allocated
 int g_test_ok = 1; 
 /*================================== FNS =================================*/

typedef struct array array;
typedef array array_int;
typedef array array_string;
typedef struct string string;
typedef struct ustring ustring;
typedef array array_byte;
typedef struct map map;
typedef array array_Entry;
typedef struct Entry Entry;
typedef struct Entry2 Entry2;
typedef struct smap smap;
typedef array array_Entry2;
typedef struct Option Option;
typedef struct StringBuilder StringBuilder;
struct array {
void* data;
int len;
int cap;
int element_size;
}; 
struct string {
byte* str;
int len;
}; 
struct ustring {
string s;
array_int runes;
int len;
}; 
struct map {
int element_size;
array_Entry entries;
bool is_sorted;
}; 
struct Entry {
string key;
void* val;
}; 
struct Entry2 {
string key;
string val;
}; 
struct smap {
array_Entry2 entries;
bool is_sorted;
}; 
struct Option {
void* data;
string error;
bool ok;
}; 
struct StringBuilder {
array_byte buf;
int len;
}; 

string _STR(const char*, ...);


string _STR_TMP(const char*, ...);

array new_array(int mylen, int cap, int elm_size);
array new_array_from_c_array(int len, int cap, int elm_size, void* c_array);
array new_array_from_c_array_no_alloc(int len, int cap, int elm_size, void* c_array);
array array_repeat(void* val, int nr_repeats, int elm_size);
void array_append_array(array* a, array b);
void array_sort_with_compare(array* a, void* compare);
void array_insert(array* a, int i, void* val);
void array_prepend(array* a, void* val);
void array_delete(array* a, int idx);
void* array__get(array a, int i);
void* array_first(array a);
void* array_last(array a);
array array_left(array s, int n);
array array_right(array s, int n);
array array_slice(array s, int start, int _end);
void array_set(array* a, int idx, void* val);
void array__push(array* arr, void* val);
void array__push_many(array* arr, void* val, int size);
string array_int_str(array_int a);
void v_array_int_free(array_int a);
string array_string_str(array_string a);
void v_free(void* a);
string tos_clone(byte* s);
string tos2(byte* s);
string tos_no_len(byte* s);
string string_clone(string a);
byte* string_cstr(string s);
string string_replace(string s, string rep, string with);
int string_to_i(string s);
float string_to_float(string s);
bool string_eq(string s, string a);
bool string_ne(string s, string a);
bool string_lt(string s, string a);
bool string_le(string s, string a);
bool string_gt(string s, string a);
bool string_ge(string s, string a);
string string_add(string s, string a);
array_string string_split(string s, string delim);
array_string string_split_single(string s, byte delim);
array_string string_split_into_lines(string s);
string string_left(string s, int n);
string string_right(string s, int n);
string string_substr(string s, int start, int end);
int string_index(string s, string p);
int string_last_index(string s, string p);
int string_index_after(string s, string p, int start);
bool string_contains(string s, string p);
bool string_starts_with(string s, string p);
bool string_ends_with(string s, string p);
string string_to_lower(string s);
string string_to_upper(string s);
string string_find_between(string s, string start, string end);
bool array_string_contains(array_string ar, string val);
bool array_int_contains(array_int ar, int val);
void* array_string_to_c(array_string a);
bool is_space(byte c);
bool byte_is_space(byte c);
string string_trim_space(string s);
string string_trim(string s, byte c);
string string_trim_left(string s, string cutset);
string string_trim_right(string s, string cutset);
int compare_strings(string* a, string* b);
int compare_strings_by_len(string* a, string* b);
int compare_lower_strings(string* a, string* b);
void array_string_sort(array_string* s);
void array_string_sort_ignore_case(array_string* s);
void array_string_sort_by_len(array_string* s);
ustring string_ustring(string s);
ustring string_ustring_tmp(string s);
string ustring_substr(ustring u, int start, int end);
string ustring_left(ustring u, int pos);
string ustring_right(ustring u, int pos);
byte string_at(string s, int idx);
string ustring_at(ustring u, int idx);
void v_ustring_free(ustring u);
int abs(int a);
bool byte_is_digit(byte c);
bool byte_is_letter(byte c);
void v_string_free(string s);
void v_array_string_free(array_string arr);
string string_all_before(string s, string dot);
string string_all_before_last(string s, string dot);
string string_all_after(string s, string dot);
string array_string_join(array_string a, string del);
string array_string_join_lines(array_string s);
string string_limit(string s, int max);
bool byte_is_white(byte c);
string repeat_char(byte c, int n);
int string_hash(string s);
void v_exit(int code);
bool isnil(void* v);
void on_panic(int (*f)( int  /*FFF*/ ));
void print_backtrace();
void v_panic(string s);
void println(string s);
void eprintln(string s);
void v_print(string s);
byte* v_malloc(int n);
byte* v_calloc(int n);
int _strlen(byte* s);
Option opt_ok(void* data);
void* memdup(void* src, int sz);
Option v_error(string s);
array_int range_int(int start, int end);
string double_str(double d);
string float_str(float d);
string f64_str(f64 d);
string f32_str(f32 d);
string ptr_str(void* ptr);
string int_str(int nn);
string u8_str(u8 nn);
string i64_str(i64 nn);
string bool_str(bool b);
string int_hex(int n);
string i64_hex(i64 n);
bool array_byte_contains(array_byte a, byte val);
string byte_str(byte c);
int string_is_utf8(string s);
string utf32_to_str(u32 code);
string utf32_to_str_no_malloc(u32 code, void* buf);
int string_utf32_code(string _rune);
map new_map(int cap, int elm_size);
Entry map_new_entry(map* m, string key, void* val);
void map__set(map* m, string key, void* val);
int volt_abs(int n);
void map_bs(map m, string query, int start, int end, void* out);
int compare_map(Entry* a, Entry* b);
void map_sort(map* m);
array_string map_keys(map m);
bool map_get(map m, string key, void* out);
void v_map_print(map m);
void v_map_free(map m);
string map_string_str(map_string m);
smap new_smap();
void smap_set(smap* m, string key, string val);
string smap_get(smap m, string key);
string smap_bs(smap m, string query, int start, int end);
int compare_smap(Entry2* a, Entry2* b);
void smap_sort(smap* m);
void v_smap_free(smap m);
string smap_str(smap m);
StringBuilder new_string_builder(int initial_size);
void StringBuilder_write(StringBuilder* b, string s);
void StringBuilder_writeln(StringBuilder* b, string s);
string StringBuilder_str(StringBuilder b);
void StringBuilder_cut(StringBuilder b, int n);
int scan_int();
byte scan_char();



 array new_array(int mylen, int cap, int elm_size) {
 
array arr= (array){ .len =  mylen , .cap =  cap , .element_size =  elm_size , .data =  v_malloc ( cap * elm_size ) } ;

 
 return  arr ;
 
 
 }
 array new_array_from_c_array(int len, int cap, int elm_size, void* c_array) {
 
array arr= (array){ .len =  len , .cap =  cap , .element_size =  elm_size , .data =  v_malloc ( cap * elm_size ) } ;
 
 memcpy ( arr .data ,  c_array ,  len * elm_size ) ;

 
 return  arr ;
 
 
 }
 array new_array_from_c_array_no_alloc(int len, int cap, int elm_size, void* c_array) {
 
array arr= (array){ .len =  len , .cap =  cap , .element_size =  elm_size , .data =  c_array } ;

 
 return  arr ;
 
 
 }
 array array_repeat(void* val, int nr_repeats, int elm_size) {
 
array arr= (array){ .len =  nr_repeats , .cap =  nr_repeats , .element_size =  elm_size , .data =  v_malloc ( nr_repeats * elm_size ) } ;
 
 for (
int i= 0  ;  i < nr_repeats  ;  i ++ ) { 
 
 memcpy ( arr .data + i * elm_size ,  val ,  elm_size ) ;
 
 }
 ;

 
 return  arr ;
 
 
 }
 void array_append_array(array* a, array b) {
 
 for (
int i= 0  ;  i < b .len  ;  i ++ ) { 
 
void* val= ( *(void**) array__get( b , i) ) ;
 
 array__push( a , val ) ;
 
 }
 ;
 
 
 }
 void array_sort_with_compare(array* a, void* compare) {
 
 qsort ( a ->data ,  a ->len ,  a ->element_size ,  compare ) ;
 
 
 }
 void array_insert(array* a, int i, void* val) {
 
 if ( i >= a ->len ) {
 /*if*/
 
 v_panic ( tos2("array.insert: index larger than length") ) ;

 
 return  ;
 
 }
 ;
 
 array__push( a , val ) ;
 
int size= a ->element_size ;
 
 memmove ( a ->data + (/*lpar*/ i + 1 ) * size ,  a ->data + i * size ,  (/*lpar*/ a ->len - i ) * size ) ;
 
 array_set( a , i , val ) ;
 
 
 }
 void array_prepend(array* a, void* val) {
 
 array_insert( a , 0 , val ) ;
 
 
 }
 void array_delete(array* a, int idx) {
 
int size= a ->element_size ;
 
 memmove ( a ->data + idx * size ,  a ->data + (/*lpar*/ idx + 1 ) * size ,  (/*lpar*/ a ->len - idx ) * size ) ;
 
 a ->len -- ;
 
 a ->cap -- ;
 
 
 }
 void* array__get(array a, int i) {
 
 if ( i < 0  ||  i >= a .len ) {
 /*if*/
 
 v_panic ( _STR("array index out of range: %d/%d", i, a .len) ) ;
 
 }
 ;

 
 return  a .data + i * a .element_size ;
 
 
 }
 void* array_first(array a) {
 
 if ( a .len == 0 ) {
 /*if*/
 
 v_panic ( tos2("array.first: empty array") ) ;
 
 }
 ;

 
 return  a .data + 0 ;
 
 
 }
 void* array_last(array a) {
 
 if ( a .len == 0 ) {
 /*if*/
 
 v_panic ( tos2("array.last: empty array") ) ;
 
 }
 ;

 
 return  a .data + (/*lpar*/ a .len - 1 ) * a .element_size ;
 
 
 }
 array array_left(array s, int n) {
 
 if ( n >= s .len ) {
 /*if*/

 
 return  s ;
 
 }
 ;

 
 return  array_slice( s , 0 , n ) ;
 
 
 }
 array array_right(array s, int n) {
 
 if ( n >= s .len ) {
 /*if*/

 
 return  s ;
 
 }
 ;

 
 return  array_slice( s , n , s .len ) ;
 
 
 }
 array array_slice(array s, int start, int _end) {
 
int end= _end ;
 
 if ( start > end ) {
 /*if*/
 
 v_panic ( _STR("invalid slice index: %d > %d", start, end) ) ;
 
 }
 ;
 
 if ( end >= s .len ) {
 /*if*/
 
 end  =  s .len ;
 
 }
 ;
 
int l= end - start ;
 
array res= (array){ .element_size =  s .element_size , .data =  s .data + start * s .element_size , .len =  l , .cap =  l } ;

 
 return  res ;
 
 
 }
 void array_set(array* a, int idx, void* val) {
 
 if ( idx < 0  ||  idx >= a ->len ) {
 /*if*/
 
 v_panic ( _STR("array index out of range: %d / %d", idx, a ->len) ) ;
 
 }
 ;
 
 memcpy ( a ->data + a ->element_size * idx ,  val ,  a ->element_size ) ;
 
 
 }
 void array__push(array* arr, void* val) {
 
 if ( arr ->len >= arr ->cap - 1 ) {
 /*if*/
 
int cap= (/*lpar*/ arr ->len + 1 ) * 2 ;
 
 if ( arr ->cap == 0 ) {
 /*if*/
 
 arr ->data  =  v_malloc ( cap * arr ->element_size ) ;
 
 }
  else { 
 /*else if*/
 
 arr ->data  =  realloc ( arr ->data ,  cap * arr ->element_size ) ;
 
 }
 ;
 
 arr ->cap  =  cap ;
 
 }
 ;
 
 memcpy ( arr ->data + arr ->element_size * arr ->len ,  val ,  arr ->element_size ) ;
 
 arr ->len ++ ;
 
 
 }
 void array__push_many(array* arr, void* val, int size) {
 
 if ( arr ->len >= arr ->cap - size ) {
 /*if*/
 
int cap= (/*lpar*/ arr ->len + size ) * 2 ;
 
 if ( arr ->cap == 0 ) {
 /*if*/
 
 arr ->data  =  v_malloc ( cap * arr ->element_size ) ;
 
 }
  else { 
 /*else if*/
 
 arr ->data  =  realloc ( arr ->data ,  cap * arr ->element_size ) ;
 
 }
 ;
 
 arr ->cap  =  cap ;
 
 }
 ;
 
 memcpy ( arr ->data + arr ->element_size * arr ->len ,  val ,  arr ->element_size * size ) ;
 
 arr ->len  +=  size ;
 
 
 }
 string array_int_str(array_int a) {
 
string res= tos2("[") ;
 
 for (
int i= 0  ;  i < a .len  ;  i ++ ) { 
 
int val= ( *(int*) array__get( a , i) ) ;
 
 res = string_add(res,  _STR("%d", val) ) ;
 
 if ( i < a .len - 1 ) {
 /*if*/
 
 res = string_add(res,  tos2(", ") ) ;
 
 }
 ;
 
 }
 ;
 
 res = string_add(res,  tos2("]") ) ;

 
 return  res ;
 
 
 }
 void v_array_int_free(array_int a) {
 
 free ( a .data ) ;
 
 
 }
 string array_string_str(array_string a) {
 
string res= tos2("[") ;
 
 for (
int i= 0  ;  i < a .len  ;  i ++ ) { 
 
string val= ( *(string*) array__get( a , i) ) ;
 
 res = string_add(res,  _STR("\"%.*s\"", val.len, val.str) ) ;
 
 if ( i < a .len - 1 ) {
 /*if*/
 
 res = string_add(res,  tos2(", ") ) ;
 
 }
 ;
 
 }
 ;
 
 res = string_add(res,  tos2("]") ) ;

 
 return  res ;
 
 
 }
 void v_free(void* a) {
 
 free ( a ) ;
 
 
 }
 string tos(byte* s, int len) {
 
 if ( isnil ( s ) ) {
 /*if*/
 
 v_panic ( tos2("tos(): nil string") ) ;
 
 }
 ;

 
 return  (string){ .str =  s , .len =  len } ;
 
 
 }
 string tos_clone(byte* s) {
 
 if ( isnil ( s ) ) {
 /*if*/
 
 v_panic ( tos2("tos: nil string") ) ;

 
 return  (string){ .str = 0 , .len = 0 } ;
 
 }
 ;
 
int len= strlen ( s ) ;
 
string res= tos ( s , len ) ;

 
 return  string_clone( res ) ;
 
 
 }
 string tos2(byte* s) {
 
 if ( isnil ( s ) ) {
 /*if*/
 
 v_panic ( tos2("tos2: nil string") ) ;

 
 return  (string){ .str = 0 , .len = 0 } ;
 
 }
 ;
 
int len= strlen ( s ) ;
 
string res= tos ( s , len ) ;

 
 return  res ;
 
 
 }
 string tos_no_len(byte* s) {

 
 return  tos2 ( s ) ;
 
 
 }
 string string_clone(string a) {
 
string b= (string){ .len =  a .len , .str =  v_malloc ( a .len + 1 ) } ;
 
 for (
int i= 0  ;  i < a .len  ;  i ++ ) { 
 
 b .str[ i ]/*rbyte 1*/  =  a .str[ i ]/*rbyte 0*/ ;
 
 }
 ;
 
 b .str[ a .len ]/*rbyte 1*/  =  '\0' ;

 
 return  b ;
 
 
 }
 byte* string_cstr(string s) {
 
string clone= string_clone( s ) ;

 
 return  clone .str ;
 
 
 }
 string string_replace(string s, string rep, string with) {
 
 if ( s .len == 0  ||  rep .len == 0 ) {
 /*if*/

 
 return  tos2("") ;
 
 }
 ;
 
 if ( ! string_contains( s , rep ) ) {
 /*if*/

 
 return  s ;
 
 }
 ;
 
array_int idxs=new_array_from_c_array(0, 0, sizeof(int), (int[]) {   }) ;
 
 {
 
 }
 
 for (
int i= 0  ;  i < s .len  ;  i ++ ) { 
 
int rep_i= 0 ;
 
int j= i ;
 
 while ( rep_i < rep .len  &&  j < s .len  &&  s .str[ j ]/*rbyte 0*/ == rep .str[ rep_i ]/*rbyte 0*/ ) {
 
 rep_i ++ ;
 
 j ++ ;
 
 }
 ;
 
 if ( rep_i == rep .len ) {
 /*if*/
 
_PUSH(& idxs , ( i ), tmp12, int) ;
 
 }
 ;
 
 }
 ;
 
 if ( idxs .len == 0 ) {
 /*if*/

 
 return  s ;
 
 }
 ;
 
int new_len= s .len + idxs .len * (/*lpar*/ with .len - rep .len ) ;
 
byte* b= v_malloc ( new_len + 1 ) ;
 
int idx_pos= 0 ;
 
int cur_idx= ( *(int*) array__get( idxs , idx_pos) ) ;
 
int b_i= 0 ;
 
 for (
int i= 0  ;  i < s .len  ;  i ++ ) { 
 
 if ( i == cur_idx ) {
 /*if*/
 
 for (
int j= 0  ;  j < with .len  ;  j ++ ) { 
 
 b [/*ptr*/ b_i ]/*rbyte 1*/  =  with .str[ j ]/*rbyte 0*/ ;
 
 b_i ++ ;
 
 }
 ;
 
 i  +=  rep .len - 1 ;
 
 idx_pos ++ ;
 
 if ( idx_pos < idxs .len ) {
 /*if*/
 
 cur_idx  =  ( *(int*) array__get( idxs , idx_pos) ) ;
 
 }
 ;
 
 }
  else { 
 /*else if*/
 
 b [/*ptr*/ b_i ]/*rbyte 1*/  =  s .str[ i ]/*rbyte 0*/ ;
 
 b_i ++ ;
 
 }
 ;
 
 }
 ;
 
 b [/*ptr*/ new_len ]/*rbyte 1*/  =  '\0' ;

 
 return  tos ( b , new_len ) ;
 
 
 }
 int string_to_i(string s) {

 
 return  atoi ( s .str ) ;
 
 
 }
 float string_to_float(string s) {

 
 return  atof ( s .str ) ;
 
 
 }
 bool string_eq(string s, string a) {
 
 if ( isnil ( s .str ) ) {
 /*if*/
 
 v_panic ( tos2("string.eq(): nil string") ) ;
 
 }
 ;
 
 if ( s .len != a .len ) {
 /*if*/

 
 return  0 ;
 
 }
 ;
 
 for (
int i= 0  ;  i < s .len  ;  i ++ ) { 
 
 if ( s .str[ i ]/*rbyte 0*/ != a .str[ i ]/*rbyte 0*/ ) {
 /*if*/

 
 return  0 ;
 
 }
 ;
 
 }
 ;

 
 return  1 ;
 
 
 }
 bool string_ne(string s, string a) {

 
 return  ! string_eq( s , a ) ;
 
 
 }
 bool string_lt(string s, string a) {
 
 for (
int i= 0  ;  i < s .len  ;  i ++ ) { 
 
 if ( i >= a .len  ||  s .str[ i ]/*rbyte 0*/ > a .str[ i ]/*rbyte 0*/ ) {
 /*if*/

 
 return  0 ;
 
 }
  else  if ( s .str[ i ]/*rbyte 0*/ < a .str[ i ]/*rbyte 0*/ ) {
 /*if*/

 
 return  1 ;
 
 }
 ;
 
 }
 ;
 
 if ( s .len < a .len ) {
 /*if*/

 
 return  1 ;
 
 }
 ;

 
 return  0 ;
 
 
 }
 bool string_le(string s, string a) {

 
 return  string_lt( s , a )  ||  string_eq( s , a ) ;
 
 
 }
 bool string_gt(string s, string a) {

 
 return  ! string_le( s , a ) ;
 
 
 }
 bool string_ge(string s, string a) {

 
 return  ! string_lt( s , a ) ;
 
 
 }
 string string_add(string s, string a) {
 
int new_len= a .len + s .len ;
 
string res= (string){ .len =  new_len , .str =  v_malloc ( new_len + 1 ) } ;
 
 for (
int j= 0  ;  j < s .len  ;  j ++ ) { 
 
 res .str[ j ]/*rbyte 1*/  =  s .str[ j ]/*rbyte 0*/ ;
 
 }
 ;
 
 for (
int j= 0  ;  j < a .len  ;  j ++ ) { 
 
 res .str[ s .len + j ]/*rbyte 1*/  =  a .str[ j ]/*rbyte 0*/ ;
 
 }
 ;
 
 res .str[ new_len ]/*rbyte 1*/  =  '\0' ;

 
 return  res ;
 
 
 }
 array_string string_split(string s, string delim) {
 
array_string res=new_array_from_c_array(0, 0, sizeof(string), (string[]) {   }) ;
 
 if ( delim .len == 0 ) {
 /*if*/
 
_PUSH(& res , ( s ), tmp31, string) ;

 
 return  res ;
 
 }
 ;
 
 if ( delim .len == 1 ) {
 /*if*/

 
 return  string_split_single( s , delim .str[ 0 ]/*rbyte 0*/ ) ;
 
 }
 ;
 
int i= 0 ;
 
int start= 0 ;
 
 while ( i < s .len ) {
 
bool a= s .str[ i ]/*rbyte 0*/ == delim .str[ 0 ]/*rbyte 0*/ ;
 
int j= 1 ;
 
 while ( j < delim .len  &&  a ) {
 
 a  =  a  &&  s .str[ i + j ]/*rbyte 0*/ == delim .str[ j ]/*rbyte 0*/ ;
 
 j ++ ;
 
 }
 ;
 
bool last= i == s .len - 1 ;
 
 if ( a  ||  last ) {
 /*if*/
 
 if ( last ) {
 /*if*/
 
 i ++ ;
 
 }
 ;
 
string val= string_substr( s , start , i ) ;
 
 if ( val .len > 0 ) {
 /*if*/
 
 if ( string_starts_with( val , delim ) ) {
 /*if*/
 
 val  =  string_right( val , delim .len ) ;
 
 }
 ;
 
_PUSH(& res , ( string_trim_space( val ) ), tmp38, string) ;
 
 }
 ;
 
 start  =  i ;
 
 }
 ;
 
 i ++ ;
 
 }
 ;

 
 return  res ;
 
 
 }
 array_string string_split_single(string s, byte delim) {
 
array_string res=new_array_from_c_array(0, 0, sizeof(string), (string[]) {   }) ;
 
 if ( (/*casttt*/ (int)( /*77*/ delim ) ) == 0 ) {
 /*if*/
 
_PUSH(& res , ( s ), tmp40, string) ;

 
 return  res ;
 
 }
 ;
 
int i= 0 ;
 
int start= 0 ;
 
 while ( i < s .len ) {
 
bool a= s .str[ i ]/*rbyte 0*/ == delim ;
 
bool b= i == s .len - 1 ;
 
 if ( a  ||  b ) {
 /*if*/
 
 if ( i == s .len - 1 ) {
 /*if*/
 
 i ++ ;
 
 }
 ;
 
string val= string_substr( s , start , i ) ;
 
 if ( val .len > 0 ) {
 /*if*/
 
_PUSH(& res , ( string_trim_space( val ) ), tmp46, string) ;
 
 }
 ;
 
 start  =  i + 1 ;
 
 }
 ;
 
 i ++ ;
 
 }
 ;

 
 return  res ;
 
 
 }
 array_string string_split_into_lines(string s) {
 
array_string res=new_array_from_c_array(0, 0, sizeof(string), (string[]) {   }) ;
 
 if ( s .len == 0 ) {
 /*if*/

 
 return  res ;
 
 }
 ;
 
int start= 0 ;
 
 for (
int i= 0  ;  i < s .len  ;  i ++ ) { 
 
bool last= i == s .len - 1 ;
 
 if ( (/*casttt*/ (int)( /*77*/ s .str[ i ]/*rbyte 0*/ ) ) == 10  ||  last ) {
 /*if*/
 
 if ( last ) {
 /*if*/
 
 i ++ ;
 
 }
 ;
 
string line= string_substr( s , start , i ) ;
 
_PUSH(& res , ( line ), tmp52, string) ;
 
 start  =  i + 1 ;
 
 }
 ;
 
 }
 ;

 
 return  res ;
 
 
 }
 string string_left(string s, int n) {
 
 if ( n >= s .len ) {
 /*if*/

 
 return  s ;
 
 }
 ;

 
 return  string_substr( s , 0 , n ) ;
 
 
 }
 string string_right(string s, int n) {
 
 if ( n >= s .len ) {
 /*if*/

 
 return  tos2("") ;
 
 }
 ;

 
 return  string_substr( s , n , s .len ) ;
 
 
 }
 string string_substr(string s, int start, int end) {
 
 if ( start >= s .len ) {
 /*if*/

 
 return  tos2("") ;
 
 }
 ;
 
int len= end - start ;
 
string res= (string){ .str =  s .str + start , .len =  len } ;

 
 return  res ;
 
 
 }
 int string_index(string s, string p) {
 
 if ( p .len > s .len ) {
 /*if*/

 
 return  - 1 ;
 
 }
 ;
 
int i= 0 ;
 
 while ( i < s .len ) {
 
int j= 0 ;
 
int ii= i ;
 
 while ( j < p .len  &&  s .str[ ii ]/*rbyte 0*/ == p .str[ j ]/*rbyte 0*/ ) {
 
 j ++ ;
 
 ii ++ ;
 
 }
 ;
 
 if ( j == p .len ) {
 /*if*/

 
 return  i ;
 
 }
 ;
 
 i ++ ;
 
 }
 ;

 
 return  - 1 ;
 
 
 }
 int string_last_index(string s, string p) {
 
 if ( p .len > s .len ) {
 /*if*/

 
 return  - 1 ;
 
 }
 ;
 
int i= s .len - p .len ;
 
 while ( i >= 0 ) {
 
int j= 0 ;
 
 while ( j < p .len  &&  s .str[ i + j ]/*rbyte 0*/ == p .str[ j ]/*rbyte 0*/ ) {
 
 j ++ ;
 
 }
 ;
 
 if ( j == p .len ) {
 /*if*/

 
 return  i ;
 
 }
 ;
 
 i -- ;
 
 }
 ;

 
 return  - 1 ;
 
 
 }
 int string_index_after(string s, string p, int start) {
 
 if ( p .len > s .len ) {
 /*if*/

 
 return  - 1 ;
 
 }
 ;
 
int strt= start ;
 
 if ( start < 0 ) {
 /*if*/
 
 strt  =  0 ;
 
 }
 ;
 
 if ( start >= s .len ) {
 /*if*/

 
 return  - 1 ;
 
 }
 ;
 
int i= strt ;
 
 while ( i < s .len ) {
 
int j= 0 ;
 
int ii= i ;
 
 while ( j < p .len  &&  s .str[ ii ]/*rbyte 0*/ == p .str[ j ]/*rbyte 0*/ ) {
 
 j ++ ;
 
 ii ++ ;
 
 }
 ;
 
 if ( j == p .len ) {
 /*if*/

 
 return  i ;
 
 }
 ;
 
 i ++ ;
 
 }
 ;

 
 return  - 1 ;
 
 
 }
 bool string_contains(string s, string p) {
 
bool res= string_index( s , p ) > 0 - 1 ;

 
 return  res ;
 
 
 }
 bool string_starts_with(string s, string p) {
 
bool res= string_index( s , p ) == 0 ;

 
 return  res ;
 
 
 }
 bool string_ends_with(string s, string p) {
 
 if ( p .len > s .len ) {
 /*if*/

 
 return  0 ;
 
 }
 ;
 
bool res= string_last_index( s , p ) == s .len - p .len ;

 
 return  res ;
 
 
 }
 string string_to_lower(string s) {
 
byte* b= v_malloc ( s .len ) ;
 
 for (
int i= 0  ;  i < s .len  ;  i ++ ) { 
 
 b [/*ptr*/ i ]/*rbyte 1*/  =  tolower ( s .str [/*ptr*/ i ]/*rbyte 0*/ ) ;
 
 }
 ;

 
 return  tos ( b , s .len ) ;
 
 
 }
 string string_to_upper(string s) {
 
byte* b= v_malloc ( s .len ) ;
 
 for (
int i= 0  ;  i < s .len  ;  i ++ ) { 
 
 b [/*ptr*/ i ]/*rbyte 1*/  =  toupper ( s .str [/*ptr*/ i ]/*rbyte 0*/ ) ;
 
 }
 ;

 
 return  tos ( b , s .len ) ;
 
 
 }
 string string_find_between(string s, string start, string end) {
 
int start_pos= string_index( s , start ) ;
 
 if ( start_pos == - 1 ) {
 /*if*/

 
 return  tos2("") ;
 
 }
 ;
 
string val= string_right( s , start_pos + start .len ) ;
 
int end_pos= string_index( val , end ) ;
 
 if ( end_pos == - 1 ) {
 /*if*/

 
 return  val ;
 
 }
 ;

 
 return  string_left( val , end_pos ) ;
 
 
 }
 bool array_string_contains(array_string ar, string val) {
 
 array_string tmp74 =  ar;
 ;
for (int tmp75 = 0; tmp75 < tmp74 .len; tmp75 ++) {
 string s = ((string *) tmp74.data)[tmp75];
 
 if (string_eq( s , val ) ) {
 /*if*/

 
 return  1 ;
 
 }
 ;
 
 }
 ;

 
 return  0 ;
 
 
 }
 bool array_int_contains(array_int ar, int val) {
 
 array_int tmp76 =  ar ;
 ;
for (int i = 0; i < tmp76 .len; i ++) {
 int s = ((int *) tmp76 . data)[i];
 
 if ( s == val ) {
 /*if*/

 
 return  1 ;
 
 }
 ;
 
 }
 ;

 
 return  0 ;
 
 
 }
 void* array_string_to_c(array_string a) {
 
 char ** res = malloc(sizeof(char*) * a.len);
 
 for (
int i= 0  ;  i < a .len  ;  i ++ ) { 
 
string val= ( *(string*) array__get( a , i) ) ;
 
 res[i] = val.str;
 
 }
 ;
 
 return res;

 
 return  0 ;
 
 
 }
 bool is_space(byte c) {

 
 return  isspace ( c ) ;
 
 
 }
 bool byte_is_space(byte c) {

 
 return  is_space ( c ) ;
 
 
 }
 string string_trim_space(string s) {
 
 if (string_eq( s , tos2("") ) ) {
 /*if*/

 
 return  tos2("") ;
 
 }
 ;
 
int i= 0 ;
 
 while ( i < s .len  &&  is_space ( s .str[ i ]/*rbyte 0*/ ) ) {
 
 i ++ ;
 
 }
 ;
 
string res= string_right( s , i ) ;
 
int end= res .len - 1 ;
 
 while ( end >= 0  &&  is_space ( res .str[ end ]/*rbyte 1*/ ) ) {
 
 end -- ;
 
 }
 ;
 
 res  =  string_left( res , end + 1 ) ;

 
 return  res ;
 
 
 }
 string string_trim(string s, byte c) {
 
 if (string_eq( s , tos2("") ) ) {
 /*if*/

 
 return  tos2("") ;
 
 }
 ;
 
int i= 0 ;
 
 while ( i < s .len  &&  c == s .str[ i ]/*rbyte 0*/ ) {
 
 i ++ ;
 
 }
 ;
 
string res= string_right( s , i ) ;
 
int end= res .len - 1 ;
 
 while ( end >= 0  &&  c == res .str[ end ]/*rbyte 1*/ ) {
 
 end -- ;
 
 }
 ;
 
 res  =  string_left( res , end + 1 ) ;

 
 return  res ;
 
 
 }
 string string_trim_left(string s, string cutset) {
 
int start= string_index( s , cutset ) ;
 
 if ( start != 0 ) {
 /*if*/

 
 return  s ;
 
 }
 ;
 
 while ( start < s .len - 1  &&  s .str[ start ]/*rbyte 0*/ == cutset .str[ 0 ]/*rbyte 0*/ ) {
 
 start ++ ;
 
 }
 ;

 
 return  string_right( s , start ) ;
 
 
 }
 string string_trim_right(string s, string cutset) {
 
int pos= string_last_index( s , cutset ) ;
 
 if ( pos == - 1 ) {
 /*if*/

 
 return  s ;
 
 }
 ;

 
 return  string_left( s , pos ) ;
 
 
 }
 int compare_strings(string* a, string* b) {
 
 if ( string_lt(* a ,* b ) ) {
 /*if*/

 
 return  - 1 ;
 
 }
 ;
 
 if ( string_gt(* a ,* b ) ) {
 /*if*/

 
 return  1 ;
 
 }
 ;

 
 return  0 ;
 
 
 }
 int compare_strings_by_len(string* a, string* b) {
 
 if ( a ->len < b ->len ) {
 /*if*/

 
 return  - 1 ;
 
 }
 ;
 
 if ( a ->len > b ->len ) {
 /*if*/

 
 return  1 ;
 
 }
 ;

 
 return  0 ;
 
 
 }
 int compare_lower_strings(string* a, string* b) {
 
string aa= string_to_lower(* a ) ;
 
string bb= string_to_lower(* a ) ;

 
 return  compare_strings (& /*11 EXP:"string*" GOT:"string" */ aa ,& /*11 EXP:"string*" GOT:"string" */ bb ) ;
 
 
 }
 void array_string_sort(array_string* s) {
 
 array_sort_with_compare( s , compare_strings ) ;
 
 
 }
 void array_string_sort_ignore_case(array_string* s) {
 
 array_sort_with_compare( s , compare_lower_strings ) ;
 
 
 }
 void array_string_sort_by_len(array_string* s) {
 
 array_sort_with_compare( s , compare_strings_by_len ) ;
 
 
 }
 ustring string_ustring(string s) {
 
ustring res= (ustring){ .s =  s , .runes =  new_array ( 0 , s .len , sizeof( int) ) , .len = 0 } ;
 
 for (
int i= 0  ;  i < s .len  ;  i ++ ) { 
 
int char_len= 0 ;
 
 char_len =UTF8_CHAR_LEN(s.str[i]);
 
_PUSH(& res .runes , ( i ), tmp94, int) ;
 
 i  +=  char_len - 1 ;
 
 res .len ++ ;
 
 }
 ;

 
 return  res ;
 
 
 }
 array_int g_ustring_runes;
 ustring string_ustring_tmp(string s) {
 
ustring res= (ustring){ .s =  s , .runes =  0 , .len = 0 } ;
 
 res.runes = g_ustring_runes ;
 
 res.runes.len = s.len ;
 
int j= 0 ;
 
 for (
int i= 0  ;  i < s .len  ;  i ++ ) { 
 
int char_len= 0 ;
 
 char_len =UTF8_CHAR_LEN(s.str[i]);
int tmp99 =  i;
 
array_set(&/*q*/ res .runes , j , & tmp99) ;
 
 j ++ ;
 
 i  +=  char_len - 1 ;
 
 res .len ++ ;
 
 }
 ;

 
 return  res ;
 
 
 }
 string ustring_substr(ustring u, int start, int end) {
 
 start  =  ( *(int*) array__get( u .runes , start) ) ;
 
 if ( end >= u .runes .len ) {
 /*if*/
 
 end  =  u .s .len ;
 
 }
  else { 
 /*else if*/
 
 end  =  ( *(int*) array__get( u .runes , end) ) ;
 
 }
 ;

 
 return  string_substr( u .s , start , end ) ;
 
 
 }
 string ustring_left(ustring u, int pos) {

 
 return  ustring_substr( u , 0 , pos ) ;
 
 
 }
 string ustring_right(ustring u, int pos) {

 
 return  ustring_substr( u , pos , u .len ) ;
 
 
 }
 byte string_at(string s, int idx) {
 
 if ( idx < 0  ||  idx >= s .len ) {
 /*if*/
 
 v_panic ( _STR("string index out of range: %d / %d", idx, s .len) ) ;
 
 }
 ;

 
 return  s .str [/*ptr*/ idx ]/*rbyte 0*/ ;
 
 
 }
 string ustring_at(ustring u, int idx) {

 
 return  ustring_substr( u , idx , idx + 1 ) ;
 
 
 }
 void v_ustring_free(ustring u) {
 
 v_array_int_free( u .runes ) ;
 
 
 }
 int abs(int a) {
 
 if ( a >= 0 ) {
 /*if*/

 
 return  a ;
 
 }
 ;

 
 return  - a ;
 
 
 }
 bool byte_is_digit(byte c) {

 
 return  c >= '0'  &&  c <= '9' ;
 
 
 }
 bool byte_is_letter(byte c) {

 
 return  (/*lpar*/ c >= 'a'  &&  c <= 'z' )  ||  (/*lpar*/ c >= 'A'  &&  c <= 'Z' ) ;
 
 
 }
 void v_string_free(string s) {
 
 free ( s .str ) ;
 
 
 }
 void v_array_string_free(array_string arr) {
 
 array_string tmp104 =  arr;
 ;
for (int tmp105 = 0; tmp105 < tmp104 .len; tmp105 ++) {
 string s = ((string *) tmp104.data)[tmp105];
 
 v_string_free( s ) ;
 
 }
 ;
 
 free ( arr .data ) ;
 
 
 }
 string string_all_before(string s, string dot) {
 
int pos= string_index( s , dot ) ;
 
 if ( pos == - 1 ) {
 /*if*/

 
 return  s ;
 
 }
 ;

 
 return  string_left( s , pos ) ;
 
 
 }
 string string_all_before_last(string s, string dot) {
 
int pos= string_last_index( s , dot ) ;
 
 if ( pos == - 1 ) {
 /*if*/

 
 return  s ;
 
 }
 ;

 
 return  string_left( s , pos ) ;
 
 
 }
 string string_all_after(string s, string dot) {
 
int pos= string_last_index( s , dot ) ;
 
 if ( pos == - 1 ) {
 /*if*/

 
 return  s ;
 
 }
 ;

 
 return  string_right( s , pos + dot .len ) ;
 
 
 }
 string array_string_join(array_string a, string del) {
 
 if ( a .len == 0 ) {
 /*if*/

 
 return  tos2("") ;
 
 }
 ;
 
int len= 0 ;
 
 array_string tmp110 =  a ;
 ;
for (int i = 0; i < tmp110 .len; i ++) {
 string val = ((string *) tmp110 . data)[i];
 
 len  +=  val .len + del .len ;
 
 }
 ;
 
 len  -=  del .len ;
 
string res= tos2("") ;
 
 res .len  =  len ;
 
 res .str  =  v_malloc ( res .len + 1 ) ;
 
int idx= 0 ;
 
 array_string tmp113 =  a ;
 ;
for (int i = 0; i < tmp113 .len; i ++) {
 string val = ((string *) tmp113 . data)[i];
 
 for (
int j= 0  ;  j < val .len  ;  j ++ ) { 
 
byte c= val .str[ j ]/*rbyte 0*/ ;
 
 res .str [/*ptr*/ idx ]/*rbyte 1*/  =  val .str [/*ptr*/ j ]/*rbyte 0*/ ;
 
 idx ++ ;
 
 }
 ;
 
 if ( i != a .len - 1 ) {
 /*if*/
 
 for (
int k= 0  ;  k < del .len  ;  k ++ ) { 
 
 res .str [/*ptr*/ idx ]/*rbyte 1*/  =  del .str [/*ptr*/ k ]/*rbyte 0*/ ;
 
 idx ++ ;
 
 }
 ;
 
 }
 ;
 
 }
 ;
 
 res .str [/*ptr*/ res .len ]/*rbyte 1*/  =  '\0' ;

 
 return  res ;
 
 
 }
 string array_string_join_lines(array_string s) {

 
 return  array_string_join( s , tos2("\n") ) ;
 
 
 }
 string string_limit(string s, int max) {
 
ustring u= string_ustring( s ) ;
 
 if ( u .len <= max ) {
 /*if*/

 
 return  s ;
 
 }
 ;

 
 return  ustring_substr( u , 0 , max ) ;
 
 
 }
 bool byte_is_white(byte c) {
 
int i= (/*casttt*/ (int)( /*77*/ c ) ) ;

 
 return  i == 10  ||  i == 32  ||  i == 9  ||  i == 13  ||  c == '\r' ;
 
 
 }
 string repeat_char(byte c, int n) {
 
 if ( n <= 0 ) {
 /*if*/

 
 return  tos2("") ;
 
 }
 ;
 
byte* arr= v_malloc ( n + 1 ) ;
 
 for (
int i= 0  ;  i < n  ;  i ++ ) { 
 
 arr [/*ptr*/ i ]/*rbyte 1*/  =  c ;
 
 }
 ;
 
 arr [/*ptr*/ n ]/*rbyte 1*/  =  '\0' ;

 
 return  tos ( arr , n ) ;
 
 
 }
 int string_hash(string s) {
 
int hash= (/*casttt*/ (int)( /*77*/ 0 ) ) ;
 
 for (
int i= 0  ;  i < s .len  ;  i ++ ) { 
 
 hash  =  hash * (/*casttt*/ (int)( /*77*/ 31 ) ) + (/*casttt*/ (int)( /*77*/ s .str [/*ptr*/ i ]/*rbyte 0*/ ) ) ;
 
 }
 ;

 
 return  hash ;
 
 
 }
 void v_exit(int code) {
 
 exit ( code ) ;
 
 
 }
 bool isnil(void* v) {

 
 return  v == 0 ;
 
 
 }
 void on_panic(int (*f)( int  /*FFF*/ )) {
 
 
 }
 void print_backtrace() {

 
 return  ;
 
 #ifdef mac
 
voidptr buffer  [100 ]= {} /* arkek init*/ ;
 
void* nr_ptrs= backtrace ( buffer ,  100 ) ;
 
 backtrace_symbols_fd ( buffer ,  nr_ptrs ,  1 ) ;
 
 #endif
 ;
 
 
 }
 void v_panic(string s) {
 
 println ( _STR("V panic: %.*s", s.len, s.str) ) ;
 
 print_backtrace ( ) ;
 
 exit ( 1 ) ;
 
 
 }
 void println(string s) {
 
 if ( isnil ( s .str ) ) {
 /*if*/
 
 v_panic ( tos2("println(NIL)") ) ;
 
 }
 ;
 
 printf ( "%.*s\n" ,  s .len ,  s .str ) ;
 
 
 }
 void eprintln(string s) {
 
 if ( isnil ( s .str ) ) {
 /*if*/
 
 v_panic ( tos2("eprintln(NIL)") ) ;
 
 }
 ;
 
 #ifdef mac
 
 fprintf ( stderr ,  "%.*s\n" ,  s .len ,  s .str ) ;
 
 ;
 
 #else
 
 println ( s ) ;
 
 #endif
 ;
 
 
 }
 void v_print(string s) {
 
 printf ( "%.*s" ,  s .len ,  s .str ) ;
 
 
 }
 byte* v_malloc(int n) {
 
 if ( n < 0 ) {
 /*if*/
 
 v_panic ( tos2("malloc(<0)") ) ;
 
 }
 ;
 
 #ifdef VPLAY
 
 if ( n > 10000 ) {
 /*if*/
 
 v_panic ( tos2("allocating more than 10 KB is not allowed in the playground") ) ;
 
 }
 ;
 
 #endif
 
 #ifdef DEBUG_ALLOC
 
i64 total= (/*casttt*/ (i64)( /*77*/ 0 ) ) ;
 
 total_m += n;
 
 total = total_m;
 
 println ( _STR("\n\n\nmalloc(%d) total=%lld", n, total) ) ;
 
 print_backtrace ( ) ;
 
 #endif
 
byte* ptr= malloc ( n ) ;
 
 if ( isnil ( ptr ) ) {
 /*if*/
 
 v_panic ( _STR("malloc(%d) failed", n) ) ;
 
 }
 ;

 
 return  ptr ;
 
 
 }
 byte* v_calloc(int n) {
 
 if ( n < 0 ) {
 /*if*/
 
 v_panic ( tos2("calloc(<0)") ) ;
 
 }
 ;

 
 return  calloc ( n ,  1 ) ;
 
 
 }
 int _strlen(byte* s) {

 
 return  strlen ( s ) ;
 
 
 }
 Option opt_ok(void* data) {

 
 return  (Option){ .data =  data , .ok =  1 , .error = tos("", 0) , } ;
 
 
 }
 void* memdup(void* src, int sz) {
 
byte* mem= v_malloc ( sz ) ;

 
 return  memcpy ( mem ,  src ,  sz ) ;
 
 
 }
 Option v_error(string s) {

 
 return  (Option){ .error =  s , .data = 0 , .ok = 0 } ;
 
 
 }
 array_int range_int(int start, int end) {
 
int len= end - start ;
int tmp7 =  0;
 
array_int res= array_repeat(&tmp7,  len , sizeof(int) ) ;
 
 for (
int i= 0  ;  i < len  ;  i ++ ) { 
int tmp10 =  start + i;
 
array_set(&/*q*/ res , i , & tmp10) ;
 
 }
 ;

 
 return  res ;
 
 
 }
 string double_str(double d) {
 
byte* buf= v_malloc ( sizeof( double) * 5 + 1 ) ;
 
 sprintf ( buf ,  "%f" ,  d ) ;

 
 return  tos ( buf , _strlen ( buf ) ) ;
 
 
 }
 string float_str(float d) {
 
byte* buf= v_malloc ( sizeof( double) * 5 + 1 ) ;
 
 sprintf ( buf ,  "%f" ,  d ) ;

 
 return  tos ( buf , _strlen ( buf ) ) ;
 
 
 }
 string f64_str(f64 d) {
 
byte* buf= v_malloc ( sizeof( double) * 5 + 1 ) ;
 
 sprintf ( buf ,  "%f" ,  d ) ;

 
 return  tos ( buf , _strlen ( buf ) ) ;
 
 
 }
 string f32_str(f32 d) {
 
byte* buf= v_malloc ( sizeof( double) * 5 + 1 ) ;
 
 sprintf ( buf ,  "%f" ,  d ) ;

 
 return  tos ( buf , _strlen ( buf ) ) ;
 
 
 }
 string ptr_str(void* ptr) {
 
byte* buf= v_malloc ( sizeof( double) * 5 + 1 ) ;
 
 sprintf ( buf ,  "%p" ,  ptr ) ;

 
 return  tos ( buf , _strlen ( buf ) ) ;
 
 
 }
 string int_str(int nn) {
 
int n= nn ;
 
 if ( n == 0 ) {
 /*if*/

 
 return  tos2("0") ;
 
 }
 ;
 
int max= 16 ;
 
byte* buf= v_malloc ( max ) ;
 
int len= 0 ;
 
bool is_neg= 0 ;
 
 if ( n < 0 ) {
 /*if*/
 
 n  =  - n ;
 
 is_neg  =  1 ;
 
 }
 ;
 
 while ( n > 0 ) {
 
int d= n % 10 ;
 
 buf [/*ptr*/ max - len - 1 ]/*rbyte 1*/  =  d + (/*casttt*/ (int)( /*77*/ '0' ) ) ;
 
 len ++ ;
 
 n  =  n / 10 ;
 
 }
 ;
 
 if ( is_neg ) {
 /*if*/
 
 buf [/*ptr*/ max - len - 1 ]/*rbyte 1*/  =  '-' ;
 
 len ++ ;
 
 }
 ;

 
 return  tos ( buf + max - len , len ) ;
 
 
 }
 string u8_str(u8 nn) {
 
u8 n= nn ;
 
 if ( n == (/*casttt*/ (u8)( /*77*/ 0 ) ) ) {
 /*if*/

 
 return  tos2("0") ;
 
 }
 ;
 
int max= 5 ;
 
byte* buf= v_malloc ( max ) ;
 
int len= 0 ;
 
bool is_neg= 0 ;
 
 if ( n < (/*casttt*/ (u8)( /*77*/ 0 ) ) ) {
 /*if*/
 
 n  =  - n ;
 
 is_neg  =  1 ;
 
 }
 ;
 
 while ( n > (/*casttt*/ (u8)( /*77*/ 0 ) ) ) {
 
u8 d= n % (/*casttt*/ (u8)( /*77*/ 10 ) ) ;
 
 buf [/*ptr*/ max - len - 1 ]/*rbyte 1*/  =  d + (/*casttt*/ (u8)( /*77*/ '0' ) ) ;
 
 len ++ ;
 
 n  =  n / (/*casttt*/ (u8)( /*77*/ 10 ) ) ;
 
 }
 ;
 
 if ( is_neg ) {
 /*if*/
 
 buf [/*ptr*/ max - len - 1 ]/*rbyte 1*/  =  '-' ;
 
 len ++ ;
 
 }
 ;

 
 return  tos ( buf + max - len , len ) ;
 
 
 }
 string i64_str(i64 nn) {
 
i64 n= nn ;
 
 if ( n == (/*casttt*/ (i64)( /*77*/ 0 ) ) ) {
 /*if*/

 
 return  tos2("0") ;
 
 }
 ;
 
int max= 32 ;
 
byte* buf= v_malloc ( max ) ;
 
int len= 0 ;
 
bool is_neg= 0 ;
 
 if ( n < (/*casttt*/ (i64)( /*77*/ 0 ) ) ) {
 /*if*/
 
 n  =  - n ;
 
 is_neg  =  1 ;
 
 }
 ;
 
 while ( n > (/*casttt*/ (i64)( /*77*/ 0 ) ) ) {
 
int d= (/*casttt*/ (int)( /*77*/ n % (/*casttt*/ (i64)( /*77*/ 10 ) ) ) ) ;
 
 buf [/*ptr*/ max - len - 1 ]/*rbyte 1*/  =  d + (/*casttt*/ (int)( /*77*/ '0' ) ) ;
 
 len ++ ;
 
 n  =  n / (/*casttt*/ (i64)( /*77*/ 10 ) ) ;
 
 }
 ;
 
 if ( is_neg ) {
 /*if*/
 
 buf [/*ptr*/ max - len - 1 ]/*rbyte 1*/  =  '-' ;
 
 len ++ ;
 
 }
 ;

 
 return  tos ( buf + max - len , len ) ;
 
 
 }
 string bool_str(bool b) {
 
 if ( b ) {
 /*if*/

 
 return  tos2("true") ;
 
 }
 ;

 
 return  tos2("false") ;
 
 
 }
 string int_hex(int n) {
 
string s= int_str( n ) ;
 
byte* hex= v_malloc ( s .len + 2 ) ;
 
 sprintf ( hex ,  "0x%x" ,  n ) ;

 
 return  tos ( hex , s .len + 2 ) ;
 
 
 }
 string i64_hex(i64 n) {
 
string s= i64_str( n ) ;
 
byte* hex= v_malloc ( s .len + 2 ) ;
 
 sprintf ( hex ,  "0x%x" ,  n ) ;

 
 return  tos ( hex , s .len + 2 ) ;
 
 
 }
 bool array_byte_contains(array_byte a, byte val) {
 
 array_byte tmp28 =  a;
 ;
for (int tmp29 = 0; tmp29 < tmp28 .len; tmp29 ++) {
 byte aa = ((byte *) tmp28.data)[tmp29];
 
 if ( aa == val ) {
 /*if*/

 
 return  1 ;
 
 }
 ;
 
 }
 ;

 
 return  0 ;
 
 
 }
 string byte_str(byte c) {
 
string str= (string){ .len =  1 , .str =  v_malloc ( 2 ) } ;
 
 str .str [/*ptr*/ 0 ]/*rbyte 1*/  =  c ;
 
 str .str [/*ptr*/ 1 ]/*rbyte 1*/  =  '\0' ;

 
 return  str ;
 
 
 }
 int string_is_utf8(string s) {
 
int faulty_bytes= 0 ;
 
int len= s .len ;
 
int i= 0 ;
 
 byte * str = s.str;
 
 
 
 while (i < len) {
 
 if (str[i] <= 0x7F) /* 00..7F */ {
 
 i += 1;
 
 }
 
 else if (str[i] >= 0xC2 && str[i] <= 0xDF) /* C2..DF 80..BF */ {
 
 if (i + 1 < len) /* Expect a 2nd byte */ {
 
 if (str[i + 1] < 0x80 || str[i + 1] > 0xBF) {
 
 printf( "After a first byte between C2 and DF, expecting a 2nd byte between 80 and BF");
 
 faulty_bytes = 2;
 
 goto end;
 
 }
 
 }
 
 else {
 
 printf( "After a first byte between C2 and DF, expecting a 2nd byte.");
 
 faulty_bytes = 1;
 
 goto end;
 
 }
 
 i += 2;
 
 }
 
 else if (str[i] == 0xE0) /* E0 A0..BF 80..BF */ {
 
 if (i + 2 < len) /* Expect a 2nd and 3rd byte */ {
 
 if (str[i + 1] < 0xA0 || str[i + 1] > 0xBF) {
 
 printf( "After a first byte of E0, expecting a 2nd byte between A0 and BF.");
 
 faulty_bytes = 2;
 
 goto end;
 
 }
 
 if (str[i + 2] < 0x80 || str[i + 2] > 0xBF) {
 
 printf( "After a first byte of E0, expecting a 3nd byte between 80 and BF.");
 
 faulty_bytes = 3;
 
 goto end;
 
 }
 
 }
 
 else {
 
 printf( "After a first byte of E0, expecting two following bytes.");
 
 faulty_bytes = 1;
 
 goto end;
 
 }
 
 i += 3;
 
 }
 
 else if (str[i] >= 0xE1 && str[i] <= 0xEC) /* E1..EC 80..BF 80..BF */ {
 
 if (i + 2 < len) /* Expect a 2nd and 3rd byte */ {
 
 if (str[i + 1] < 0x80 || str[i + 1] > 0xBF) {
 
 printf( "After a first byte between E1 and EC, expecting the 2nd byte between 80 and BF.");
 
 faulty_bytes = 2;
 
 goto end;
 
 }
 
 if (str[i + 2] < 0x80 || str[i + 2] > 0xBF) {
 
 printf( "After a first byte between E1 and EC, expecting the 3rd byte between 80 and BF.");
 
 faulty_bytes = 3;
 
 goto end;
 
 }
 
 }
 
 else {
 
 printf( "After a first byte between E1 and EC, expecting two following bytes.");
 
 faulty_bytes = 1;
 
 goto end;
 
 }
 
 i += 3;
 
 }
 
 else if (str[i] == 0xED) /* ED 80..9F 80..BF */ {
 
 if (i + 2 < len) /* Expect a 2nd and 3rd byte */ {
 
 if (str[i + 1] < 0x80 || str[i + 1] > 0x9F) {
 
 printf( "After a first byte of ED, expecting 2nd byte between 80 and 9F.");
 
 faulty_bytes = 2;
 
 goto end;
 
 }
 
 if (str[i + 2] < 0x80 || str[i + 2] > 0xBF) {
 
 printf( "After a first byte of ED, expecting 3rd byte between 80 and BF.");
 
 faulty_bytes = 3;
 
 goto end;
 
 }
 
 }
 
 else {
 
 printf( "After a first byte of ED, expecting two following bytes.");
 
 faulty_bytes = 1;
 
 goto end;
 
 }
 
 i += 3;
 
 }
 
 else if (str[i] >= 0xEE && str[i] <= 0xEF) /* EE..EF 80..BF 80..BF */ {
 
 if (i + 2 < len) /* Expect a 2nd and 3rd byte */ {
 
 if (str[i + 1] < 0x80 || str[i + 1] > 0xBF) {
 
 printf( "After a first byte between EE and EF, expecting 2nd byte between 80 and BF.");
 
 faulty_bytes = 2;
 
 goto end;
 
 }
 
 if (str[i + 2] < 0x80 || str[i + 2] > 0xBF) {
 
 printf( "After a first byte between EE and EF, expecting 3rd byte between 80 and BF.");
 
 faulty_bytes = 3;
 
 goto end;
 
 }
 
 }
 
 else {
 
 printf( "After a first byte between EE and EF, two following bytes.");
 
 faulty_bytes = 1;
 
 goto end;
 
 }
 
 i += 3;
 
 }
 
 else if (str[i] == 0xF0) /* F0 90..BF 80..BF 80..BF */ {
 
 if (i + 3 < len) /* Expect a 2nd, 3rd 3th byte */ {
 
 if (str[i + 1] < 0x90 || str[i + 1] > 0xBF) {
 
 printf( "After a first byte of F0, expecting 2nd byte between 90 and BF.");
 
 faulty_bytes = 2;
 
 goto end;
 
 }
 
 if (str[i + 2] < 0x80 || str[i + 2] > 0xBF) {
 
 printf( "After a first byte of F0, expecting 3rd byte between 80 and BF.");
 
 faulty_bytes = 3;
 
 goto end;
 
 }
 
 if (str[i + 3] < 0x80 || str[i + 3] > 0xBF) {
 
 printf( "After a first byte of F0, expecting 4th byte between 80 and BF.");
 
 faulty_bytes = 4;
 
 goto end;
 
 }
 
 }
 
 else {
 
 printf( "After a first byte of F0, expecting three following bytes.");
 
 faulty_bytes = 1;
 
 goto end;
 
 }
 
 i += 4;
 
 }
 
 else if (str[i] >= 0xF1 && str[i] <= 0xF3) /* F1..F3 80..BF 80..BF 80..BF */ {
 
 if (i + 3 < len) /* Expect a 2nd, 3rd 3th byte */ {
 
 if (str[i + 1] < 0x80 || str[i + 1] > 0xBF) {
 
 printf( "After a first byte of F1, F2, or F3, expecting a 2nd byte between 80 and BF.");
 
 faulty_bytes = 2;
 
 goto end;
 
 }
 
 if (str[i + 2] < 0x80 || str[i + 2] > 0xBF) {
 
 printf( "After a first byte of F1, F2, or F3, expecting a 3rd byte between 80 and BF.");
 
 faulty_bytes = 3;
 
 goto end;
 
 }
 
 if (str[i + 3] < 0x80 || str[i + 3] > 0xBF) {
 
 printf( "After a first byte of F1, F2, or F3, expecting a 4th byte between 80 and BF.");
 
 faulty_bytes = 4;
 
 goto end;
 
 }
 
 }
 
 else {
 
 printf( "After a first byte of F1, F2, or F3, expecting three following bytes.");
 
 faulty_bytes = 1;
 
 goto end;
 
 }
 
 i += 4;
 
 }
 
 else if (str[i] == 0xF4) /* F4 80..8F 80..BF 80..BF */ {
 
 if (i + 3 < len) /* Expect a 2nd, 3rd 3th byte */ {
 
 if (str[i + 1] < 0x80 || str[i + 1] > 0x8F) {
 
 printf( "After a first byte of F4, expecting 2nd byte between 80 and 8F.");
 
 faulty_bytes = 2;
 
 goto end;
 
 }
 
 if (str[i + 2] < 0x80 || str[i + 2] > 0xBF) {
 
 printf( "After a first byte of F4, expecting 3rd byte between 80 and BF.");
 
 faulty_bytes = 3;
 
 goto end;
 
 }
 
 if (str[i + 3] < 0x80 || str[i + 3] > 0xBF) {
 
 printf( "After a first byte of F4, expecting 4th byte between 80 and BF.");
 
 faulty_bytes = 4;
 
 goto end;
 
 }
 
 }
 
 else {
 
 printf( "After a first byte of F4, expecting three following bytes.");
 
 faulty_bytes = 1;
 
 goto end;
 
 }
 
 i += 4;
 
 }
 
 else {
 
 printf( "i=%d Expecting bytes in the following ranges: 00..7F C2..F4.",
 
 i);
 
 faulty_bytes = 1;
 
 goto end;
 
 }
 
 }
 
 
 
 end: ;
 
bool ok= faulty_bytes == 0 ;
 
 if ( ok ) {
 /*if*/

 
 return  - 1 ;
 
 }
 ;
 
 if ( ! ok ) {
 /*if*/
 
 println ( _STR("utf is bad dalen=%d KEK %.*s sdf", len, s.len, s.str) ) ;
 
 }
 ;

 
 return  i ;
 
 
 }
 string utf32_to_str(u32 code) {
 
byte* buffer= v_malloc ( 5 ) ;
 
 if (code <= 0x7F) {
 
 buffer[0] = code;
 
 return tos(buffer, 1);
 
 }
 
 if (code <= 0x7FF) {
 
 buffer[0] = 0xC0 | (code >> 6);            /* 110xxxxx */
 
 buffer[1] = 0x80 | (code & 0x3F);          /* 10xxxxxx */
 
 return tos(buffer, 2);
 
 }
 
 if (code <= 0xFFFF) {
 
 buffer[0] = 0xE0 | (code >> 12);           /* 1110xxxx */
 
 buffer[1] = 0x80 | ((code >> 6) & 0x3F);   /* 10xxxxxx */
 
 buffer[2] = 0x80 | (code & 0x3F);          /* 10xxxxxx */
 
 return tos(buffer, 3);
 
 }
 
 if (code <= 0x10FFFF) {
 
 buffer[0] = 0xF0 | (code >> 18);           /* 11110xxx */
 
 buffer[1] = 0x80 | ((code >> 12) & 0x3F);  /* 10xxxxxx */
 
 buffer[2] = 0x80 | ((code >> 6) & 0x3F);   /* 10xxxxxx */
 
 buffer[3] = 0x80 | (code & 0x3F);          /* 10xxxxxx */
 
 return tos(buffer, 4);
 
 }

 
 return  tos2("") ;
 
 
 }
 string utf32_to_str_no_malloc(u32 code, void* buf) {
 
 char* buffer = buf;
 
 if (code <= 0x7F) {
 
 buffer[0] = code;
 
 return tos(buffer, 1);
 
 }
 
 if (code <= 0x7FF) {
 
 buffer[0] = 0xC0 | (code >> 6);            /* 110xxxxx */
 
 buffer[1] = 0x80 | (code & 0x3F);          /* 10xxxxxx */
 
 return tos(buffer, 2);
 
 }
 
 if (code <= 0xFFFF) {
 
 buffer[0] = 0xE0 | (code >> 12);           /* 1110xxxx */
 
 buffer[1] = 0x80 | ((code >> 6) & 0x3F);   /* 10xxxxxx */
 
 buffer[2] = 0x80 | (code & 0x3F);          /* 10xxxxxx */
 
 return tos(buffer, 3);
 
 }
 
 if (code <= 0x10FFFF) {
 
 buffer[0] = 0xF0 | (code >> 18);           /* 11110xxx */
 
 buffer[1] = 0x80 | ((code >> 12) & 0x3F);  /* 10xxxxxx */
 
 buffer[2] = 0x80 | ((code >> 6) & 0x3F);   /* 10xxxxxx */
 
 buffer[3] = 0x80 | (code & 0x3F);          /* 10xxxxxx */
 
 return tos(buffer, 4);
 
 }

 
 return  tos2("") ;
 
 
 }
 int string_utf32_code(string _rune) {
 
 if ( _rune .len == 0 ) {
 /*if*/

 
 return  0 ;
 
 }
 ;
 
 if ( _rune .len == 1 ) {
 /*if*/

 
 return  (/*casttt*/ (int)( /*77*/ _rune .str[ 0 ]/*rbyte 0*/ ) ) ;
 
 }
 ;
 
byte b= (/*casttt*/ (byte)( /*77*/ (/*casttt*/ (int)( /*77*/ _rune .str[ 0 ]/*rbyte 0*/ ) ) ) ) ;
 
 b <<= _rune.len;
 
int res= (/*casttt*/ (int)( /*77*/ b ) ) ;
 
int shift= 6 - _rune .len ;
 
 for (
int i= 1  ;  i < _rune .len  ;  i ++ ) { 
 
int c= (/*casttt*/ (int)( /*77*/ _rune .str[ i ]/*rbyte 0*/ ) ) ;
 
 res <<= shift;
 
 res |= c & 0x3f;
 
 shift  =  6 ;
 
 }
 ;

 
 return  res ;
 
 
 }
 map new_map(int cap, int elm_size) {
 
map res= (map){ .element_size =  elm_size , .entries = new_array(0, 1, sizeof(Entry)) , .is_sorted = 0 } ;

 
 return  res ;
 
 
 }
 Entry map_new_entry(map* m, string key, void* val) {
 
Entry new_e= (Entry){ .key =  key , .val =  v_malloc ( m ->element_size ) } ;
 
 memcpy ( new_e .val ,  val ,  m ->element_size ) ;

 
 return  new_e ;
 
 
 }
 void map__set(map* m, string key, void* val) {
 
Entry e= map_new_entry(& /* ? */* m , key , val ) ;
 
 for (
int i= 0  ;  i < m ->entries .len  ;  i ++ ) { 
 
Entry entry= ( *(Entry*) array__get( m ->entries , i) ) ;
 
 if (string_eq( entry .key , key ) ) {
 /*if*/
Entry tmp8 =  e;
 
array_set(&/*q*/ m ->entries , i , & tmp8) ;

 
 return  ;
 
 }
 ;
 
 }
 ;
 
_PUSH(& m ->entries , ( e ), tmp9, Entry) ;
 
 m ->is_sorted  =  0 ;
 
 
 }
 int volt_abs(int n) {
 
 if ( n < 0 ) {
 /*if*/

 
 return  - n ;
 
 }
 ;

 
 return  n ;
 
 
 }
 void map_bs(map m, string query, int start, int end, void* out) {
 
int mid= start + (/*lpar*/ (/*lpar*/ end - start ) / 2 ) ;
 
 if ( end - start == 0 ) {
 /*if*/
 
Entry last= ( *(Entry*) array__get( m .entries , end) ) ;
 
 memcpy ( out ,  last .val ,  m .element_size ) ;

 
 return  ;
 
 }
 ;
 
 if ( end - start == 1 ) {
 /*if*/
 
Entry first= ( *(Entry*) array__get( m .entries , start) ) ;
 
 memcpy ( out ,  first .val ,  m .element_size ) ;

 
 return  ;
 
 }
 ;
 
 if ( mid >= m .entries .len ) {
 /*if*/

 
 return  ;
 
 }
 ;
 
Entry mid_msg= ( *(Entry*) array__get( m .entries , mid) ) ;
 
 if (string_lt( query , mid_msg .key ) ) {
 /*if*/
 
 map_bs( m , query , start , mid , out ) ;

 
 return  ;
 
 }
 ;
 
 map_bs( m , query , mid , end , out ) ;
 
 
 }
 int compare_map(Entry* a, Entry* b) {
 
 if (string_lt( a ->key , b ->key ) ) {
 /*if*/

 
 return  - 1 ;
 
 }
 ;
 
 if (string_gt( a ->key , b ->key ) ) {
 /*if*/

 
 return  1 ;
 
 }
 ;

 
 return  0 ;
 
 
 }
 void map_sort(map* m) {
 
 array_sort_with_compare(& /* ? */ m ->entries , compare_map ) ;
 
 m ->is_sorted  =  1 ;
 
 
 }
 array_string map_keys(map m) {
 
array_string keys=new_array_from_c_array(0, 0, sizeof(string), (string[]) {   }) ;
 
 {
 
 }
 
 for (
int i= 0  ;  i < m .entries .len  ;  i ++ ) { 
 
Entry entry= ( *(Entry*) array__get( m .entries , i) ) ;
 
_PUSH(& keys , ( entry .key ), tmp25, string) ;
 
 }
 ;

 
 return  keys ;
 
 
 }
 bool map_get(map m, string key, void* out) {
 
 if ( m .is_sorted ) {
 /*if*/
 
 map_bs( m , key , 0 , m .entries .len , out ) ;

 
 return  1 ;
 
 }
 ;
 
 for (
int i= 0  ;  i < m .entries .len  ;  i ++ ) { 
 
Entry entry= ( *(Entry*) array__get( m .entries , i) ) ;
 
 if (string_eq( entry .key , key ) ) {
 /*if*/
 
 memcpy ( out ,  entry .val ,  m .element_size ) ;

 
 return  1 ;
 
 }
 ;
 
 }
 ;

 
 return  0 ;
 
 
 }
 void v_map_print(map m) {
 
 println ( tos2("<<<<<<<<") ) ;
 
 for (
int i= 0  ;  i < m .entries .len  ;  i ++ ) { 
 
 }
 ;
 
 println ( tos2(">>>>>>>>>>") ) ;
 
 
 }
 void v_map_free(map m) {
 
 
 }
 string map_string_str(map_string m) {
 
 if ( m .entries .len == 0 ) {
 /*if*/

 
 return  tos2("{}") ;
 
 }
 ;
 
string s= tos2("{\n") ;
 
 array_Entry tmp32 =  m .entries;
 ;
for (int tmp33 = 0; tmp33 < tmp32 .len; tmp33 ++) {
 Entry entry = ((Entry *) tmp32.data)[tmp33];
string tmp34 = tos("", 0); bool tmp35 = map_get( m , entry .key, & tmp34);
if (!tmp35) tmp34 = tos("", 0);
 
string val= tmp34 ;
 
 s = string_add(s,  _STR("  \"%.*s\" => \"%.*s\"\n", entry .key.len, entry .key.str, val.len, val.str) ) ;
 
 }
 ;
 
 s = string_add(s,  tos2("}") ) ;

 
 return  s ;
 
 
 }
 smap new_smap() {
 
smap res= (smap){ .entries = new_array(0, 1, sizeof(Entry2)) , .is_sorted = 0 } ;

 
 return  res ;
 
 
 }
 void smap_set(smap* m, string key, string val) {
 
Entry2 e= (Entry2){ .key =  key , .val =  val } ;
 
_PUSH(& m ->entries , ( e ), tmp3, Entry2) ;
 
 
 }
 string smap_get(smap m, string key) {
 
 if ( m .is_sorted ) {
 /*if*/

 
 return  smap_bs( m , key , 0 , m .entries .len ) ;
 
 }
 ;
 
 for (
int i= 0  ;  i < m .entries .len  ;  i ++ ) { 
 
Entry2 entry= ( *(Entry2*) array__get( m .entries , i) ) ;
 
 if (string_eq( entry .key , key ) ) {
 /*if*/

 
 return  entry .val ;
 
 }
 ;
 
 }
 ;

 
 return  tos2("") ;
 
 
 }
 string smap_bs(smap m, string query, int start, int end) {
 
int mid= start + (/*lpar*/ (/*lpar*/ end - start ) / 2 ) ;
 
 if ( end - start == 0 ) {
 /*if*/
 
Entry2 last= ( *(Entry2*) array__get( m .entries , end) ) ;

 
 return  last .val ;
 
 }
 ;
 
 if ( end - start == 1 ) {
 /*if*/
 
Entry2 first= ( *(Entry2*) array__get( m .entries , start) ) ;

 
 return  first .val ;
 
 }
 ;
 
 if ( mid >= m .entries .len ) {
 /*if*/

 
 return  tos2("") ;
 
 }
 ;
 
Entry2 mid_msg= ( *(Entry2*) array__get( m .entries , mid) ) ;
 
 if (string_lt( query , mid_msg .key ) ) {
 /*if*/

 
 return  smap_bs( m , query , start , mid ) ;
 
 }
 ;

 
 return  smap_bs( m , query , mid , end ) ;
 
 
 }
 int compare_smap(Entry2* a, Entry2* b) {
 
 if (string_lt( a ->key , b ->key ) ) {
 /*if*/

 
 return  - 1 ;
 
 }
 ;
 
 if (string_gt( a ->key , b ->key ) ) {
 /*if*/

 
 return  1 ;
 
 }
 ;

 
 return  0 ;
 
 
 }
 void smap_sort(smap* m) {
 
 array_sort_with_compare(& /* ? */ m ->entries , compare_smap ) ;
 
 m ->is_sorted  =  1 ;
 
 
 }
 void v_smap_free(smap m) {
 
 
 }
 string smap_str(smap m) {
 
 if ( m .entries .len == 0 ) {
 /*if*/

 
 return  tos2("{}") ;
 
 }
 ;
 
string s= tos2("{\n") ;
 
 array_Entry2 tmp19 =  m .entries;
 ;
for (int tmp20 = 0; tmp20 < tmp19 .len; tmp20 ++) {
 Entry2 entry = ((Entry2 *) tmp19.data)[tmp20];
 
 s = string_add(s,  _STR("  \"%.*s\" => \"%.*s\"\n", entry .key.len, entry .key.str, entry .val.len, entry .val.str) ) ;
 
 }
 ;
 
 s = string_add(s,  tos2("}") ) ;

 
 return  s ;
 
 
 }
 StringBuilder new_string_builder(int initial_size) {

 
 return  (StringBuilder){ .buf =  new_array ( 0 , initial_size , sizeof( byte) ) , .len = 0 } ;
 
 
 }
 void StringBuilder_write(StringBuilder* b, string s) {
 
 array__push_many(& /* ? */ b ->buf , s .str , s .len ) ;
 
 b ->len  +=  s .len ;
 
 
 }
 void StringBuilder_writeln(StringBuilder* b, string s) {
 
 array__push_many(& /* ? */ b ->buf , s .str , s .len ) ;
 
_PUSH(& b ->buf , ( '\n' ), tmp1, byte) ;
 
 b ->len  +=  s .len + 1 ;
 
 
 }
 string StringBuilder_str(StringBuilder b) {

 
 return  tos ( b .buf .data , b .len ) ;
 
 
 }
 void StringBuilder_cut(StringBuilder b, int n) {
 
 b .len  -=  n ;
 
 
 }
 int scan_int() {
 
string scanner= tos2("%d") ;
 
int scanned= 0 ;
 
 scanf ( string_cstr( scanner ) ,  & /*vvar*/  scanned ) ;

 
 return  scanned ;
 
 
 }
 byte scan_char() {
 
string scanner= tos2("%c") ;
 
byte scanned= (/*casttt*/ (byte)( /*77*/ 0 ) ) ;
 
 scanf ( string_cstr( scanner ) ,  & /*vvar*/  scanned ) ;

 
 return  scanned ;
 
 
 }
 int main(int argc, char** argv) {
 init_consts();
 
array_byte chars=new_array_from_c_array(4, 4, sizeof(byte), (byte[]) {  scan_char ( ) , scan_char ( ) , scan_char ( ) , scan_char ( )  }) ;
 
 println ( ( ( *(byte*) array__get( chars , 0) ) == ( *(byte*) array__get( chars , 1) )  ||  ( *(byte*) array__get( chars , 1) ) == ( *(byte*) array__get( chars , 2) )  ||  ( *(byte*) array__get( chars , 2) ) == ( *(byte*) array__get( chars , 3) ) ) ? ( tos2("Bad") ) : ( tos2("Good") ) ) ;
 
 
 }
 void init_consts() { g_str_buf=malloc(1000);  }
 
string _STR(const char *fmt, ...) {
	va_list argptr;
	va_start(argptr, fmt);
	size_t len = vsnprintf(0, 0, fmt, argptr) + 1;  
	va_end(argptr);
	byte* buf = malloc(len);  
	va_start(argptr, fmt);
	vsprintf(buf, fmt, argptr);
	va_end(argptr);
#ifdef DEBUG_ALLOC 
	puts("_STR:"); 
	puts(buf); 
#endif 
	return tos2(buf);
}

string _STR_TMP(const char *fmt, ...) {
	va_list argptr;
	va_start(argptr, fmt);
	size_t len = vsnprintf(0, 0, fmt, argptr) + 1;  
	va_end(argptr);
	va_start(argptr, fmt);
	vsprintf(g_str_buf, fmt, argptr);
	va_end(argptr);
#ifdef DEBUG_ALLOC 
	//puts("_STR_TMP:"); 
	//puts(g_str_buf); 
#endif 
	return tos2(g_str_buf);
}




Measured memory_bytes: 256