#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
/* public */
enum jn_json_type
{
JN_STRING=1,
JN_NUMBER,
JN_TRUE,
JN_FALSE,
JN_NULL,
JN_ARRAY,
JN_OBJECT,
JN_KEYVALUE
};
/* public */
typedef struct jn_tok_st
{
char* s;
int len;
}
jn_tok_t;
/* public */
typedef struct jn_json_st jn_json_t;
/* private */
typedef struct jn_json_st
{
int type;
jn_tok_t k;
struct jn_json_st* v;
struct jn_json_st* r; /* right */
#ifdef JN_AVLTREE
struct jn_json_st* l;
struct jn_json_st* p;
#endif
}
jn_json_t;
#define JN_ALLOCATOR
#undef JN_ALLOCATOR
#define JN_ALLOCATOR
/* public */
typedef struct jn_alloc_st
{
jn_json_t* (*alloc) (int, struct jn_alloc_st*);
void (*free) (jn_json_t
* ,struct jn_alloc_st
*); #ifdef JN_ALLOCATOR
jn_json_t* nodes;
int cnt;
#endif
}
jn_alloc_t;
#define JN_MAX_LIMIT (0x100000)
/* public */
void jn_init_alloc(jn_alloc_t* a);
int jn_parse(jn_alloc_t* a, char* in_buf, jn_json_t** out_json);
void jn_print_json(jn_json_t* json);
/* private */
jn_json_t* jn_alloc_json (int size, jn_alloc_t* a);
void jn_free_json (jn_json_t* n , jn_alloc_t* a);
int jn_scan(char* in_buf, jn_tok_t* out_toks, int* out_len);
void _jn_print_json(jn_json_t* json, int indent, int kv);
/* optimized tokenizer */
int jn_scan(char* in_buf, jn_tok_t* out_toks, int* out_len)
{
static int eqcls[256] = {
0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x2, 0x2, 0x0, 0x0, 0x2, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x2, 0x0, 0x33, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x1000, 0x1, 0x1104, 0x400, 0x20,
0x2e84, 0x2f84, 0x2f84, 0x2f84, 0x2f84, 0x2f84, 0x2f84, 0x2f84,
0x2f84, 0x2f84, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x80, 0x80, 0x80, 0x80, 0x880, 0x80, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x1, 0x38, 0x1, 0x0, 0x0,
0x0, 0x20080, 0xa0, 0x80, 0x80, 0x110880, 0xa6, 0x0,
0x0, 0x0, 0x0, 0x0, 0x440000, 0x0, 0x27, 0x0,
0x0, 0x0, 0x4020, 0x80000, 0x25, 0x208040, 0x0, 0x0,
0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
};
static int tbl[] = {
0x200, 0xa00, 0x7000d01, 0x7000c01, 0x3030e09, 0x3080a18, 0x10e0e36, 0x1110e3c,
0x1150e44, 0x3031609, 0x1200, 0x7001501, 0x305160d, 0x1a00, 0x3031e09, 0x1071e10,
0x2200, 0x1072612, 0x2a00, 0x1072e14, 0x3200, 0x1073616, 0x3a00, 0x3033e09,
0x4200, 0x308461c, 0x3084620, 0x3084624, 0x4a00, 0x4a00, 0x3084e20, 0x3084e24,
0x30a5228, 0x5200, 0x5200, 0x5200, 0x30a5a28, 0x5a00, 0x3085e24, 0x3085e24,
0x7006101, 0x30a662c, 0x30c6630, 0x6200, 0x7006901, 0x6a00, 0x30c6e30, 0x30a6e2c,
0x7200, 0x30c7633, 0x30c7633, 0x7007901, 0x7a00, 0x30c7e33, 0x8200, 0x10f8638,
0x8a00, 0x1108e3a, 0x9200, 0x7009501, 0x9a00, 0x1129e3e, 0xa200, 0x113a640,
0xaa00, 0x114ae42, 0xb200, 0x700b501, 0xba00, 0x116be46, 0xc200, 0x116c648,
0xca00, 0x700cd01 };
//start = 0x7000201
char* p = in_buf;
char* s = in_buf;
jn_tok_t* t = out_toks;
int state = 0x7000201;
unsigned int cls = 0;
do
{
p += (state>>10) & 0x1;
t->s = s;
t->len = p - s;
t += (state>>8) & 0x1;
s += (p - s) & (UINT_MAX + ((state>>9) & 0x1));
cls = eqcls[(unsigned char)(*p)];
cls = (cls>>((state & 0x00FF0000)>>16))&(state>>24);
state = tbl[ (state & 0x000000FF) + cls ];
}
while( (state & 0x000000FF) > 0);
*out_len = t - out_toks;
if(*p == 0)
{
return 1; /* SUCCESS */
}
cls = ((state & 0xf800) >> 11); /* fail state idx */
if(cls < 1) /* fail state idx */
{
/* fail msg */
}
return 0;
}
/* simple memory allocator */
void jn_init_alloc(jn_alloc_t* a)
{
#ifdef JN_ALLOCATOR
static jn_json_t json_nodes[JN_MAX_LIMIT];
memset(json_nodes
, 0x00 ,sizeof(json_nodes
)); a->nodes = json_nodes;
a->cnt = 0;
#endif
a->alloc = jn_alloc_json;
}
jn_json_t* jn_alloc_json (int size, jn_alloc_t* a)
{
jn_json_t* ret = NULL;
#ifdef JN_ALLOCATOR
ret = &(a->nodes[a->cnt]);
a->cnt += size;
#else
ret
= (jn_json_t
*)malloc( size
* sizeof(jn_json_t
));#endif
memset(ret
, 0x00, size
* sizeof(sizeof(jn_json_t
))); return ret;
}
void jn_free_json (jn_json_t* n , jn_alloc_t* a)
{
#ifdef JN_ALLOCATOR
/* pass */
#else
#endif
}
typedef struct jn_stack_st
{
int state;
jn_tok_t* token;
jn_json_t* json;
int cls;
}
jn_stack_t;
int jn_parse(jn_alloc_t* a, char* in_buf, jn_json_t** out_json)
{
static int eqcls[] = {
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,8 ,2 ,0 ,0 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,11 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,6 ,0 ,7 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
4 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,5 ,0 ,0 ,0 ,0 ,0 ,3 ,0 ,0 ,0 ,0 ,0 ,0 ,9 ,0 ,10 ,0 ,0
};
static int tbl[] = {
0, 4, 6, 7, 8, 9, 10, 0, 0, 5, 0, 0, 1, 2, 0, 3, 0, 0,
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31, 0, 0, 0, 0, 0, 0, 31, 31, 0, 31, 0, 0, 0, 0, 0, 0, 0,
32, 0, 0, 0, 0, 0, 0, 32, 32, 0, 32, 0, 0, 0, 0, 0, 0, 0,
26, 0, 0, 0, 0, 0, 0, 26, 26, 0, 26, 0, 0, 0, 0, 0, 0, 0,
0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 11, 12,
27, 0, 0, 0, 0, 0, 0, 27, 27, 0, 27, 0, 0, 0, 0, 0, 0, 0,
28, 0, 0, 0, 0, 0, 0, 28, 28, 0, 28, 0, 0, 0, 0, 0, 0, 0,
29, 0, 0, 0, 0, 0, 0, 29, 29, 0, 29, 0, 0, 0, 0, 0, 0, 0,
30, 0, 0, 0, 0, 0, 0, 30, 30, 0, 30, 0, 0, 0, 0, 0, 0, 0,
0, 4, 6, 7, 8, 9, 10, 17, 0, 5, 0, 0, 15, 2, 16, 3, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 39, 0, 0, 0, 0, 0, 0, 0,
37, 0, 0, 0, 0, 0, 0, 37, 37, 0, 37, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 35, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
33, 0, 0, 0, 0, 0, 0, 33, 33, 0, 33, 0, 0, 0, 0, 0, 0, 0,
38, 0, 0, 0, 0, 0, 0, 38, 38, 0, 38, 0, 0, 0, 0, 0, 0, 0,
0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 12,
0, 4, 6, 7, 8, 9, 10, 0, 0, 5, 0, 0, 24, 2, 0, 3, 0, 0,
0, 4, 6, 7, 8, 9, 10, 0, 0, 5, 0, 0, 15, 2, 25, 3, 0, 0,
34, 0, 0, 0, 0, 0, 0, 34, 34, 0, 34, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 41, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static jn_stack_t stack[JN_MAX_LIMIT];
/* */
static jn_tok_t toks[JN_MAX_LIMIT];
int tok_len = 0;
int tok_idx = 0;
int ret = 0;
/* */
int state =0;
int top = 0; /* stack top */
int top_state = 0;
int top_cls = 0;
jn_tok_t* top_tok = NULL;
jn_json_t* top_json = NULL;
/* tokenizing */
ret = jn_scan(in_buf, toks, &tok_len);
if(ret == 0)
{
return 0; /* fail */
}
toks[tok_len].s = "";
toks[tok_len].len = 0;
tok_idx = 0;
/* parsing */
do
{
jn_tok_t* t = &(toks[tok_idx]);
int cls = eqcls[(unsigned char)(*toks[tok_idx].s)];
state = tbl[stack[top].state * 18 + cls];
switch(state)
{
case 0:
break;
/* value: STR | NUM | TRUE | FALSE | NULL */
case 26: case 27: case 28: case 29: case 30:
top_json = a->alloc(1, a); /* alloc */
top_json->type = state - 25;
top_json->k = *(stack[top].token);
top -= 1;
top_cls = 12; /* value */
top_state = tbl[stack[top].state * 18 + top_cls];
top_tok = NULL;
break;
/* value: array | object */
case 31: case 32:
top_json = stack[top].json; /* pass */
top -= 1;
top_cls = 12; /* value */
top_state = tbl[stack[top].state * 18 + top_cls];
top_tok = NULL;
break;
/* array: [] */
case 33:
top_json = a->alloc(1, a); /* alloc */
top_json->type = JN_ARRAY;
top -= 2;
top_cls = 13; /* array */
top_state = tbl[stack[top].state * 18 + top_cls];
top_tok = NULL;
break;
/* array: [ elements ] */
case 34:
top_json = a->alloc(1, a); /* alloc */
top_json->type = JN_ARRAY;
top_json->v = stack[top-1].json;
top -= 3;
top_cls = 13; /* array */
top_state = tbl[stack[top].state * 18 + top_cls];
top_tok = NULL;
break;
/* elements: value */
case 35:
top_json = stack[top].json; /* pass */
top -= 1;
top_cls = 14; /* elements */
top_state = tbl[stack[top].state * 18 + top_cls];
top_tok = NULL;
break;
/* elements: value , elements */
case 36:
top_json = stack[top-2].json;
top_json->r = stack[top].json;
top -= 3;
top_cls = 14; /* elements */
top_state = tbl[stack[top].state * 18 + top_cls];
top_tok = NULL;
break;
/* object: {} */
case 37:
top_json = a->alloc(1, a); /* alloc */
top_json->type = JN_OBJECT;
top -= 2;
top_cls = 15; /* object */
top_state = tbl[stack[top].state * 18 + top_cls];
top_tok = NULL;
break;
/* object: { members } */
case 38:
top_json = a->alloc(1, a); /* alloc */
top_json->type = JN_OBJECT;
top_json->v = stack[top-1].json;
top -= 3;
top_cls = 15; /* object */
top_state = tbl[stack[top].state * 18 + top_cls];
top_tok = NULL;
break;
/* members: member */
case 39:
top_json = stack[top].json; /* pass */
top -= 1;
top_cls = 16; /* members */
top_state = tbl[stack[top].state * 18 + top_cls];
top_tok = NULL;
break;
/* members: member , members */
case 40:
top_json = stack[top-2].json;
top_json->r = stack[top].json;
top -= 3;
top_cls = 16; /* members */
top_state = tbl[stack[top].state * 18 + top_cls];
top_tok = NULL;
break;
/* member : str : value */
case 41:
top_json = a->alloc(1, a); /* alloc */
top_json->type = JN_KEYVALUE;
top_json->k = *(stack[top-2].token);
top_json->v = stack[top].json;
top -= 3;
top_cls = 17; /* members */
top_state = tbl[stack[top].state * 18 + top_cls];
top_tok = NULL;
break;
default:
/* shift */
top_cls = cls;
top_state = state;
top_tok = t;
top_json = NULL;
tok_idx++;
break;
}
if(state > 0)
{
top++;
stack[top].cls = top_cls;
stack[top].state = top_state;
stack[top].token = top_tok;
stack[top].json = top_json;
}
}while(state > 0 && tok_idx <= tok_len);
if(state == -1) /* accept */
{
*out_json = stack[top].json;
return 1; /* success */
}
else
{
/* TODO: free all json memory */
*out_json = NULL;
}
return 0;
}
void jn_print_json(jn_json_t* json)
{
_jn_print_json(json, 0, 0);
}
void _jn_print_json(jn_json_t* json, int indent, int kv)
{
if(json != NULL)
{
int i=0;
for(i=0; i < indent && kv == 0; i++)
{
}
switch(json->type)
{
case JN_STRING:
case JN_NUMBER:
case JN_TRUE:
case JN_FALSE:
case JN_NULL:
printf("%.*s", json
->k.
len, json
->k.
s); break;
case JN_ARRAY:
_jn_print_json(json->v, indent+1, 0);
for(i=0; i < indent; i++)
{
}
break;
case JN_OBJECT:
_jn_print_json(json->v, indent+1, 0);
for(i=0; i < indent; i++)
{
}
break;
case JN_KEYVALUE:
printf("%.*s: ", json
->k.
len, json
->k.
s); _jn_print_json(json->v, indent, 1);
break;
}
if(json->r != NULL)
{
_jn_print_json(json->r, indent, 0);
}
else
{
}
}
}
/* LALR table
-------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-
[ ] | $ | str | num | true | false | null | [ | ] | , | { | } | = | value | array | elements | object | members | member |
-------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-
[ 0] | | s 4 | s 6 | s 7 | s 8 | s 9 | s 10 | | | s 5 | | | 1 | 2 | | 3 | | |
[ 1] | ACC | | | | | | | | | | | | | | | | | |
[ 2] | r 6 | | | | | | | r 6 | r 6 | | r 6 | | | | | | | |
[ 3] | r 7 | | | | | | | r 7 | r 7 | | r 7 | | | | | | | |
[ 4] | r 1 | | | | | | | r 1 | r 1 | | r 1 | | | | | | | |
[ 5] | | s 14 | | | | | | | | | s 13 | | | | | | 11 | 12 |
[ 6] | r 2 | | | | | | | r 2 | r 2 | | r 2 | | | | | | | |
[ 7] | r 3 | | | | | | | r 3 | r 3 | | r 3 | | | | | | | |
[ 8] | r 4 | | | | | | | r 4 | r 4 | | r 4 | | | | | | | |
[ 9] | r 5 | | | | | | | r 5 | r 5 | | r 5 | | | | | | | |
[ 10] | | s 4 | s 6 | s 7 | s 8 | s 9 | s 10 | s 17 | | s 5 | | | 15 | 2 | 16 | 3 | | |
[ 11] | | | | | | | | | | | s 18 | | | | | | | |
[ 12] | | | | | | | | | s 19 | | r 14 | | | | | | | |
[ 13] | r 12 | | | | | | | r 12 | r 12 | | r 12 | | | | | | | |
[ 14] | | | | | | | | | | | | s 20 | | | | | | |
[ 15] | | | | | | | | r 10 | s 21 | | | | | | | | | |
[ 16] | | | | | | | | s 22 | | | | | | | | | | |
[ 17] | r 8 | | | | | | | r 8 | r 8 | | r 8 | | | | | | | |
[ 18] | r 13 | | | | | | | r 13 | r 13 | | r 13 | | | | | | | |
[ 19] | | s 14 | | | | | | | | | | | | | | | 23 | 12 |
[ 20] | | s 4 | s 6 | s 7 | s 8 | s 9 | s 10 | | | s 5 | | | 24 | 2 | | 3 | | |
[ 21] | | s 4 | s 6 | s 7 | s 8 | s 9 | s 10 | | | s 5 | | | 15 | 2 | 25 | 3 | | |
[ 22] | r 9 | | | | | | | r 9 | r 9 | | r 9 | | | | | | | |
[ 23] | | | | | | | | | | | r 15 | | | | | | | |
[ 24] | | | | | | | | | r 16 | | r 16 | | | | | | | |
[ 25] | | | | | | | | r 11 | | | | | | | | | | |
-------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-
value: str | num | true | false | null | array | object ;
array: [ ] | [ elements ] ;
elements: value | value , elements ;
object: { } | { members } ;
members: member | member , members ;
member: str = value ;
*/
int main(void)
{
jn_alloc_t a;
char* succ_json1 = "{\"key1\": \"this is test json\", \"key2\": [0, 1, 12, 0.123, 12.234, -293, -394.294E-23]}";
char* succ_json2 = "{\"gram\":[{\"head\":\"value\",\"body\":[\"str\"],\"op\":\"str\"},{\"head\":\"value\",\"body\":[\"num\"],\"op\":\"num\"},{\"head\":\"value\",\"body\":[\"true\"],\"op\":\"true\"},{\"head\":\"value\",\"body\":[\"false\"],\"op\":\"false\"},{\"head\":\"value\",\"body\":[\"null\"],\"op\":\"null\"},{\"head\":\"value\",\"body\":[\"array\"],\"op\":null},{\"head\":\"value\",\"body\":[\"object\"],\"op\":null},{\"head\":\"array\",\"body\":[\"[\",\"]\"],\"op\":\"]\"},{\"head\":\"array\",\"body\":[\"[\",\"elements\",\"]\"],\"op\":\"]\"},{\"head\":\"elements\",\"body\":[\"value\"],\"op\":null},{\"head\":\"elements\",\"body\":[\"value\",\",\",\"elements\"],\"op\":\",\"},{\"head\":\"object\",\"body\":[\"{\",\"}\"],\"op\":\"}\"},{\"head\":\"object\",\"body\":[\"{\",\"members\",\"}\"],\"op\":\"}\"},{\"head\":\"members\",\"body\":[\"member\"],\"op\":null},{\"head\":\"members\",\"body\":[\"member\",\",\",\"members\"],\"op\":\",\"},{\"head\":\"member\",\"body\":[\"str\",\"=\",\"value\"],\"op\":\"=\"}],\"non\":{\"value\":0,\"array\":1,\"elements\":2,\"object\":3,\"members\":4,\"member\":5},\"ter\":{\"str\":0,\"num\":1,\"true\":2,\"false\":3,\"null\":4,\"[\":5,\"]\":6,\",\":7,\"{\":8,\"}\":9,\"=\":10}}";
jn_json_t* out = NULL;
out = NULL;
jn_init_alloc(&a);
if(jn_parse(&a, succ_json1, &out))
jn_print_json(out);
out = NULL;
jn_init_alloc(&a);
if(jn_parse(&a, succ_json2, &out))
jn_print_json(out);
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPGxpbWl0cy5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CgovKiBwdWJsaWMgKi8KZW51bSBqbl9qc29uX3R5cGUKewoJSk5fU1RSSU5HPTEsCglKTl9OVU1CRVIsCglKTl9UUlVFLAoJSk5fRkFMU0UsCglKTl9OVUxMLAoJSk5fQVJSQVksCglKTl9PQkpFQ1QsCglKTl9LRVlWQUxVRQp9OwoKLyogcHVibGljICovCnR5cGVkZWYgc3RydWN0IGpuX3Rva19zdCAgCnsKCWNoYXIqIHM7CglpbnQgbGVuOwp9CmpuX3Rva190OwoKLyogcHVibGljICovCnR5cGVkZWYgc3RydWN0IGpuX2pzb25fc3Qgam5fanNvbl90OwoKLyogcHJpdmF0ZSAqLwp0eXBlZGVmIHN0cnVjdCBqbl9qc29uX3N0CnsKCWludCB0eXBlOwoJam5fdG9rX3QgIGs7IAoJc3RydWN0IGpuX2pzb25fc3QqIHY7CglzdHJ1Y3Qgam5fanNvbl9zdCogcjsgLyogcmlnaHQgKi8KI2lmZGVmIEpOX0FWTFRSRUUKCXN0cnVjdCBqbl9qc29uX3N0KiBsOwoJc3RydWN0IGpuX2pzb25fc3QqIHA7CiNlbmRpZgp9CmpuX2pzb25fdDsKCgojZGVmaW5lIEpOX0FMTE9DQVRPUgojdW5kZWYgIEpOX0FMTE9DQVRPUgojZGVmaW5lIEpOX0FMTE9DQVRPUgoKLyogIHB1YmxpYyAqLwp0eXBlZGVmIHN0cnVjdCBqbl9hbGxvY19zdAp7Cglqbl9qc29uX3QqICgqYWxsb2MpIChpbnQsIHN0cnVjdCBqbl9hbGxvY19zdCopOwoJdm9pZCAgICAgICAgKCpmcmVlKSAoam5fanNvbl90KiAsc3RydWN0IGpuX2FsbG9jX3N0Kik7CiNpZmRlZiBKTl9BTExPQ0FUT1IKCWpuX2pzb25fdCogbm9kZXM7CglpbnQgICAgICAgIGNudDsKI2VuZGlmCn0Kam5fYWxsb2NfdDsKCgojZGVmaW5lIEpOX01BWF9MSU1JVCAoMHgxMDAwMDApCgoKCgovKiBwdWJsaWMgICovCnZvaWQgam5faW5pdF9hbGxvYyhqbl9hbGxvY190KiBhKTsKaW50IGpuX3BhcnNlKGpuX2FsbG9jX3QqIGEsIGNoYXIqIGluX2J1Ziwgam5fanNvbl90Kiogb3V0X2pzb24pOwp2b2lkIGpuX3ByaW50X2pzb24oam5fanNvbl90KiBqc29uKTsKCgovKiBwcml2YXRlICovCmpuX2pzb25fdCogam5fYWxsb2NfanNvbiAoaW50IHNpemUsIGpuX2FsbG9jX3QqIGEpOwp2b2lkIGpuX2ZyZWVfanNvbiAgKGpuX2pzb25fdCogbiAsIGpuX2FsbG9jX3QqIGEpOwppbnQgam5fc2NhbihjaGFyKiBpbl9idWYsIGpuX3Rva190KiBvdXRfdG9rcywgaW50KiBvdXRfbGVuKTsKdm9pZCBfam5fcHJpbnRfanNvbihqbl9qc29uX3QqIGpzb24sIGludCBpbmRlbnQsIGludCBrdik7CgoKLyogb3B0aW1pemVkIHRva2VuaXplciAqLwppbnQgam5fc2NhbihjaGFyKiBpbl9idWYsIGpuX3Rva190KiBvdXRfdG9rcywgaW50KiBvdXRfbGVuKQp7CglzdGF0aWMgaW50IGVxY2xzWzI1Nl0gPSB7CgkgICAgICAgMHg4LCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAKCSAgICAgICAweDAsICAgICAgICAweDIsICAgICAgICAweDIsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDIsICAgICAgICAweDAsICAgICAgICAweDAsIAoJICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgCgkgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAKCSAgICAgICAweDIsICAgICAgICAweDAsICAgICAgIDB4MzMsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsIAoJICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgIDB4MTAwMCwgICAgICAgIDB4MSwgICAgIDB4MTEwNCwgICAgICAweDQwMCwgICAgICAgMHgyMCwgCgkgICAgMHgyZTg0LCAgICAgMHgyZjg0LCAgICAgMHgyZjg0LCAgICAgMHgyZjg0LCAgICAgMHgyZjg0LCAgICAgMHgyZjg0LCAgICAgMHgyZjg0LCAgICAgMHgyZjg0LCAKCSAgICAweDJmODQsICAgICAweDJmODQsICAgICAgICAweDEsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsIAoJICAgICAgIDB4MCwgICAgICAgMHg4MCwgICAgICAgMHg4MCwgICAgICAgMHg4MCwgICAgICAgMHg4MCwgICAgICAweDg4MCwgICAgICAgMHg4MCwgICAgICAgIDB4MCwgCgkgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAKCSAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsIAoJICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MSwgICAgICAgMHgzOCwgICAgICAgIDB4MSwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgCgkgICAgICAgMHgwLCAgICAweDIwMDgwLCAgICAgICAweGEwLCAgICAgICAweDgwLCAgICAgICAweDgwLCAgIDB4MTEwODgwLCAgICAgICAweGE2LCAgICAgICAgMHgwLCAKCSAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgMHg0NDAwMDAsICAgICAgICAweDAsICAgICAgIDB4MjcsICAgICAgICAweDAsIAoJICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgIDB4NDAyMCwgICAgMHg4MDAwMCwgICAgICAgMHgyNSwgICAweDIwODA0MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgCgkgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgxLCAgICAgICAgMHgwLCAgICAgICAgMHgxLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAKCSAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsIAoJICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgCgkgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAKCSAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsIAoJICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgCgkgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAKCSAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsIAoJICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgCgkgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAKCSAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsIAoJICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgCgkgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAKCSAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsIAoJICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgICAgICAgIDB4MCwgCgkgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAgICAgICAgMHgwLCAKCSAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAsICAgICAgICAweDAKCX07CgoJc3RhdGljIGludCB0YmxbXSA9IHsKCSAgICAgMHgyMDAsICAgICAgMHhhMDAsICAweDcwMDBkMDEsICAweDcwMDBjMDEsICAweDMwMzBlMDksICAweDMwODBhMTgsICAweDEwZTBlMzYsICAweDExMTBlM2MsIAoJIDB4MTE1MGU0NCwgIDB4MzAzMTYwOSwgICAgIDB4MTIwMCwgIDB4NzAwMTUwMSwgIDB4MzA1MTYwZCwgICAgIDB4MWEwMCwgIDB4MzAzMWUwOSwgIDB4MTA3MWUxMCwgCgkgICAgMHgyMjAwLCAgMHgxMDcyNjEyLCAgICAgMHgyYTAwLCAgMHgxMDcyZTE0LCAgICAgMHgzMjAwLCAgMHgxMDczNjE2LCAgICAgMHgzYTAwLCAgMHgzMDMzZTA5LCAKCSAgICAweDQyMDAsICAweDMwODQ2MWMsICAweDMwODQ2MjAsICAweDMwODQ2MjQsICAgICAweDRhMDAsICAgICAweDRhMDAsICAweDMwODRlMjAsICAweDMwODRlMjQsIAoJIDB4MzBhNTIyOCwgICAgIDB4NTIwMCwgICAgIDB4NTIwMCwgICAgIDB4NTIwMCwgIDB4MzBhNWEyOCwgICAgIDB4NWEwMCwgIDB4MzA4NWUyNCwgIDB4MzA4NWUyNCwgCgkgMHg3MDA2MTAxLCAgMHgzMGE2NjJjLCAgMHgzMGM2NjMwLCAgICAgMHg2MjAwLCAgMHg3MDA2OTAxLCAgICAgMHg2YTAwLCAgMHgzMGM2ZTMwLCAgMHgzMGE2ZTJjLCAKCSAgICAweDcyMDAsICAweDMwYzc2MzMsICAweDMwYzc2MzMsICAweDcwMDc5MDEsICAgICAweDdhMDAsICAweDMwYzdlMzMsICAgICAweDgyMDAsICAweDEwZjg2MzgsIAoJICAgIDB4OGEwMCwgIDB4MTEwOGUzYSwgICAgIDB4OTIwMCwgIDB4NzAwOTUwMSwgICAgIDB4OWEwMCwgIDB4MTEyOWUzZSwgICAgIDB4YTIwMCwgIDB4MTEzYTY0MCwgCgkgICAgMHhhYTAwLCAgMHgxMTRhZTQyLCAgICAgMHhiMjAwLCAgMHg3MDBiNTAxLCAgICAgMHhiYTAwLCAgMHgxMTZiZTQ2LCAgICAgMHhjMjAwLCAgMHgxMTZjNjQ4LCAKCSAgICAweGNhMDAsICAweDcwMGNkMDEgfTsKCgkvL3N0YXJ0ID0gMHg3MDAwMjAxCgoJY2hhciogcCA9IGluX2J1ZjsKCWNoYXIqIHMgPSBpbl9idWY7Cglqbl90b2tfdCogdCA9IG91dF90b2tzOwoJaW50IHN0YXRlID0gMHg3MDAwMjAxOwoJdW5zaWduZWQgaW50IGNscyA9IDA7CglkbwoJewoJICAgIHAgKz0gKHN0YXRlPj4xMCkgJiAweDE7CgkgICAgdC0+cyA9IHM7CgkgICAgdC0+bGVuID0gcCAtIHM7CgkgICAgdCArPSAoc3RhdGU+PjgpICYgMHgxOwoJICAgIHMgKz0gKHAgLSBzKSAmIChVSU5UX01BWCArICgoc3RhdGU+PjkpICYgMHgxKSk7CgkgICAgY2xzID0gZXFjbHNbKHVuc2lnbmVkIGNoYXIpKCpwKV07CgkgICAgY2xzID0gKGNscz4+KChzdGF0ZSAmIDB4MDBGRjAwMDApPj4xNikpJihzdGF0ZT4+MjQpOwoJCXN0YXRlID0gdGJsWyAoc3RhdGUgJiAweDAwMDAwMEZGKSArIGNscyBdOwoJfQoJd2hpbGUoIChzdGF0ZSAmIDB4MDAwMDAwRkYpID4gMCk7CgoJKm91dF9sZW4gPSB0IC0gb3V0X3Rva3M7CglpZigqcCA9PSAwKQoJewoJCXJldHVybiAxOyAvKiBTVUNDRVNTICovCgl9CgljbHMgPSAoKHN0YXRlICYgMHhmODAwKSA+PiAxMSk7IC8qIGZhaWwgc3RhdGUgaWR4ICovCglpZihjbHMgPCAxKSAvKiBmYWlsIHN0YXRlIGlkeCAqLwoJewoJCS8qIGZhaWwgbXNnICAqLwoJfQoJcmV0dXJuIDA7Cn0KCgovKiBzaW1wbGUgbWVtb3J5IGFsbG9jYXRvciAqLwp2b2lkIGpuX2luaXRfYWxsb2Moam5fYWxsb2NfdCogYSkKewojaWZkZWYgSk5fQUxMT0NBVE9SCglzdGF0aWMgam5fanNvbl90IGpzb25fbm9kZXNbSk5fTUFYX0xJTUlUXTsKCW1lbXNldChqc29uX25vZGVzLCAweDAwICxzaXplb2YoanNvbl9ub2RlcykpOwoJYS0+bm9kZXMgPSBqc29uX25vZGVzOwoJYS0+Y250ID0gMDsKI2VuZGlmCglhLT5hbGxvYyA9IGpuX2FsbG9jX2pzb247CglhLT5mcmVlID0gam5fZnJlZV9qc29uOwp9CiAKam5fanNvbl90KiBqbl9hbGxvY19qc29uIChpbnQgc2l6ZSwgam5fYWxsb2NfdCogYSkKewoJam5fanNvbl90KiByZXQgPSBOVUxMOwojaWZkZWYgSk5fQUxMT0NBVE9SCglyZXQgPSAmKGEtPm5vZGVzW2EtPmNudF0pOwoJYS0+Y250ICs9IHNpemU7CiNlbHNlCglyZXQgPSAgKGpuX2pzb25fdCopbWFsbG9jKCBzaXplICogc2l6ZW9mKGpuX2pzb25fdCkpOwojZW5kaWYKCW1lbXNldChyZXQsIDB4MDAsIHNpemUgKiBzaXplb2Yoc2l6ZW9mKGpuX2pzb25fdCkpKTsKCXJldHVybiByZXQ7Cn0Kdm9pZCBqbl9mcmVlX2pzb24gIChqbl9qc29uX3QqIG4gLCBqbl9hbGxvY190KiBhKQp7CiNpZmRlZiBKTl9BTExPQ0FUT1IKCS8qIHBhc3MgKi8KI2Vsc2UKCWZyZWUobik7CiNlbmRpZgp9Cgp0eXBlZGVmIHN0cnVjdCBqbl9zdGFja19zdAp7CglpbnQgc3RhdGU7Cglqbl90b2tfdCogdG9rZW47Cglqbl9qc29uX3QqIGpzb247CglpbnQgY2xzOwp9CmpuX3N0YWNrX3Q7CgoKaW50IGpuX3BhcnNlKGpuX2FsbG9jX3QqIGEsIGNoYXIqIGluX2J1Ziwgam5fanNvbl90Kiogb3V0X2pzb24pCnsKCXN0YXRpYyBpbnQgZXFjbHNbXSA9IHsKCQkwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwKCQkxICwwICwwICwwICwwICwwICwwICwwICwwICwwICw4ICwyICwwICwwICwyICwyICwyICwyICwyICwyICwyICwyICwyICwyICwxMSAsMCAsMCAsMCAsMCAsMCAsMCAsMCAsMCAsMCAsCgkJMCAsMCAsMCAsMCAsMCAsMCAsMCAsMCAsMCAsMCAsMCAsMCAsMCAsMCAsMCAsMCAsMCAsMCAsMCAsMCAsMCAsMCAsMCAsNiAsMCAsNyAsMCAsMCAsMCAsMCAsMCAsMCAsMCAsMCAsCgkJNCAsMCAsMCAsMCAsMCAsMCAsMCAsMCAsNSAsMCAsMCAsMCAsMCAsMCAsMyAsMCAsMCAsMCAsMCAsMCAsMCAsOSAsMCAsMTAgLDAgLDAgCgl9OwoJc3RhdGljIGludCB0YmxbXSA9IHsKICAwLCAgIDQsICAgNiwgICA3LCAgIDgsICAgOSwgIDEwLCAgIDAsICAgMCwgICA1LCAgIDAsICAgMCwgICAxLCAgIDIsICAgMCwgICAzLCAgIDAsICAgMCwKIC0xLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKIDMxLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgMzEsICAzMSwgICAwLCAgMzEsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKIDMyLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgMzIsICAzMiwgICAwLCAgMzIsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKIDI2LCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgMjYsICAyNiwgICAwLCAgMjYsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKICAwLCAgMTQsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgMTMsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgMTEsICAxMiwKIDI3LCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgMjcsICAyNywgICAwLCAgMjcsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKIDI4LCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgMjgsICAyOCwgICAwLCAgMjgsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKIDI5LCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgMjksICAyOSwgICAwLCAgMjksICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKIDMwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgMzAsICAzMCwgICAwLCAgMzAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKICAwLCAgIDQsICAgNiwgICA3LCAgIDgsICAgOSwgIDEwLCAgMTcsICAgMCwgICA1LCAgIDAsICAgMCwgIDE1LCAgIDIsICAxNiwgICAzLCAgIDAsICAgMCwKICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgMTgsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAxOSwgICAwLCAgMzksICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKIDM3LCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgMzcsICAzNywgICAwLCAgMzcsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAyMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgMzUsICAyMSwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgMjIsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKIDMzLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgMzMsICAzMywgICAwLCAgMzMsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKIDM4LCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgMzgsICAzOCwgICAwLCAgMzgsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKICAwLCAgMTQsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgMjMsICAxMiwKICAwLCAgIDQsICAgNiwgICA3LCAgIDgsICAgOSwgIDEwLCAgIDAsICAgMCwgICA1LCAgIDAsICAgMCwgIDI0LCAgIDIsICAgMCwgICAzLCAgIDAsICAgMCwKICAwLCAgIDQsICAgNiwgICA3LCAgIDgsICAgOSwgIDEwLCAgIDAsICAgMCwgICA1LCAgIDAsICAgMCwgIDE1LCAgIDIsICAyNSwgICAzLCAgIDAsICAgMCwKIDM0LCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgMzQsICAzNCwgICAwLCAgMzQsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgNDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICA0MSwgICAwLCAgNDEsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgMzYsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMAoJfTsKCXN0YXRpYyBqbl9zdGFja190IHN0YWNrW0pOX01BWF9MSU1JVF07CgoJLyogICovCglzdGF0aWMgam5fdG9rX3QgdG9rc1tKTl9NQVhfTElNSVRdOwoJaW50ICAgICAgdG9rX2xlbiAgPSAwOwoJaW50ICAgICAgdG9rX2lkeCAgPSAwOwoJaW50ICAgICAgcmV0ID0gMDsKCS8qICAqLwoJaW50IHN0YXRlID0wOwoJaW50IHRvcCA9IDA7IC8qIHN0YWNrIHRvcCAqLwoJaW50IHRvcF9zdGF0ZSA9IDA7CglpbnQgdG9wX2NscyA9IDA7Cglqbl90b2tfdCogdG9wX3RvayA9IE5VTEw7Cglqbl9qc29uX3QqIHRvcF9qc29uID0gTlVMTDsKCgkvKiB0b2tlbml6aW5nICovCglyZXQgPSBqbl9zY2FuKGluX2J1ZiwgdG9rcywgJnRva19sZW4pOwoJaWYocmV0ID09IDApCgl7CgkJcmV0dXJuIDA7IC8qIGZhaWwgKi8KCX0KCXRva3NbdG9rX2xlbl0ucyA9ICIiOwoJdG9rc1t0b2tfbGVuXS5sZW4gPSAwOwoJdG9rX2lkeCA9IDA7CgoJLyogcGFyc2luZyAqLwoJZG8KCXsKCQlqbl90b2tfdCogdCA9ICYodG9rc1t0b2tfaWR4XSk7CgkJaW50IGNscyA9IGVxY2xzWyh1bnNpZ25lZCBjaGFyKSgqdG9rc1t0b2tfaWR4XS5zKV07CgkJc3RhdGUgPSB0Ymxbc3RhY2tbdG9wXS5zdGF0ZSAqIDE4ICsgY2xzXTsKCgkJc3dpdGNoKHN0YXRlKQoJCXsKCQkJY2FzZSAwOgoJCQkJYnJlYWs7CgkJCS8qIHZhbHVlOiBTVFIgfCBOVU0gfCBUUlVFIHwgRkFMU0UgfCBOVUxMICovCgkJCWNhc2UgMjY6IGNhc2UgMjc6IGNhc2UgMjg6IGNhc2UgMjk6IGNhc2UgMzA6CgkJCQl0b3BfanNvbiA9IGEtPmFsbG9jKDEsIGEpOyAvKiBhbGxvYyAqLwoJCQkJdG9wX2pzb24tPnR5cGUgPSBzdGF0ZSAtIDI1OwoJCQkJdG9wX2pzb24tPmsgICAgPSAqKHN0YWNrW3RvcF0udG9rZW4pOwoJCQkJCgkJCQl0b3AgLT0gMTsKCQkJCXRvcF9jbHMgPSAxMjsgLyogdmFsdWUgKi8KCQkJCXRvcF9zdGF0ZSA9IHRibFtzdGFja1t0b3BdLnN0YXRlICogMTggKyB0b3BfY2xzXTsKCQkJCXRvcF90b2sgPSBOVUxMOwoJCQkJYnJlYWs7CgkJCS8qIHZhbHVlOiBhcnJheSB8IG9iamVjdCAqLwoJCQljYXNlIDMxOiBjYXNlIDMyOgoJCQkJdG9wX2pzb24gPSBzdGFja1t0b3BdLmpzb247IC8qIHBhc3MgKi8KCQkJCQoJCQkJdG9wIC09IDE7CgkJCQl0b3BfY2xzID0gMTI7IC8qIHZhbHVlICovCgkJCQl0b3Bfc3RhdGUgPSB0Ymxbc3RhY2tbdG9wXS5zdGF0ZSAqIDE4ICsgdG9wX2Nsc107CgkJCQl0b3BfdG9rID0gTlVMTDsKCQkJCWJyZWFrOwoJCQkvKiBhcnJheTogW10gKi8KCQkJY2FzZSAzMzogCgkJCQl0b3BfanNvbiA9IGEtPmFsbG9jKDEsIGEpOyAvKiBhbGxvYyAqLwoJCQkJdG9wX2pzb24tPnR5cGUgPSBKTl9BUlJBWTsKCQkJCQoJCQkJdG9wIC09IDI7CgkJCQl0b3BfY2xzID0gMTM7IC8qIGFycmF5ICovCgkJCQl0b3Bfc3RhdGUgPSB0Ymxbc3RhY2tbdG9wXS5zdGF0ZSAqIDE4ICsgdG9wX2Nsc107CgkJCQl0b3BfdG9rID0gTlVMTDsKCQkJCWJyZWFrOwogCgkJCS8qIGFycmF5OiBbIGVsZW1lbnRzIF0gKi8KCQkJY2FzZSAzNDoKCQkJCXRvcF9qc29uID0gYS0+YWxsb2MoMSwgYSk7IC8qIGFsbG9jICovCgkJCQl0b3BfanNvbi0+dHlwZSA9IEpOX0FSUkFZOwoJCQkJdG9wX2pzb24tPnYgPSBzdGFja1t0b3AtMV0uanNvbjsKCQkJCQoJCQkJdG9wIC09IDM7CgkJCQl0b3BfY2xzID0gMTM7IC8qIGFycmF5ICovCgkJCQl0b3Bfc3RhdGUgPSB0Ymxbc3RhY2tbdG9wXS5zdGF0ZSAqIDE4ICsgdG9wX2Nsc107CgkJCQl0b3BfdG9rID0gTlVMTDsKCQkJCWJyZWFrOwoKCQkJLyogZWxlbWVudHM6IHZhbHVlICovCgkJCWNhc2UgMzU6CgkJCQl0b3BfanNvbiA9IHN0YWNrW3RvcF0uanNvbjsgLyogcGFzcyAqLwoJCQkJCgkJCQl0b3AgLT0gMTsKCQkJCXRvcF9jbHMgPSAxNDsgLyogZWxlbWVudHMgKi8KCQkJCXRvcF9zdGF0ZSA9IHRibFtzdGFja1t0b3BdLnN0YXRlICogMTggKyB0b3BfY2xzXTsKCQkJCXRvcF90b2sgPSBOVUxMOwoJCQkJYnJlYWs7CgkJCS8qIGVsZW1lbnRzOiB2YWx1ZSAsIGVsZW1lbnRzICovCgkJCWNhc2UgMzY6CgkJCQl0b3BfanNvbiA9IHN0YWNrW3RvcC0yXS5qc29uOwoJCQkJdG9wX2pzb24tPnIgPSBzdGFja1t0b3BdLmpzb247CgkJCQkKCQkJCXRvcCAtPSAzOwoJCQkJdG9wX2NscyA9IDE0OyAvKiBlbGVtZW50cyAqLwoJCQkJdG9wX3N0YXRlID0gdGJsW3N0YWNrW3RvcF0uc3RhdGUgKiAxOCArIHRvcF9jbHNdOwoJCQkJdG9wX3RvayA9IE5VTEw7CgkJCQlicmVhazsKCgkJCS8qIG9iamVjdDoge30gKi8KCQkJY2FzZSAzNzogCgkJCQl0b3BfanNvbiA9IGEtPmFsbG9jKDEsIGEpOyAvKiBhbGxvYyAqLwoJCQkJdG9wX2pzb24tPnR5cGUgPSBKTl9PQkpFQ1Q7CgkJCQkKCQkJCXRvcCAtPSAyOwoJCQkJdG9wX2NscyA9IDE1OyAvKiBvYmplY3QgKi8KCQkJCXRvcF9zdGF0ZSA9IHRibFtzdGFja1t0b3BdLnN0YXRlICogMTggKyB0b3BfY2xzXTsKCQkJCXRvcF90b2sgPSBOVUxMOwoJCQkJYnJlYWs7CiAKCQkJLyogb2JqZWN0OiB7IG1lbWJlcnMgfSAqLwoJCQljYXNlIDM4OgoJCQkJdG9wX2pzb24gPSBhLT5hbGxvYygxLCBhKTsgLyogYWxsb2MgKi8KCQkJCXRvcF9qc29uLT50eXBlID0gSk5fT0JKRUNUOwoJCQkJdG9wX2pzb24tPnYgPSBzdGFja1t0b3AtMV0uanNvbjsKCQkJCQoJCQkJdG9wIC09IDM7CgkJCQl0b3BfY2xzID0gMTU7IC8qIG9iamVjdCAqLwoJCQkJdG9wX3N0YXRlID0gdGJsW3N0YWNrW3RvcF0uc3RhdGUgKiAxOCArIHRvcF9jbHNdOwoJCQkJdG9wX3RvayA9IE5VTEw7CgkJCQlicmVhazsKCgkJCS8qIG1lbWJlcnM6IG1lbWJlciAqLwoJCQljYXNlIDM5OgoJCQkJdG9wX2pzb24gPSBzdGFja1t0b3BdLmpzb247IC8qIHBhc3MgKi8KCQkJCQoJCQkJdG9wIC09IDE7CgkJCQl0b3BfY2xzID0gMTY7IC8qIG1lbWJlcnMgKi8KCQkJCXRvcF9zdGF0ZSA9IHRibFtzdGFja1t0b3BdLnN0YXRlICogMTggKyB0b3BfY2xzXTsKCQkJCXRvcF90b2sgPSBOVUxMOwoJCQkJYnJlYWs7CgkJCS8qIG1lbWJlcnM6IG1lbWJlciAsIG1lbWJlcnMgKi8KCQkJY2FzZSA0MDoKCQkJCXRvcF9qc29uID0gc3RhY2tbdG9wLTJdLmpzb247CgkJCQl0b3BfanNvbi0+ciA9IHN0YWNrW3RvcF0uanNvbjsKCQkJCQoJCQkJdG9wIC09IDM7CgkJCQl0b3BfY2xzID0gMTY7IC8qIG1lbWJlcnMgKi8KCQkJCXRvcF9zdGF0ZSA9IHRibFtzdGFja1t0b3BdLnN0YXRlICogMTggKyB0b3BfY2xzXTsKCQkJCXRvcF90b2sgPSBOVUxMOwoJCQkJYnJlYWs7CgoJCQkvKiBtZW1iZXIgOiBzdHIgOiB2YWx1ZSAqLwoJCQljYXNlIDQxOgoJCQkJdG9wX2pzb24gPSBhLT5hbGxvYygxLCBhKTsgLyogYWxsb2MgKi8KCQkJCXRvcF9qc29uLT50eXBlID0gSk5fS0VZVkFMVUU7CgkJCQl0b3BfanNvbi0+ayA9ICooc3RhY2tbdG9wLTJdLnRva2VuKTsKCQkJCXRvcF9qc29uLT52ID0gc3RhY2tbdG9wXS5qc29uOwoJCQkJCgkJCQl0b3AgLT0gMzsKCQkJCXRvcF9jbHMgPSAxNzsgLyogbWVtYmVycyAqLwoJCQkJdG9wX3N0YXRlID0gdGJsW3N0YWNrW3RvcF0uc3RhdGUgKiAxOCArIHRvcF9jbHNdOwoJCQkJdG9wX3RvayA9IE5VTEw7CgkJCQlicmVhazsKCgkJCWRlZmF1bHQ6CgkJCQkvKiBzaGlmdCAqLwoJCQkJdG9wX2NscyA9IGNsczsKCQkJCXRvcF9zdGF0ZSA9IHN0YXRlOwoJCQkJdG9wX3RvayA9IHQ7CgkJCQl0b3BfanNvbiA9IE5VTEw7CgkJCQl0b2tfaWR4Kys7CgkJCQlicmVhazsKCQl9CgkJaWYoc3RhdGUgPiAwKQoJCXsKCQkJdG9wKys7CgkJCXN0YWNrW3RvcF0uY2xzID0gdG9wX2NsczsKCQkJc3RhY2tbdG9wXS5zdGF0ZSA9IHRvcF9zdGF0ZTsKCQkJc3RhY2tbdG9wXS50b2tlbiA9IHRvcF90b2s7CgkJCXN0YWNrW3RvcF0uanNvbiA9IHRvcF9qc29uOwoJCX0KCQkKCX13aGlsZShzdGF0ZSA+IDAgJiYgdG9rX2lkeCA8PSB0b2tfbGVuKTsKCgoJaWYoc3RhdGUgPT0gLTEpIC8qIGFjY2VwdCAqLwoJewoJCSpvdXRfanNvbiA9IHN0YWNrW3RvcF0uanNvbjsKCQlyZXR1cm4gMTsgLyogc3VjY2VzcyAqLwoJfQoJZWxzZQoJewoJCS8qIFRPRE86IGZyZWUgYWxsIGpzb24gbWVtb3J5ICAqLwoJCSpvdXRfanNvbiA9IE5VTEw7Cgl9CgoKCXJldHVybiAwOwp9CgoKdm9pZCBqbl9wcmludF9qc29uKGpuX2pzb25fdCoganNvbikKewoJX2puX3ByaW50X2pzb24oanNvbiwgMCwgMCk7Cn0Kdm9pZCBfam5fcHJpbnRfanNvbihqbl9qc29uX3QqIGpzb24sIGludCBpbmRlbnQsIGludCBrdikKewoJaWYoanNvbiAhPSBOVUxMKQoJewoJCWludCBpPTA7IAoJCWZvcihpPTA7IGkgPCBpbmRlbnQgJiYga3YgPT0gMDsgaSsrKQoJCXsKCQkJcHJpbnRmKCIgICIpOwoJCX0KCQlzd2l0Y2goanNvbi0+dHlwZSkKCQl7CgkJCWNhc2UgSk5fU1RSSU5HOgoJCQljYXNlIEpOX05VTUJFUjoKCQkJY2FzZSBKTl9UUlVFOgoJCQljYXNlIEpOX0ZBTFNFOgoJCQljYXNlIEpOX05VTEw6CgkJCQlwcmludGYoIiUuKnMiLCBqc29uLT5rLmxlbiwganNvbi0+ay5zKTsKCQkJCWJyZWFrOwoJCQljYXNlIEpOX0FSUkFZOgoJCQkJcHJpbnRmKCJbXG4iKTsKCQkJCV9qbl9wcmludF9qc29uKGpzb24tPnYsIGluZGVudCsxLCAwKTsKCQkJCXByaW50ZigiXG4iKTsKCQkJCWZvcihpPTA7IGkgPCBpbmRlbnQ7IGkrKykKCQkJCXsKCQkJCQlwcmludGYoIiAgIik7CgkJCQl9CgkJCQlwcmludGYoIl0iKTsKCQkJCWJyZWFrOwoJCQljYXNlIEpOX09CSkVDVDoKCQkJCXByaW50Zigie1xuIik7CgkJCQlfam5fcHJpbnRfanNvbihqc29uLT52LCBpbmRlbnQrMSwgMCk7CgkJCQlwcmludGYoIlxuIik7CgkJCQlmb3IoaT0wOyBpIDwgaW5kZW50OyBpKyspCgkJCQl7CgkJCQkJcHJpbnRmKCIgICIpOwoJCQkJfQoJCQkJcHJpbnRmKCJ9Iik7CgkJCQlicmVhazsKCQkJY2FzZSBKTl9LRVlWQUxVRToKCQkJCXByaW50ZigiJS4qczogIiwganNvbi0+ay5sZW4sIGpzb24tPmsucyk7CgkJCQlfam5fcHJpbnRfanNvbihqc29uLT52LCBpbmRlbnQsIDEpOwoJCQkJYnJlYWs7CgkJfQoJCWlmKGpzb24tPnIgIT0gTlVMTCkKCQl7CgkJCXByaW50ZigiLFxuIik7CgkJCV9qbl9wcmludF9qc29uKGpzb24tPnIsIGluZGVudCwgMCk7CgkJfQoJCWVsc2UKCQl7CgkJCXByaW50ZigiIik7CgkJfQoJfQp9CgoKLyogTEFMUiB0YWJsZQotLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0KWyAgICBdIHwgICAgICAgICAkIHwgICAgICAgc3RyIHwgICAgICAgbnVtIHwgICAgICB0cnVlIHwgICAgIGZhbHNlIHwgICAgICBudWxsIHwgICAgICAgICBbIHwgICAgICAgICBdIHwgICAgICAgICAsIHwgICAgICAgICB7IHwgICAgICAgICB9IHwgICAgICAgICA9IHwgICAgIHZhbHVlIHwgICAgIGFycmF5IHwgIGVsZW1lbnRzIHwgICAgb2JqZWN0IHwgICBtZW1iZXJzIHwgICAgbWVtYmVyIHwgCi0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLQpbICAgMF0gfCAgICAgICAgICAgfCBzICAgICAgIDQgfCBzICAgICAgIDYgfCBzICAgICAgIDcgfCBzICAgICAgIDggfCBzICAgICAgIDkgfCBzICAgICAgMTAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCBzICAgICAgIDUgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgIDEgfCAgICAgICAgIDIgfCAgICAgICAgICAgfCAgICAgICAgIDMgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAKWyAgIDFdIHwgICAgICAgQUNDIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgClsgICAyXSB8IHIgICAgICAgNiB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8IHIgICAgICAgNiB8IHIgICAgICAgNiB8ICAgICAgICAgICB8IHIgICAgICAgNiB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8IApbICAgM10gfCByICAgICAgIDcgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCByICAgICAgIDcgfCByICAgICAgIDcgfCAgICAgICAgICAgfCByICAgICAgIDcgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAKWyAgIDRdIHwgciAgICAgICAxIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgciAgICAgICAxIHwgciAgICAgICAxIHwgICAgICAgICAgIHwgciAgICAgICAxIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgClsgICA1XSB8ICAgICAgICAgICB8IHMgICAgICAxNCB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8IHMgICAgICAxMyB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAxMSB8ICAgICAgICAxMiB8IApbICAgNl0gfCByICAgICAgIDIgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCByICAgICAgIDIgfCByICAgICAgIDIgfCAgICAgICAgICAgfCByICAgICAgIDIgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAKWyAgIDddIHwgciAgICAgICAzIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgciAgICAgICAzIHwgciAgICAgICAzIHwgICAgICAgICAgIHwgciAgICAgICAzIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgClsgICA4XSB8IHIgICAgICAgNCB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8IHIgICAgICAgNCB8IHIgICAgICAgNCB8ICAgICAgICAgICB8IHIgICAgICAgNCB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8IApbICAgOV0gfCByICAgICAgIDUgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCByICAgICAgIDUgfCByICAgICAgIDUgfCAgICAgICAgICAgfCByICAgICAgIDUgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAKWyAgMTBdIHwgICAgICAgICAgIHwgcyAgICAgICA0IHwgcyAgICAgICA2IHwgcyAgICAgICA3IHwgcyAgICAgICA4IHwgcyAgICAgICA5IHwgcyAgICAgIDEwIHwgcyAgICAgIDE3IHwgICAgICAgICAgIHwgcyAgICAgICA1IHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgIDE1IHwgICAgICAgICAyIHwgICAgICAgIDE2IHwgICAgICAgICAzIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgClsgIDExXSB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8IHMgICAgICAxOCB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8IApbICAxMl0gfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCBzICAgICAgMTkgfCAgICAgICAgICAgfCByICAgICAgMTQgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAKWyAgMTNdIHwgciAgICAgIDEyIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgciAgICAgIDEyIHwgciAgICAgIDEyIHwgICAgICAgICAgIHwgciAgICAgIDEyIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgClsgIDE0XSB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8IHMgICAgICAyMCB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8IApbICAxNV0gfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCByICAgICAgMTAgfCBzICAgICAgMjEgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAKWyAgMTZdIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgcyAgICAgIDIyIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgClsgIDE3XSB8IHIgICAgICAgOCB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8IHIgICAgICAgOCB8IHIgICAgICAgOCB8ICAgICAgICAgICB8IHIgICAgICAgOCB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8IApbICAxOF0gfCByICAgICAgMTMgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCByICAgICAgMTMgfCByICAgICAgMTMgfCAgICAgICAgICAgfCByICAgICAgMTMgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAKWyAgMTldIHwgICAgICAgICAgIHwgcyAgICAgIDE0IHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgIDIzIHwgICAgICAgIDEyIHwgClsgIDIwXSB8ICAgICAgICAgICB8IHMgICAgICAgNCB8IHMgICAgICAgNiB8IHMgICAgICAgNyB8IHMgICAgICAgOCB8IHMgICAgICAgOSB8IHMgICAgICAxMCB8ICAgICAgICAgICB8ICAgICAgICAgICB8IHMgICAgICAgNSB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAyNCB8ICAgICAgICAgMiB8ICAgICAgICAgICB8ICAgICAgICAgMyB8ICAgICAgICAgICB8ICAgICAgICAgICB8IApbICAyMV0gfCAgICAgICAgICAgfCBzICAgICAgIDQgfCBzICAgICAgIDYgfCBzICAgICAgIDcgfCBzICAgICAgIDggfCBzICAgICAgIDkgfCBzICAgICAgMTAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCBzICAgICAgIDUgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgMTUgfCAgICAgICAgIDIgfCAgICAgICAgMjUgfCAgICAgICAgIDMgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAKWyAgMjJdIHwgciAgICAgICA5IHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgciAgICAgICA5IHwgciAgICAgICA5IHwgICAgICAgICAgIHwgciAgICAgICA5IHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgClsgIDIzXSB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8IHIgICAgICAxNSB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICB8IApbICAyNF0gfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCByICAgICAgMTYgfCAgICAgICAgICAgfCByICAgICAgMTYgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgICAgfCAKWyAgMjVdIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgciAgICAgIDExIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgCi0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rLQp2YWx1ZTogc3RyIHwgbnVtIHwgdHJ1ZSB8IGZhbHNlIHwgbnVsbCB8IGFycmF5IHwgb2JqZWN0IDsKYXJyYXk6IFsgXSB8IFsgZWxlbWVudHMgXSA7CmVsZW1lbnRzOiB2YWx1ZSB8IHZhbHVlICwgZWxlbWVudHMgOwpvYmplY3Q6IHsgfSB8IHsgbWVtYmVycyB9IDsKbWVtYmVyczogbWVtYmVyIHwgbWVtYmVyICwgbWVtYmVycyA7Cm1lbWJlcjogc3RyID0gdmFsdWUgOwoqLwoKCgppbnQgbWFpbih2b2lkKQp7Cglqbl9hbGxvY190IGE7CgoJY2hhciogc3VjY19qc29uMSA9ICJ7XCJrZXkxXCI6IFwidGhpcyBpcyB0ZXN0IGpzb25cIiwgXCJrZXkyXCI6IFswLCAxLCAxMiwgMC4xMjMsIDEyLjIzNCwgLTI5MywgLTM5NC4yOTRFLTIzXX0iOwoJY2hhciogc3VjY19qc29uMiA9ICJ7XCJncmFtXCI6W3tcImhlYWRcIjpcInZhbHVlXCIsXCJib2R5XCI6W1wic3RyXCJdLFwib3BcIjpcInN0clwifSx7XCJoZWFkXCI6XCJ2YWx1ZVwiLFwiYm9keVwiOltcIm51bVwiXSxcIm9wXCI6XCJudW1cIn0se1wiaGVhZFwiOlwidmFsdWVcIixcImJvZHlcIjpbXCJ0cnVlXCJdLFwib3BcIjpcInRydWVcIn0se1wiaGVhZFwiOlwidmFsdWVcIixcImJvZHlcIjpbXCJmYWxzZVwiXSxcIm9wXCI6XCJmYWxzZVwifSx7XCJoZWFkXCI6XCJ2YWx1ZVwiLFwiYm9keVwiOltcIm51bGxcIl0sXCJvcFwiOlwibnVsbFwifSx7XCJoZWFkXCI6XCJ2YWx1ZVwiLFwiYm9keVwiOltcImFycmF5XCJdLFwib3BcIjpudWxsfSx7XCJoZWFkXCI6XCJ2YWx1ZVwiLFwiYm9keVwiOltcIm9iamVjdFwiXSxcIm9wXCI6bnVsbH0se1wiaGVhZFwiOlwiYXJyYXlcIixcImJvZHlcIjpbXCJbXCIsXCJdXCJdLFwib3BcIjpcIl1cIn0se1wiaGVhZFwiOlwiYXJyYXlcIixcImJvZHlcIjpbXCJbXCIsXCJlbGVtZW50c1wiLFwiXVwiXSxcIm9wXCI6XCJdXCJ9LHtcImhlYWRcIjpcImVsZW1lbnRzXCIsXCJib2R5XCI6W1widmFsdWVcIl0sXCJvcFwiOm51bGx9LHtcImhlYWRcIjpcImVsZW1lbnRzXCIsXCJib2R5XCI6W1widmFsdWVcIixcIixcIixcImVsZW1lbnRzXCJdLFwib3BcIjpcIixcIn0se1wiaGVhZFwiOlwib2JqZWN0XCIsXCJib2R5XCI6W1wie1wiLFwifVwiXSxcIm9wXCI6XCJ9XCJ9LHtcImhlYWRcIjpcIm9iamVjdFwiLFwiYm9keVwiOltcIntcIixcIm1lbWJlcnNcIixcIn1cIl0sXCJvcFwiOlwifVwifSx7XCJoZWFkXCI6XCJtZW1iZXJzXCIsXCJib2R5XCI6W1wibWVtYmVyXCJdLFwib3BcIjpudWxsfSx7XCJoZWFkXCI6XCJtZW1iZXJzXCIsXCJib2R5XCI6W1wibWVtYmVyXCIsXCIsXCIsXCJtZW1iZXJzXCJdLFwib3BcIjpcIixcIn0se1wiaGVhZFwiOlwibWVtYmVyXCIsXCJib2R5XCI6W1wic3RyXCIsXCI9XCIsXCJ2YWx1ZVwiXSxcIm9wXCI6XCI9XCJ9XSxcIm5vblwiOntcInZhbHVlXCI6MCxcImFycmF5XCI6MSxcImVsZW1lbnRzXCI6MixcIm9iamVjdFwiOjMsXCJtZW1iZXJzXCI6NCxcIm1lbWJlclwiOjV9LFwidGVyXCI6e1wic3RyXCI6MCxcIm51bVwiOjEsXCJ0cnVlXCI6MixcImZhbHNlXCI6MyxcIm51bGxcIjo0LFwiW1wiOjUsXCJdXCI6NixcIixcIjo3LFwie1wiOjgsXCJ9XCI6OSxcIj1cIjoxMH19IjsKCWpuX2pzb25fdCogb3V0ID0gTlVMTDsKCglwcmludGYoIi0tLS0tLS0tLS0tLVxuIik7CglvdXQgPSBOVUxMOwoJam5faW5pdF9hbGxvYygmYSk7CglpZihqbl9wYXJzZSgmYSwgc3VjY19qc29uMSwgJm91dCkpCgkJam5fcHJpbnRfanNvbihvdXQpOwoKCXByaW50ZigiLS0tLS0tLS0tLS0tXG4iKTsKCW91dCA9IE5VTEw7Cglqbl9pbml0X2FsbG9jKCZhKTsKCWlmKGpuX3BhcnNlKCZhLCBzdWNjX2pzb24yLCAmb3V0KSkKCQlqbl9wcmludF9qc29uKG91dCk7CgoJcmV0dXJuIDA7Cn0=