aboutsummaryrefslogtreecommitdiffstats
path: root/lib/asn1/test/asn1_bin_v2_particular_SUITE.erl.src
blob: 4c3c8c78083b9d298b27f9fd27263257926b80d6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
particular() -> [smp, ticket7904].


smp(suite) -> [];
smp(Config)  ->
    case erlang:system_info(smp_support) of
	true ->
	    NumOfProcs = erlang:system_info(schedulers),
	    io:format("smp starting ~p workers\n",[NumOfProcs]),

            ?line Msg = {initiatingMessage, testNBAPsystem:cell_setup_req_msg()},
	    ?line ok = testNBAPsystem:compile(Config,per_bin,[optimize]),
	    
	    enc_dec(NumOfProcs,Msg,2),

	    N = 10000,

            ?line {Time1,ok} = timer:tc(?MODULE,enc_dec,[NumOfProcs,Msg, N]),
	    ?line {Time1S,ok} = timer:tc(?MODULE,enc_dec,[1, Msg, NumOfProcs * N]),

	    ?line ok = testNBAPsystem:compile(Config,ber_bin,[optimize,nif]),
            ?line {Time3,ok} = timer:tc(?MODULE,enc_dec,[NumOfProcs,Msg, N]),

	    ?line {Time3S,ok} = timer:tc(?MODULE,enc_dec,[1, Msg, NumOfProcs * N]),

            {comment,lists:flatten(
		       io_lib:format(
			 "Encode/decode time parallell with ~p cores: ~p [microsecs]~n"
			 "Encode/decode time sequential: ~p [microsecs]",
			 [NumOfProcs,Time1+Time3,Time1S+Time3S]))};
        false ->
            {skipped,"No smp support"}
    end.

per_performance(Config) ->
    PrivDir = proplists:get_value(priv_dir, Config),
    NifDir = filename:join(PrivDir,"nif"),
    ErlDir = filename:join(PrivDir,"erl"),
    file:make_dir(NifDir),file:make_dir(ErlDir),

    ?line Msg = {initiatingMessage, testNBAPsystem:cell_setup_req_msg()},
    ?line ok = testNBAPsystem:compile([{priv_dir,NifDir}|Config],per_bin,
				      [optimize]),
    ?line ok = testNBAPsystem:compile([{priv_dir,ErlDir}|Config],per_bin,
				      []),

    Modules = ['NBAP-CommonDataTypes',
	       'NBAP-Constants',
	       'NBAP-Containers',
	       'NBAP-IEs',
	       'NBAP-PDU-Contents',
	       'NBAP-PDU-Discriptions'],


    PreNif = fun() ->
		     code:add_patha(NifDir),
		     lists:foreach(fun(M) ->
					   code:purge(M),
					   code:load_file(M)
				   end,Modules)
	     end,
    
    PreErl = fun() ->
		     code:add_patha(ErlDir),
		     lists:foreach(fun(M) ->
					   code:purge(M),
					   code:load_file(M)
				   end,Modules)
	     end,

    Func = fun() ->
		   element(1,timer:tc(
			       asn1_wrapper,encode,['NBAP-PDU-Discriptions',
						    'NBAP-PDU',
						    Msg]))
	   end,

    nif_vs_erlang_performance({{{PreNif,Func},{PreErl,Func}},100000,32}).

ber_performance(Config) ->

    ?line Msg = {initiatingMessage, testNBAPsystem:cell_setup_req_msg()},
    ?line ok = testNBAPsystem:compile(Config,ber_bin,[optimize,nif]),


    BerFun = fun() ->
		     {ok,B} = asn1_wrapper:encode('NBAP-PDU-Discriptions',
						  'NBAP-PDU', Msg),
		     asn1_wrapper:decode(
			'NBAP-PDU-Discriptions',
			'NBAP-PDU',
			B)
	     end,
    nif_vs_erlang_performance({BerFun,100000,32}).

cert_pem_performance(Config) when is_list(Config) ->
    cert_pem_performance({100000, 32});
cert_pem_performance({N,S}) ->
    nif_vs_erlang_performance({fun cert_pem/0,N,S}).

dsa_pem_performance(Config) when is_list(Config) ->
    cert_pem_performance({100000, 32});
dsa_pem_performance({N,S}) ->
    nif_vs_erlang_performance({fun dsa_pem/0,N,S}).


nif_vs_erlang_performance({{TC1,TC2},N,Sched}) ->
    random:seed({123,456,789}),
    io:format("Running a ~p sample with ~p max procs...~n~n",[N,Sched]),
    
    {True,False} = exec(TC1,TC2,Sched,N+1),
        
    io:format("~ndone!~n"),

    io:format("~n"),TStats = print_stats(strip(True,N div 20)),
    io:format("~n"),FStats = print_stats(strip(False,N div 20)),
    Str = io_lib:format("~nNifs are ~.3f% faster than erlang!~n",
			[(element(2,FStats) - element(2,TStats)) / 
			     element(2,FStats) * 100]),
    io:format(Str),
    {comment, lists:flatten(Str)};
nif_vs_erlang_performance({T,N,Sched}) ->
    PTC1 = fun() ->
		  application:set_env(asn1, nif_loadable, true)
	   end,
    PTC2 = fun() ->
		  application:set_env(asn1, nif_loadable, false)
	   end,
    TC = fun() ->
		 element(1,timer:tc(T))
	 end,
    nif_vs_erlang_performance({{{PTC1,TC},{PTC2,TC}},N,Sched}).
    

print_stats(Data) ->
    Length = length(Data),
    Mean = lists:sum(Data) / Length,
    Variance = lists:foldl(fun(N,Acc) -> math:pow(N - Mean, 2)+Acc end, 0, Data),
    StdDev = math:sqrt(Variance / Length),
    Median = lists:nth(round(Length/2),Data),
    Min = lists:min(Data),
    Max = lists:max(Data),
    if Length < 20 ->
	    io:format("Data: ~w~n",[Data]);
       true ->
	    ok
    end,
    io:format("Length: ~p~nMean: ~p~nStdDev: ~p~nMedian: ~p~nMin: ~p~nMax: ~p~n",
	      [Length,Mean,StdDev,Median,Min,Max]),
    {Length,Mean,StdDev,Median,Min,Max}.
    
collect(Acc) ->
    receive
	{Tag,Val} ->
	    Prev = proplists:get_value(Tag,Acc,[]),
	    collect(lists:keystore(Tag,1,Acc,{Tag,[Val|Prev]}))
    after 100 ->
	    Acc
    end.

exec(One,Two,Max,N) ->
    exec(One,Two,Max,N,{[],[]}).
exec(_,_,_,1,{D1,D2}) ->
    {lists:flatten(D1),lists:flatten(D2)};
exec({PreOne,One} = O,{PreTwo,Two} = T,MaxProcs, N, {D1,D2}) ->
    Num = random:uniform(round(N/2)),
    if Num rem 3 == 0 ->
	    timer:sleep(Num rem 1000);
       true ->
	    ok
    end,
    Procs = random:uniform(MaxProcs),
    io:format("\tBatch: ~p items in ~p processes, ~p left~n",[Num,Procs,N-Num]),
    if Num rem 2 == 1 ->
	    erlang:garbage_collect(),
	    PreOne(),
	    MoreOne = pexec(One, Num, Procs, []),
	    erlang:garbage_collect(),
	    PreTwo(),
	    MoreTwo = pexec(Two, Num, Procs, []);
       true ->
	    erlang:garbage_collect(),
	    PreTwo(),
	    MoreTwo = pexec(Two, Num, Procs, []),
	    erlang:garbage_collect(),
	    PreOne(),
	    MoreOne = pexec(One, Num, Procs, [])
    end,
    exec(O,T,MaxProcs,N-Num,{[MoreOne|D1],
			     [MoreTwo|D2]}).

pexec(_Fun, _, 0, []) ->
    [];
pexec(Fun, _, 0, [{Ref,Pid}|Rest]) ->
    receive
	{data,D} ->
	    [D|pexec(Fun,0,0,[{Ref,Pid}|Rest])];
	{'DOWN', Ref, process, Pid, normal} ->
	    pexec(Fun, 0,0,Rest)
    end;
pexec(Fun, 0, 1, AccProcs) ->
    pexec(Fun, 0, 0, AccProcs);
pexec(Fun, N, 1, AccProcs) ->
    [Fun()|pexec(Fun, N - 1, 1, AccProcs)];
pexec(Fun, N, Procs, AccProcs) ->
    S = self(),
    Pid = spawn(fun() ->
			S ! {data,pexec(Fun,N,1,[])}
		end),
    Ref = erlang:monitor(process, Pid),
    pexec(Fun, N, Procs - 1, [{Ref,Pid}|AccProcs]).

strip(Data,Num) ->
    {_,R} = lists:split(Num,lists:sort(Data)),
    element(2,lists:split(Num,lists:reverse(R))).

faster(A,B) ->
    (B - A)/B * 100.

enc_dec(1, Msg, N) ->
    worker_loop(N, Msg);
enc_dec(NumOfProcs,Msg, N) ->
    pforeach(fun(_) ->
		     worker_loop(N, Msg)
	     end, [I || I <- lists:seq(1,NumOfProcs)]).

worker_loop(0, _Msg) ->
    ok;
worker_loop(N, Msg) ->
    ?line {ok,B}=asn1_wrapper:encode('NBAP-PDU-Discriptions',
				     'NBAP-PDU',
				     Msg),
    ?line {ok,_Msg}=asn1_wrapper:decode('NBAP-PDU-Discriptions',
					'NBAP-PDU',
					B),
    worker_loop(N - 1, Msg).


pforeach(Fun, List) ->
    pforeach(Fun, List, []).
pforeach(Fun, [], [{Pid,Ref}|Pids]) ->
    receive
	{'DOWN', Ref, process, Pid, normal} ->
	    pforeach(Fun, [], Pids)
    end;
pforeach(Fun, [H|T], Pids) ->
    Pid = spawn(fun() -> Fun(H) end),
    Ref = erlang:monitor(process, Pid),
    pforeach(Fun, T, [{Pid, Ref}|Pids]);
pforeach(_Fun,[],[]) ->
    ok.
    
-record('InitiatingMessage',{procedureCode,criticality,value}).
-record('Iu-ReleaseCommand',{first,second}).

ticket7904(suite) -> [];
ticket7904(Config) ->
    ?line DataDir = ?config(data_dir,Config),
    ?line OutDir = ?config(priv_dir,Config),

    ?line ok = asn1ct:compile(DataDir ++ 
		      "RANAPextract1",[per_bin,optimize,{outdir,OutDir}]),

    Val1 = #'InitiatingMessage'{procedureCode=1,
				criticality=ignore,
				value=#'Iu-ReleaseCommand'{
				  first=13,
				  second=true}},

    ?line {ok,_} = 'RANAPextract1':encode('InitiatingMessage', Val1),
    asn1rt:unload_driver(),
    ?line {ok,_} = 'RANAPextract1':encode('InitiatingMessage', Val1).

cert_pem() ->
    'OTP-PUB-KEY':decode('Certificate',<<48,130,3,184,48,130,3,33,160,3,2,1,2,2,1,1,48,13,6,9,42,134,72,134,247,13,1,1,5,5,0,48,129,131,49,14,48,12,6,3,85,4,3,19,5,111,116,112,67,65,49,19,48,17,6,3,85,4,11,19,10,69,114,108,97,110,103,32,79,84,80,49,20,48,18,6,3,85,4,10,19,11,69,114,105,99,115,115,111,110,32,65,66,49,11,48,9,6,3,85,4,6,19,2,83,69,49,18,48,16,6,3,85,4,7,19,9,83,116,111,99,107,104,111,108,109,49,37,48,35,6,9,42,134,72,134,247,13,1,9,1,22,22,112,101,116,101,114,64,101,114,105,120,46,101,114,105,99,115,115,111,110,46,115,101,48,30,23,13,48,56,48,49,48,57,48,56,50,57,51,48,90,23,13,49,55,49,49,49,55,48,56,50,57,51,48,90,48,129,132,49,15,48,13,6,3,85,4,3,19,6,99,108,105,101,110,116,49,19,48,17,6,3,85,4,11,19,10,69,114,108,97,110,103,32,79,84,80,49,20,48,18,6,3,85,4,10,19,11,69,114,105,99,115,115,111,110,32,65,66,49,11,48,9,6,3,85,4,6,19,2,83,69,49,18,48,16,6,3,85,4,7,19,9,83,116,111,99,107,104,111,108,109,49,37,48,35,6,9,42,134,72,134,247,13,1,9,1,22,22,112,101,116,101,114,64,101,114,105,120,46,101,114,105,99,115,115,111,110,46,115,101,48,129,159,48,13,6,9,42,134,72,134,247,13,1,1,1,5,0,3,129,141,0,48,129,137,2,129,129,0,245,56,68,254,220,239,193,190,63,221,182,60,67,77,121,163,214,136,137,183,139,8,166,30,100,27,45,17,126,58,15,173,151,218,75,224,148,14,22,164,10,100,186,183,104,175,197,97,96,182,146,150,106,129,140,100,194,106,90,62,133,233,155,46,155,33,101,220,83,193,182,232,240,99,253,249,114,8,159,172,143,77,179,132,229,205,29,110,185,233,224,52,25,149,249,100,80,229,199,125,23,106,146,233,159,26,13,8,161,206,221,43,240,149,42,45,194,190,85,6,235,152,220,219,160,32,144,67,2,3,1,0,1,163,130,1,55,48,130,1,51,48,9,6,3,85,29,19,4,2,48,0,48,11,6,3,85,29,15,4,4,3,2,5,224,48,29,6,3,85,29,14,4,22,4,20,26,59,44,5,72,211,158,214,23,34,30,241,125,27,123,115,93,163,231,120,48,129,179,6,3,85,29,35,4,129,171,48,129,168,128,20,6,171,128,52,58,164,184,118,178,189,157,46,40,229,109,145,222,125,1,155,161,129,140,164,129,137,48,129,134,49,17,48,15,6,3,85,4,3,19,8,101,114,108,97,110,103,67,65,49,19,48,17,6,3,85,4,11,19,10,69,114,108,97,110,103,32,79,84,80,49,20,48,18,6,3,85,4,10,19,11,69,114,105,99,115,115,111,110,32,65,66,49,18,48,16,6,3,85,4,7,19,9,83,116,111,99,107,104,111,108,109,49,11,48,9,6,3,85,4,6,19,2,83,69,49,37,48,35,6,9,42,134,72,134,247,13,1,9,1,22,22,112,101,116,101,114,64,101,114,105,120,46,101,114,105,99,115,115,111,110,46,115,101,130,1,1,48,33,6,3,85,29,17,4,26,48,24,129,22,112,101,116,101,114,64,101,114,105,120,46,101,114,105,99,115,115,111,110,46,115,101,48,33,6,3,85,29,18,4,26,48,24,129,22,112,101,116,101,114,64,101,114,105,120,46,101,114,105,99,115,115,111,110,46,115,101,48,13,6,9,42,134,72,134,247,13,1,1,5,5,0,3,129,129,0,93,11,112,227,121,15,121,179,247,135,110,216,17,197,84,18,149,166,147,142,190,178,0,209,190,0,142,233,144,100,194,205,220,182,73,204,108,42,95,23,48,63,4,120,239,42,194,25,184,35,117,107,96,229,18,45,76,122,125,40,171,210,132,50,146,178,160,55,17,35,255,208,114,30,47,55,185,154,155,165,204,180,14,143,20,234,6,234,201,225,72,235,5,87,61,255,250,23,217,1,144,246,98,221,223,102,49,168,177,13,70,241,26,27,254,251,217,14,244,18,242,197,151,50,186,214,15,42>>).

dsa_pem() ->
    'OTP-PUB-KEY':decode('DSAPrivateKey',<<48,130,1,187,2,1,0,2,129,129,0,183,179,230,217,37,99,144,157,21,228,204,162,207,61,246,144,58,139,139,184,184,43,108,206,0,115,173,208,100,233,201,121,21,90,179,119,53,140,25,52,34,202,121,211,164,107,43,56,68,162,159,51,244,232,138,126,164,109,121,89,237,142,57,28,32,188,44,67,253,111,121,104,40,141,211,255,140,118,37,234,150,201,155,160,16,17,51,59,26,249,41,129,16,211,119,128,95,254,182,235,132,0,92,206,93,77,106,217,201,132,203,4,75,201,246,204,216,162,1,84,79,211,10,21,152,195,103,145,2,21,0,213,30,184,86,247,16,247,69,192,241,35,138,84,57,140,3,71,65,206,233,2,129,129,0,148,179,24,63,74,91,128,25,96,29,5,78,223,246,175,0,121,86,54,178,42,231,98,241,147,180,157,60,149,160,50,243,227,76,175,89,234,203,252,242,76,108,9,204,157,182,59,206,227,127,99,215,42,156,194,78,116,25,7,62,243,169,45,5,101,179,247,127,199,144,135,103,23,42,154,125,231,248,154,101,175,155,101,42,232,41,80,41,47,128,208,11,31,106,63,12,202,207,135,80,200,136,250,171,31,118,52,91,200,138,112,111,179,23,214,123,21,118,194,179,0,185,217,52,197,182,236,13,2,129,128,124,66,0,111,121,139,142,209,95,136,95,237,177,150,248,252,49,135,117,100,155,232,138,244,132,89,40,5,70,125,202,96,78,239,76,37,125,149,82,64,107,54,227,73,25,180,227,41,0,234,73,47,80,242,242,129,250,61,68,62,39,38,156,193,146,40,241,247,106,215,223,202,194,110,130,62,186,90,18,28,196,174,99,47,193,61,130,100,150,25,248,115,164,231,153,99,46,69,66,139,33,187,51,49,35,219,234,29,44,172,166,247,42,16,177,187,9,162,81,243,33,26,100,46,78,57,203,135,2,20,89,128,159,14,187,249,182,172,15,88,162,110,211,71,179,209,29,125,217,38>>),
    'OTP-PUB-KEY':decode('SubjectPublicKeyInfo',<<48,130,1,183,48,130,1,44,6,7,42,134,72,206,56,4,1,48,130,1,31,2,129,129,0,183,179,230,217,37,99,144,157,21,228,204,162,207,61,246,144,58,139,139,184,184,43,108,206,0,115,173,208,100,233,201,121,21,90,179,119,53,140,25,52,34,202,121,211,164,107,43,56,68,162,159,51,244,232,138,126,164,109,121,89,237,142,57,28,32,188,44,67,253,111,121,104,40,141,211,255,140,118,37,234,150,201,155,160,16,17,51,59,26,249,41,129,16,211,119,128,95,254,182,235,132,0,92,206,93,77,106,217,201,132,203,4,75,201,246,204,216,162,1,84,79,211,10,21,152,195,103,145,2,21,0,213,30,184,86,247,16,247,69,192,241,35,138,84,57,140,3,71,65,206,233,2,129,129,0,148,179,24,63,74,91,128,25,96,29,5,78,223,246,175,0,121,86,54,178,42,231,98,241,147,180,157,60,149,160,50,243,227,76,175,89,234,203,252,242,76,108,9,204,157,182,59,206,227,127,99,215,42,156,194,78,116,25,7,62,243,169,45,5,101,179,247,127,199,144,135,103,23,42,154,125,231,248,154,101,175,155,101,42,232,41,80,41,47,128,208,11,31,106,63,12,202,207,135,80,200,136,250,171,31,118,52,91,200,138,112,111,179,23,214,123,21,118,194,179,0,185,217,52,197,182,236,13,3,129,132,0,2,129,128,124,66,0,111,121,139,142,209,95,136,95,237,177,150,248,252,49,135,117,100,155,232,138,244,132,89,40,5,70,125,202,96,78,239,76,37,125,149,82,64,107,54,227,73,25,180,227,41,0,234,73,47,80,242,242,129,250,61,68,62,39,38,156,193,146,40,241,247,106,215,223,202,194,110,130,62,186,90,18,28,196,174,99,47,193,61,130,100,150,25,248,115,164,231,153,99,46,69,66,139,33,187,51,49,35,219,234,29,44,172,166,247,42,16,177,187,9,162,81,243,33,26,100,46,78,57,203,135>>),
    'OTP-PUB-KEY':decode('DSAParams',<<48,130,1,31,2,129,129,0,183,179,230,217,37,99,144,157,21,228,204,162,207,61,246,144,58,139,139,184,184,43,108,206,0,115,173,208,100,233,201,121,21,90,179,119,53,140,25,52,34,202,121,211,164,107,43,56,68,162,159,51,244,232,138,126,164,109,121,89,237,142,57,28,32,188,44,67,253,111,121,104,40,141,211,255,140,118,37,234,150,201,155,160,16,17,51,59,26,249,41,129,16,211,119,128,95,254,182,235,132,0,92,206,93,77,106,217,201,132,203,4,75,201,246,204,216,162,1,84,79,211,10,21,152,195,103,145,2,21,0,213,30,184,86,247,16,247,69,192,241,35,138,84,57,140,3,71,65,206,233,2,129,129,0,148,179,24,63,74,91,128,25,96,29,5,78,223,246,175,0,121,86,54,178,42,231,98,241,147,180,157,60,149,160,50,243,227,76,175,89,234,203,252,242,76,108,9,204,157,182,59,206,227,127,99,215,42,156,194,78,116,25,7,62,243,169,45,5,101,179,247,127,199,144,135,103,23,42,154,125,231,248,154,101,175,155,101,42,232,41,80,41,47,128,208,11,31,106,63,12,202,207,135,80,200,136,250,171,31,118,52,91,200,138,112,111,179,23,214,123,21,118,194,179,0,185,217,52,197,182,236,13>>),
    'OTP-PUB-KEY':decode('DSAPublicKey',<<2,129,128,124,66,0,111,121,139,142,209,95,136,95,237,177,150,248,252,49,135,117,100,155,232,138,244,132,89,40,5,70,125,202,96,78,239,76,37,125,149,82,64,107,54,227,73,25,180,227,41,0,234,73,47,80,242,242,129,250,61,68,62,39,38,156,193,146,40,241,247,106,215,223,202,194,110,130,62,186,90,18,28,196,174,99,47,193,61,130,100,150,25,248,115,164,231,153,99,46,69,66,139,33,187,51,49,35,219,234,29,44,172,166,247,42,16,177,187,9,162,81,243,33,26,100,46,78,57,203,135>>),
    'OTP-PUB-KEY':encode('DSAParams',{params,{'Dss-Parms',129000451850199666185842362389296595317127259539517666765336291347244303954511451744518587442120964433734460998523119938005801396466878889993179871123036311260456172022864663021425348874648247531097042575063545128239655736096045972718934778583429973433661785691086624069991876932064334822608460064613803976593,1216700114794736143432235288305776850295620488937,104420402274523493329542694749036577763086597934731674202966304958550599470165597750883637440049774107540742087494301536297571301945349213110548764383811017178451900599240379681904765817950545426764751538502808499880604633364255316249231153053427235538288687666086821781456733226598288985591031656134573747213}}),
    'OTP-PUB-KEY':encode(
      'SubjectPublicKeyInfo',
      {'SubjectPublicKeyInfo',
       {'AlgorithmIdentifier',
        {1,2,840,10040,4,1},
        <<48,130,1,31,2,129,129,0,183,179,230,217,37,99,144,157,21,228,204,162,207,61,246,144,58,139,139,184,184,43,108,206,0,115,173,208,100,233,201,121,21,90,179,119,53,140,25,52,34,202,121,211,164,107,43,56,68,162,159,51,244,232,138,126,164,109,121,89,237,142,57,28,32,188,44,67,253,111,121,104,40,141,211,255,140,118,37,234,150,201,155,160,16,17,51,59,26,249,41,129,16,211,119,128,95,254,182,235,132,0,92,206,93,77,106,217,201,132,203,4,75,201,246,204,216,162,1,84,79,211,10,21,152,195,103,145,2,21,0,213,30,184,86,247,16,247,69,192,241,35,138,84,57,140,3,71,65,206,233,2,129,129,0,148,179,24,63,74,91,128,25,96,29,5,78,223,246,175,0,121,86,54,178,42,231,98,241,147,180,157,60,149,160,50,243,227,76,175,89,234,203,252,242,76,108,9,204,157,182,59,206,227,127,99,215,42,156,194,78,116,25,7,62,243,169,45,5,101,179,247,127,199,144,135,103,23,42,154,125,231,248,154,101,175,155,101,42,232,41,80,41,47,128,208,11,31,106,63,12,202,207,135,80,200,136,250,171,31,118,52,91,200,138,112,111,179,23,214,123,21,118,194,179,0,185,217,52,197,182,236,13>>},
       {0,
	<<2,129,128,124,66,0,111,121,139,142,209,95,136,95,237,177,150,248,252,49,135,117,100,155,232,138,244,132,89,40,5,70,125,202,96,78,239,76,37,125,149,82,64,107,54,227,73,25,180,227,41,0,234,73,47,80,242,242,129,250,61,68,62,39,38,156,193,146,40,241,247,106,215,223,202,194,110,130,62,186,90,18,28,196,174,99,47,193,61,130,100,150,25,248,115,164,231,153,99,46,69,66,139,33,187,51,49,35,219,234,29,44,172,166,247,42,16,177,187,9,162,81,243,33,26,100,46,78,57,203,135>>}}).