Contract con_dex_v2_test4


Contract Code


  
1 import currency
2 I = importlib
3 token_interface = [I.Func('transfer', args=('amount', 'to')), I.Func(
4 'approve', args=('amount', 'to')), I.Func('transfer_from', args=(
5 'amount', 'to', 'main_account'))]
6 pairs = Hash()
7 prices = Hash(default_value=0)
8 lp_points = Hash(default_value=0)
9 reserves = Hash(default_value=[0, 0])
10 staked_amount = Hash(default_value=0)
11 discount = Hash(default_value=1)
12 state = Hash()
13 def init():
14 state['FEE_PERCENTAGE'] = decimal('0.5') / 100
15 state['TOKEN_CONTRACT'] = 'con_rswp_lst001'
16 state['TOKEN_DISCOUNT'] = decimal('0.75')
17 state['BURN_PERCENTAGE'] = decimal('0.8')
18 state['BURN_ADDRESS'] = 'burn'
19 state['LOG_ACCURACY'] = decimal('1000000000.0')
20 state['MULTIPLIER'] = decimal('0.07')
21 state['DISCOUNT_FLOOR'] = decimal('0.505')
22 state['OWNER'] = ctx.caller
23 @export
24 def create_market(contract: str, currency_amount: float=0, token_amount:
25 float=0):
26 assert pairs[contract] is None, 'Market already exists!'
27 assert currency_amount > 0 and token_amount > 0, 'Must provide currency amount and token amount!'
28 token = I.import_module(contract)
29 assert I.enforce_interface(token, token_interface
30 ), 'Invalid token interface!'
31 currency.transfer_from(amount=currency_amount, to=ctx.this,
32 main_account=ctx.caller)
33 token.transfer_from(amount=token_amount, to=ctx.this, main_account=ctx.
34 caller)
35 prices[contract] = currency_amount / token_amount
36 pairs[contract] = True
37 lp_points[contract, ctx.caller] = 100
38 lp_points[contract] = 100
39 reserves[contract] = [currency_amount, token_amount]
40 return True
41 @export
42 def liquidity_balance_of(contract: str, account: str):
43 return lp_points[contract, account]
44 @export
45 def add_liquidity(contract: str, currency_amount: float=0):
46 assert pairs[contract] is True, 'Market does not exist!'
47 assert currency_amount > 0
48 token = I.import_module(contract)
49 assert I.enforce_interface(token, token_interface
50 ), 'Invalid token interface!'
51 token_amount = currency_amount / prices[contract]
52 currency.transfer_from(amount=currency_amount, to=ctx.this,
53 main_account=ctx.caller)
54 token.transfer_from(amount=token_amount, to=ctx.this, main_account=ctx.
55 caller)
56 total_lp_points = lp_points[contract]
57 currency_reserve, token_reserve = reserves[contract]
58 points_per_currency = total_lp_points / currency_reserve
59 lp_to_mint = points_per_currency * currency_amount
60 lp_points[contract, ctx.caller] += lp_to_mint
61 lp_points[contract] += lp_to_mint
62 reserves[contract] = [currency_reserve + currency_amount,
63 token_reserve + token_amount]
64 return lp_to_mint
65 @export
66 def remove_liquidity(contract: str, amount: float=0):
67 assert pairs[contract] is True, 'Market does not exist!'
68 assert amount > 0, 'Must be a positive LP point amount!'
69 assert lp_points[contract, ctx.caller
70 ] >= amount, 'Not enough LP points to remove!'
71 token = I.import_module(contract)
72 assert I.enforce_interface(token, token_interface
73 ), 'Invalid token interface!'
74 lp_percentage = amount / lp_points[contract]
75 currency_reserve, token_reserve = reserves[contract]
76 currency_amount = currency_reserve * lp_percentage
77 token_amount = token_reserve * lp_percentage
78 currency.transfer(to=ctx.caller, amount=currency_amount)
79 token.transfer(to=ctx.caller, amount=token_amount)
80 lp_points[contract, ctx.caller] -= amount
81 lp_points[contract] -= amount
82 assert lp_points[contract] > 1, 'Not enough remaining liquidity!'
83 new_currency_reserve = currency_reserve - currency_amount
84 new_token_reserve = token_reserve - token_amount
85 assert new_currency_reserve > 0 and new_token_reserve > 0, 'Not enough remaining liquidity!'
86 reserves[contract] = [new_currency_reserve, new_token_reserve]
87 return currency_amount, token_amount
88 @export
89 def transfer_liquidity(contract: str, to: str, amount: float):
90 assert amount > 0, 'Must be a positive LP point amount!'
91 assert lp_points[contract, ctx.caller
92 ] >= amount, 'Not enough LP points to transfer!'
93 lp_points[contract, ctx.caller] -= amount
94 lp_points[contract, to] += amount
95 @export
96 def approve_liquidity(contract: str, to: str, amount: float):
97 assert amount > 0, 'Cannot send negative balances!'
98 lp_points[contract, ctx.caller, to] += amount
99 @export
100 def transfer_liquidity_from(contract: str, to: str, main_account: str,
101 amount: float):
102 assert amount > 0, 'Cannot send negative balances!'
103 assert lp_points[contract, main_account, ctx.caller
104 ] >= amount, 'Not enough coins approved to send! You have {} and are trying to spend {}'.format(
105 lp_points[main_account, ctx.caller], amount)
106 assert lp_points[contract, main_account
107 ] >= amount, 'Not enough coins to send!'
108 lp_points[contract, main_account, ctx.caller] -= amount
109 lp_points[contract, main_account] -= amount
110 lp_points[contract, to] += amount
111 @export
112 def buy(contract: str, currency_amount: float, minimum_received: float=0,
113 token_fees: bool=False):
114 assert pairs[contract] is True, 'Market does not exist!'
115 assert currency_amount > 0, 'Must provide currency amount!'
116 token = I.import_module(contract)
117 amm_token = I.import_module(state['TOKEN_CONTRACT'])
118 assert I.enforce_interface(token, token_interface
119 ), 'Invalid token interface!'
120 if contract == state['TOKEN_CONTRACT']:
121 currency.transfer_from(amount=currency_amount, to=ctx.this,
122 main_account=ctx.caller)
123 tokens_purchased = internal_buy(contract=state['TOKEN_CONTRACT'
124 ], currency_amount=currency_amount)
125 token.transfer(amount=tokens_purchased, to=ctx.caller)
126 return tokens_purchased
127 currency_reserve, token_reserve = reserves[contract]
128 k = currency_reserve * token_reserve
129 new_currency_reserve = currency_reserve + currency_amount
130 new_token_reserve = k / new_currency_reserve
131 tokens_purchased = token_reserve - new_token_reserve
132 fee_percent = state['FEE_PERCENTAGE'] * discount[ctx.caller]
133 fee = tokens_purchased * fee_percent
134 if token_fees is True:
135 fee = fee * state['TOKEN_DISCOUNT']
136 rswp_k = currency_reserve * token_reserve
137 rswp_new_token_reserve = token_reserve + fee
138 rswp_new_currency_reserve = rswp_k / rswp_new_token_reserve
139 rswp_currency_purchased = currency_reserve - rswp_new_currency_reserve
140 rswp_currency_purchased += rswp_currency_purchased * fee_percent
141 rswp_currency_reserve_2, rswp_token_reserve_2 = reserves[state[
142 'TOKEN_CONTRACT']]
143 rswp_k_2 = rswp_currency_reserve_2 * rswp_token_reserve_2
144 rswp_new_currency_reserve_2 = (rswp_currency_reserve_2 +
145 rswp_currency_purchased)
146 rswp_new_currency_reserve_2 += rswp_currency_purchased * fee_percent
147 rswp_new_token_reserve_2 = rswp_k_2 / rswp_new_currency_reserve_2
148 sell_amount = rswp_token_reserve_2 - rswp_new_token_reserve_2
149 sell_amount_with_fee = sell_amount * state['BURN_PERCENTAGE']
150 amm_token.transfer_from(amount=sell_amount, to=ctx.this,
151 main_account=ctx.caller)
152 currency_received = internal_sell(contract=state[
153 'TOKEN_CONTRACT'], token_amount=sell_amount_with_fee)
154 amm_token.transfer(amount=sell_amount - sell_amount_with_fee, to=
155 state['BURN_ADDRESS'])
156 token_received = internal_buy(contract=contract, currency_amount=
157 currency_received)
158 new_currency_reserve += reserves[contract][0] - currency_reserve
159 new_token_reserve += reserves[contract][1] - token_reserve
160 new_token_reserve = new_token_reserve + token_received
161 else:
162 tokens_purchased = tokens_purchased - fee
163 burn_amount = internal_buy(contract=state['TOKEN_CONTRACT'],
164 currency_amount=internal_sell(contract=contract, token_amount
165 =fee - fee * state['BURN_PERCENTAGE']))
166 new_currency_reserve += reserves[contract][0] - currency_reserve
167 new_token_reserve += reserves[contract][1] - token_reserve
168 new_token_reserve = new_token_reserve + fee * state['BURN_PERCENTAGE'
169 ]
170 amm_token.transfer(amount=burn_amount, to=state['BURN_ADDRESS'])
171 if minimum_received != None:
172 assert tokens_purchased >= minimum_received, 'Only {} tokens can be purchased, which is less than your minimum, which is {} tokens.'.format(
173 tokens_purchased, minimum_received)
174 assert tokens_purchased > 0, 'Token reserve error!'
175 currency.transfer_from(amount=currency_amount, to=ctx.this,
176 main_account=ctx.caller)
177 token.transfer(amount=tokens_purchased, to=ctx.caller)
178 reserves[contract] = [new_currency_reserve, new_token_reserve]
179 prices[contract] = new_currency_reserve / new_token_reserve
180 return tokens_purchased
181 @export
182 def sell(contract: str, token_amount: float, minimum_received: float=0,
183 token_fees: bool=False):
184 assert pairs[contract] is True, 'Market does not exist!'
185 assert token_amount > 0, 'Must provide currency amount and token amount!'
186 token = I.import_module(contract)
187 amm_token = I.import_module(state['TOKEN_CONTRACT'])
188 assert I.enforce_interface(token, token_interface
189 ), 'Invalid token interface!'
190 if contract == state['TOKEN_CONTRACT']:
191 token.transfer_from(amount=token_amount, to=ctx.this, main_account=
192 ctx.caller)
193 currency_purchased = internal_sell(contract=state[
194 'TOKEN_CONTRACT'], token_amount=token_amount)
195 currency.transfer(amount=currency_purchased, to=ctx.caller)
196 return currency_purchased
197 currency_reserve, token_reserve = reserves[contract]
198 k = currency_reserve * token_reserve
199 new_token_reserve = token_reserve + token_amount
200 new_currency_reserve = k / new_token_reserve
201 currency_purchased = currency_reserve - new_currency_reserve
202 fee_percent = state['FEE_PERCENTAGE'] * discount[ctx.caller]
203 fee = currency_purchased * fee_percent
204 if token_fees is True:
205 fee = fee * state['TOKEN_DISCOUNT']
206 rswp_currency_reserve, rswp_token_reserve = reserves[state[
207 'TOKEN_CONTRACT']]
208 rswp_k = rswp_currency_reserve * rswp_token_reserve
209 rswp_new_currency_reserve = rswp_currency_reserve + fee
210 rswp_new_currency_reserve += fee * fee_percent
211 rswp_new_token_reserve = rswp_k / rswp_new_currency_reserve
212 sell_amount = rswp_token_reserve - rswp_new_token_reserve
213 sell_amount_with_fee = sell_amount * state['BURN_PERCENTAGE']
214 amm_token.transfer_from(amount=sell_amount, to=ctx.this,
215 main_account=ctx.caller)
216 currency_received = internal_sell(contract=state[
217 'TOKEN_CONTRACT'], token_amount=sell_amount_with_fee)
218 amm_token.transfer(amount=sell_amount - sell_amount_with_fee, to=
219 state['BURN_ADDRESS'])
220 new_currency_reserve = new_currency_reserve + currency_received
221 else:
222 currency_purchased = currency_purchased - fee
223 burn_amount = fee - fee * state['BURN_PERCENTAGE']
224 new_currency_reserve = new_currency_reserve + fee * state[
225 'BURN_PERCENTAGE']
226 token_received = internal_buy(contract=state['TOKEN_CONTRACT'],
227 currency_amount=burn_amount)
228 amm_token.transfer(amount=token_received, to=state['BURN_ADDRESS'])
229 if minimum_received != None:
230 assert currency_purchased >= minimum_received, 'Only {} TAU can be purchased, which is less than your minimum, which is {} TAU.'.format(
231 currency_purchased, minimum_received)
232 assert currency_purchased > 0, 'Token reserve error!'
233 token.transfer_from(amount=token_amount, to=ctx.this, main_account=ctx.
234 caller)
235 currency.transfer(amount=currency_purchased, to=ctx.caller)
236 reserves[contract] = [new_currency_reserve, new_token_reserve]
237 prices[contract] = new_currency_reserve / new_token_reserve
238 return currency_purchased
239 @export
240 def stake(amount: float, token_contract: str=None):
241 assert amount >= 0, 'Must be a positive stake amount!'
242 if token_contract == None:
243 token_contract = state['TOKEN_CONTRACT']
244 amm_token = I.import_module(token_contract)
245 current_balance = staked_amount[ctx.caller, token_contract]
246 if amount < current_balance:
247 amm_token.transfer(current_balance - amount, ctx.caller)
248 staked_amount[ctx.caller, token_contract] = amount
249 discount_amount = state['LOG_ACCURACY'] * (staked_amount[ctx.
250 caller, state['TOKEN_CONTRACT']] ** (1 / state[
251 'LOG_ACCURACY']) - 1) * state['MULTIPLIER'] - state[
252 'DISCOUNT_FLOOR']
253 if discount_amount > decimal('0.99'):
254 discount_amount = decimal('0.99')
255 if discount_amount < 0:
256 discount_amount = 0
257 discount[ctx.caller] = 1 - discount_amount
258 return discount_amount
259 elif amount > current_balance:
260 amm_token.transfer_from(amount - current_balance, ctx.this, ctx.caller)
261 staked_amount[ctx.caller, token_contract] = amount
262 discount_amount = state['LOG_ACCURACY'] * (staked_amount[ctx.
263 caller, state['TOKEN_CONTRACT']] ** (1 / state[
264 'LOG_ACCURACY']) - 1) * state['MULTIPLIER'] - state[
265 'DISCOUNT_FLOOR']
266 if discount_amount > decimal('0.99'):
267 discount_amount = decimal('0.99')
268 if discount_amount < 0:
269 discount_amount = 0
270 discount[ctx.caller] = 1 - discount_amount
271 return discount_amount
272 @export
273 def change_state(key: str, new_value: str, convert_to_decimal: bool=False):
274 assert state['OWNER'] == ctx.caller, 'Not the owner!'
275 if convert_to_decimal:
276 new_value = decimal(new_value)
277 state[key] = new_value
278 return new_value
279 @export
280 def change_state_float(key: str, new_value: float, convert_to_int: bool=False):
281 assert state['OWNER'] == ctx.caller, 'Not the owner!'
282 if convert_to_int:
283 new_value = int(new_value)
284 state[key] = new_value
285 return new_value
286 @export
287 def sync_reserves(contract: str):
288 assert state['SYNC_ENABLED'] is True, 'Sync is not enabled!'
289 token = I.import_module(contract)
290 new_balance = token.balance_of(ctx.this)
291 assert new_balance > 0, 'Cannot be a negative balance!'
292 reserves[contract][1] = new_balance
293 return new_balance
294 def internal_buy(contract: str, currency_amount: float):
295 assert pairs[contract] is True, 'RSWP Market does not exist!'
296 if currency_amount <= 0:
297 return 0
298 token = I.import_module(contract)
299 assert I.enforce_interface(token, token_interface
300 ), 'Invalid token interface!'
301 currency_reserve, token_reserve = reserves[contract]
302 k = currency_reserve * token_reserve
303 new_currency_reserve = currency_reserve + currency_amount
304 new_token_reserve = k / new_currency_reserve
305 tokens_purchased = token_reserve - new_token_reserve
306 fee = tokens_purchased * state['FEE_PERCENTAGE']
307 tokens_purchased -= fee
308 new_token_reserve += fee
309 assert tokens_purchased > 0, 'Token reserve error!'
310 reserves[contract] = [new_currency_reserve, new_token_reserve]
311 prices[contract] = new_currency_reserve / new_token_reserve
312 return tokens_purchased
313 def internal_sell(contract: str, token_amount: float):
314 assert pairs[contract] is True, 'RSWP Market does not exist!'
315 if token_amount <= 0:
316 return 0
317 token = I.import_module(contract)
318 assert I.enforce_interface(token, token_interface
319 ), 'Invalid token interface!'
320 currency_reserve, token_reserve = reserves[contract]
321 k = currency_reserve * token_reserve
322 new_token_reserve = token_reserve + token_amount
323 new_currency_reserve = k / new_token_reserve
324 currency_purchased = currency_reserve - new_currency_reserve
325 fee = currency_purchased * state['FEE_PERCENTAGE']
326 currency_purchased -= fee
327 new_currency_reserve += fee
328 assert currency_purchased > 0, 'Token reserve error!'
329 reserves[contract] = [new_currency_reserve, new_token_reserve]
330 prices[contract] = new_currency_reserve / new_token_reserve
331 return currency_purchased
332

Byte Code

e30000000000000000000000000700000040000000731e020000640064016c005a0065015a0265026a036402644264058d0265026a036406644364058d0265026a036407644464058d0267035a0465056409640a640b8d025a06650564006409640c640d8d035a07650564006409640e640d8d035a0865056400640067026409640f640d8d035a096505640064096410640d8d035a0a6505641164096412640d8d035a0b650564096413640b8d025a0c6414641584005a0d650e640983016445650f6510651064169c0364176418840583015a11650e64098301650f650f64199c02641a641b840483015a12650e640983016446650f6510641c9c02641d641e840583015a13650e640983016447650f6510641f9c0264206421840583015a14650e64098301650f650f651064229c0364236424840483015a15650e64098301650f650f651064229c0364256426840483015a16650e64098301650f650f650f651064279c0464286429840483015a17650e640983016448650f651065106518642b9c04642c642d840583015a19650e640983016449650f651065106518642e9c04642f6430840583015a1a650e64098301644a6510650f64319c0264326433840583015a1b650e64098301644b650f650f651864349c0364356436840583015a1c650e64098301644c650f6510651864379c0364386439840583015a1d650e64098301650f643a9c01643b643c840483015a1e650f6510641c9c02643d643e84045a1f650f6510643f9c026440644184045a2064015300294de9000000004eda087472616e73666572da06616d6f756e74da02746f2901da0461726773da07617070726f7665da0d7472616e736665725f66726f6dda0c6d61696e5f6163636f756e74da10636f6e5f6465785f76325f7465737434da0570616972732902da08636f6e7472616374da046e616d65da067072696365732903da0d64656661756c745f76616c7565720b000000720c000000da096c705f706f696e7473da087265736572766573da0d7374616b65645f616d6f756e74e901000000da08646973636f756e74da057374617465630000000000000000000000000300000043000000736a00000074006401830164021b00740164033c006404740164053c00740064068301740164073c00740064088301740164093c00640a7401640b3c007400640c83017401640d3c007400640e83017401640f3c00740064108301740164113c0074026a03740164123c006400530029134e7a03302e35e964000000da0e4645455f50455243454e54414745da0f636f6e5f727377705f6c7374303031da0e544f4b454e5f434f4e54524143547a04302e3735da0e544f4b454e5f444953434f554e547a03302e38da0f4255524e5f50455243454e54414745da046275726eda0c4255524e5f414444524553537a0c313030303030303030302e30da0c4c4f475f41434355524143597a04302e3037da0a4d554c5449504c4945527a05302e353035da0e444953434f554e545f464c4f4f52da054f574e45522904da07646563696d616cda075f5f7374617465da03637478da0663616c6c6572a90072250000007225000000da00da065f5f696e69741300000073120000000001100108010c010c0108010c010c010c0172270000002903720b000000da0f63757272656e63795f616d6f756e74da0c746f6b656e5f616d6f756e7463030000000000000004000000050000004300000073ac00000074007c00190064006b08731474016401830182017c0164026b0472247c0264026b04732c740164038301820174026a037c0083017d0374026a047c0374058302734a740164048301820174066a077c0174086a0974086a0a64058d0301007c036a077c0274086a0974086a0a64058d0301007c017c021b00740b7c003c00640674007c003c006407740c7c0074086a0a66023c006407740c7c003c007c017c026702740d7c003c006406530029084e7a164d61726b657420616c7265616479206578697374732172010000007a2e4d7573742070726f766964652063757272656e637920616d6f756e7420616e6420746f6b656e20616d6f756e74217a18496e76616c696420746f6b656e20696e74657266616365212903720300000072040000007208000000547215000000290eda075f5f7061697273da0e417373657274696f6e4572726f72da0149da0d696d706f72745f6d6f64756c65da11656e666f7263655f696e74657266616365da0f746f6b656e5f696e74657266616365da0863757272656e637972070000007223000000da04746869737224000000da085f5f707269636573da0b5f5f6c705f706f696e7473da0a5f5f72657365727665732904720b00000072280000007229000000da05746f6b656e722500000072250000007226000000da0d6372656174655f6d61726b65741f000000731c0000000003140118010a010e0106010a010a0114020c0108010e0108010c0172360000002902720b000000da076163636f756e74630200000000000000020000000300000043000000730c00000074007c007c0166021900530029014e290172330000002902720b0000007237000000722500000072250000007226000000da146c69717569646974795f62616c616e63655f6f66330000007302000000000272380000002902720b000000722800000063020000000000000009000000050000004300000073d400000074007c00190064016b08731474016402830182017c0164036b0473207401820174026a037c0083017d0274026a047c0274058302733e74016404830182017c0174067c0019001b007d0374076a087c0174096a0a74096a0b64058d0301007c026a087c0374096a0a74096a0b64058d030100740c7c0019007d04740d7c0019005c027d057d067c047c051b007d077c077c0114007d08740c7c0074096a0b6602050019007c08370003003c00740c7c00050019007c08370003003c007c057c0117007c067c0317006702740d7c003c007c08530029064e547a164d61726b657420646f6573206e6f742065786973742172010000007a18496e76616c696420746f6b656e20696e74657266616365212903720300000072040000007208000000290e722a000000722b000000722c000000722d000000722e000000722f000000723200000072300000007207000000722300000072310000007224000000723300000072340000002909720b000000722800000072350000007229000000da0f746f74616c5f6c705f706f696e7473da1063757272656e63795f72657365727665da0d746f6b656e5f72657365727665da13706f696e74735f7065725f63757272656e6379da0a6c705f746f5f6d696e74722500000072250000007226000000da0d6164645f6c6971756964697479380000007324000000000214010c010a010e0106010c010a010a01140208010c01080108011601100106010e01723e0000002902720b00000072030000006302000000000000000a0000000400000043000000731c01000074007c00190064016b08731474016402830182017c0164036b047324740164048301820174027c0074036a04660219007c016b05733e740164058301820174056a067c0083017d0274056a077c0274088302735c74016406830182017c0174027c0019001b007d0374097c0019005c027d047d057c047c0314007d067c057c0314007d07740a6a0b74036a047c0664078d0201007c026a0b74036a047c0764078d02010074027c0074036a046602050019007c01380003003c0074027c00050019007c01380003003c0074027c00190064086b0473de74016409830182017c047c0618007d087c057c0718007d097c0864036b046ffc7c0964036b049001730874016409830182017c087c09670274097c003c007c067c0766025300290a4e547a164d61726b657420646f6573206e6f742065786973742172010000007a234d757374206265206120706f736974697665204c5020706f696e7420616d6f756e74217a1f4e6f7420656e6f756768204c5020706f696e747320746f2072656d6f7665217a18496e76616c696420746f6b656e20696e746572666163652129027204000000720300000072120000007a1f4e6f7420656e6f7567682072656d61696e696e67206c697175696469747921290c722a000000722b000000723300000072230000007224000000722c000000722d000000722e000000722f000000723400000072300000007202000000290a720b00000072030000007235000000da0d6c705f70657263656e74616765723a000000723b00000072280000007229000000da146e65775f63757272656e63795f72657365727665da116e65775f746f6b656e5f72657365727665722500000072250000007226000000da1072656d6f76655f6c69717569646974794f000000732a0000000002140110010c010e010a010e0106010c010c010801080110011001160110011401080108011a010c0172420000002903720b0000007204000000720300000063030000000000000003000000040000004300000073580000007c0264016b047310740064028301820174017c0074026a03660219007c026b05732a740064038301820174017c0074026a036602050019007c02380003003c0074017c007c016602050019007c02370003003c006400530029044e72010000007a234d757374206265206120706f736974697665204c5020706f696e7420616d6f756e74217a214e6f7420656e6f756768204c5020706f696e747320746f207472616e73666572212904722b0000007233000000722300000072240000002903720b00000072040000007203000000722500000072250000007226000000da127472616e736665725f6c697175696469747968000000730a000000000210010c010e0116017243000000630300000000000000030000000400000043000000732c0000007c0264016b047310740064028301820174017c0074026a037c016603050019007c02370003003c006400530029034e72010000007a1e43616e6e6f742073656e64206e656761746976652062616c616e636573212904722b0000007233000000722300000072240000002903720b00000072040000007203000000722500000072250000007226000000da11617070726f76655f6c69717569646974797100000073040000000002100172440000002904720b000000720400000072080000007203000000630400000000000000040000000500000043000000739a0000007c0364016b047310740064028301820174017c007c0274026a03660319007c036b05733e740064036a0474017c0274026a03660219007c0383028301820174017c007c02660219007c036b057356740064048301820174017c007c0274026a036603050019007c03380003003c0074017c007c026602050019007c03380003003c0074017c007c016602050019007c03370003003c006400530029054e72010000007a1e43616e6e6f742073656e64206e656761746976652062616c616e636573217a494e6f7420656e6f75676820636f696e7320617070726f76656420746f2073656e642120596f752068617665207b7d20616e642061726520747279696e6720746f207370656e64207b7d7a194e6f7420656e6f75676820636f696e7320746f2073656e64212905722b000000723300000072230000007224000000da06666f726d61742904720b000000720400000072080000007203000000722500000072250000007226000000da177472616e736665725f6c69717569646974795f66726f6d770000007312000000000310010e010c0114010a010e01180114017246000000462904720b0000007228000000da106d696e696d756d5f7265636569766564da0a746f6b656e5f666565736304000000000000001c000000080000004300000073c802000074007c00190064016b08731474016402830182017c0164036b047324740164048301820174026a037c0083017d0474026a0374046405190083017d0574026a057c0474068302735074016406830182017c007404640519006b02729474076a087c0174096a0a74096a0b64078d030100740c7404640519007c0164088d027d067c046a0d7c0674096a0b64098d0201007c065300740e7c0019005c027d077d087c077c0814007d097c077c0117007d0a7c097c0a1b007d0b7c087c0b18007d067404640a1900740f74096a0b190014007d0c7c067c0c14007d0d7c0364016b08900172dc7c0d7404640b190014007d0d7c077c0814007d0e7c087c0d17007d0f7c0e7c0f1b007d107c077c1018007d117c117c117c0c140037007d11740e74046405190019005c027d127d137c127c1314007d147c127c1117007d157c157c117c0c140037007d157c147c151b007d167c137c1618007d177c177404640c190014007d187c056a087c1774096a0a74096a0b64078d03010074107404640519007c18640d8d027d197c056a0d7c177c1818007404640e190064098d020100740c7c007c1964088d027d1a7c0a740e7c001900640319007c07180037007d0a7c0b740e7c001900640f19007c08180037007d0b7c0b7c1a17007d0b6e767c067c0d18007d06740c74046405190074107c007c0d7c0d7404640c190014001800640d8d0264088d027d1b7c0a740e7c001900640319007c07180037007d0a7c0b740e7c001900640f19007c08180037007d0b7c0b7c0d7404640c1900140017007d0b7c056a0d7c1b7404640e190064098d0201007c0264006b03900272767c067c026b0590027376740164106a117c067c028302830182017c0664036b0490027388740164118301820174076a087c0174096a0a74096a0b64078d0301007c046a0d7c0674096a0b64098d0201007c0a7c0b6702740e7c003c007c0a7c0b1b0074127c003c007c06530029124e547a164d61726b657420646f6573206e6f742065786973742172010000007a1d4d7573742070726f766964652063757272656e637920616d6f756e742172180000007a18496e76616c696420746f6b656e20696e746572666163652129037203000000720400000072080000002902720b000000722800000029027203000000720400000072160000007219000000721a0000002902720b0000007229000000721c00000072120000007a554f6e6c79207b7d20746f6b656e732063616e206265207075726368617365642c207768696368206973206c657373207468616e20796f7572206d696e696d756d2c207768696368206973207b7d20746f6b656e732e7a14546f6b656e2072657365727665206572726f72212913722a000000722b000000722c000000722d0000007222000000722e000000722f00000072300000007207000000722300000072310000007224000000da0e5f5f696e7465726e616c5f62757972020000007234000000da0a5f5f646973636f756e74da0f5f5f696e7465726e616c5f73656c6c72450000007232000000291c720b0000007228000000724700000072480000007235000000da09616d6d5f746f6b656eda10746f6b656e735f707572636861736564723a000000723b000000da016b72400000007241000000da0b6665655f70657263656e74da03666565da06727377705f6bda16727377705f6e65775f746f6b656e5f72657365727665da19727377705f6e65775f63757272656e63795f72657365727665da17727377705f63757272656e63795f707572636861736564da17727377705f63757272656e63795f726573657276655f32da14727377705f746f6b656e5f726573657276655f32da08727377705f6b5f32da1b727377705f6e65775f63757272656e63795f726573657276655f32da18727377705f6e65775f746f6b656e5f726573657276655f32da0b73656c6c5f616d6f756e74da1473656c6c5f616d6f756e745f776974685f666565da1163757272656e63795f7265636569766564da0e746f6b656e5f7265636569766564da0b6275726e5f616d6f756e74722500000072250000007226000000da036275798500000073820000000003140110010a010e010e0106010c010a010a0108010801100104010c010801080108010801120108010a010c0108010801080108010c0104010c010801020106010c01080108010c010a010a0104010c010a010c0104010801140114010a02080108010401180114011401100212010a0110010a0112010a010a0110010c010c01725f0000002904720b000000722900000072470000007248000000630400000000000000180000000500000043000000733c02000074007c00190064016b08731474016402830182017c0164036b047324740164048301820174026a037c0083017d0474026a0374046405190083017d0574026a057c0474068302735074016406830182017c007404640519006b0272947c046a077c0174086a0974086a0a64078d030100740b7404640519007c0164088d027d06740c6a0d7c0674086a0a64098d0201007c065300740e7c0019005c027d077d087c077c0814007d097c087c0117007d0a7c097c0a1b007d0b7c077c0b18007d067404640a1900740f74086a0a190014007d0c7c067c0c14007d0d7c0364016b089001727c7c0d7404640b190014007d0d740e74046405190019005c027d0e7d0f7c0e7c0f14007d107c0e7c0d17007d117c117c0d7c0c140037007d117c107c111b007d127c0f7c1218007d137c137404640c190014007d147c056a077c1374086a0974086a0a64078d030100740b7404640519007c1464088d027d157c056a0d7c137c1418007404640d190064098d0201007c0b7c1517007d0b6e4a7c067c0d18007d067c0d7c0d7404640c1900140018007d167c0b7c0d7404640c1900140017007d0b74107404640519007c16640e8d027d177c056a0d7c177404640d190064098d0201007c0264006b03900172ea7c067c026b05900173ea7401640f6a117c067c028302830182017c0664036b04900173fc74016410830182017c046a077c0174086a0974086a0a64078d030100740c6a0d7c0674086a0a64098d0201007c0b7c0a6702740e7c003c007c0b7c0a1b0074127c003c007c06530029114e547a164d61726b657420646f6573206e6f742065786973742172010000007a2e4d7573742070726f766964652063757272656e637920616d6f756e7420616e6420746f6b656e20616d6f756e742172180000007a18496e76616c696420746f6b656e20696e746572666163652129037203000000720400000072080000002902720b000000722900000029027203000000720400000072160000007219000000721a000000721c0000002902720b00000072280000007a4f4f6e6c79207b7d205441552063616e206265207075726368617365642c207768696368206973206c657373207468616e20796f7572206d696e696d756d2c207768696368206973207b7d205441552e7a14546f6b656e2072657365727665206572726f72212913722a000000722b000000722c000000722d0000007222000000722e000000722f0000007207000000722300000072310000007224000000724b000000723000000072020000007234000000724a0000007249000000724500000072320000002918720b0000007229000000724700000072480000007235000000724c000000da1263757272656e63795f707572636861736564723a000000723b000000724e00000072410000007240000000724f0000007250000000da15727377705f63757272656e63795f72657365727665da12727377705f746f6b656e5f72657365727665725100000072530000007252000000725a000000725b000000725c000000725e000000725d000000722500000072250000007226000000da0473656c6ccd000000736a0000000003140110010a010e010e0106010c010a010a0104010c01100104010c010801080108010801120108010a010c0104010c01080108010c01080108010c010a010a0104010c010a010c010a020801100106010a010801080112010a0110010a011201140210010c010c01726300000029027203000000da0e746f6b656e5f636f6e7472616374630200000000000000050000000500000043000000736e0100007c0064016b05731074006402830182017c0164006b0272207401640319007d0174026a037c0183017d02740474056a067c01660219007d037c007c036b0072cc7c026a077c037c00180074056a06830201007c00740474056a067c0166023c00740164041900740474056a067401640319006602190064057401640419001b001300640518001400740164061900140074016407190018007d047c047408640883016b0472ae7408640883017d047c0464016b0072ba64017d0464057c041800740974056a063c007c0453007c007c036b049001726a7c026a0a7c007c03180074056a0b74056a06830301007c00740474056a067c0166023c00740164041900740474056a067401640319006602190064057401640419001b001300640518001400740164061900140074016407190018007d047c047408640883016b049001724a7408640883017d047c0464016b009001725864017d0464057c041800740974056a063c007c0453006400530029094e72010000007a204d757374206265206120706f736974697665207374616b6520616d6f756e74217218000000721d0000007212000000721e000000721f0000007a04302e3939290c722b0000007222000000722c000000722d000000da0f5f5f7374616b65645f616d6f756e747223000000722400000072020000007221000000724a00000072070000007231000000290572030000007264000000724c000000da0f63757272656e745f62616c616e6365da0f646973636f756e745f616d6f756e74722500000072250000007226000000da057374616b6509010000733600000000021001080108010a010e01080112010e03320108010c010801080104010e0104010a0116010e03320108010e0108010a0104010e0172680000002903da036b6579da096e65775f76616c7565da12636f6e766572745f746f5f646563696d616c630300000000000000030000000300000043000000732e00000074006401190074016a026b02731674036402830182017c02722274047c0183017d017c0174007c003c007c01530029034e72200000007a0e4e6f7420746865206f776e6572212905722200000072230000007224000000722b000000722100000029037269000000726a000000726b000000722500000072250000007226000000da0c6368616e67655f73746174652c010000730a00000000021601040108010801726c00000029037269000000726a000000da0e636f6e766572745f746f5f696e74630300000000000000030000000300000043000000732e00000074006401190074016a026b02731674036402830182017c02722274047c0183017d017c0174007c003c007c01530029034e72200000007a0e4e6f7420746865206f776e6572212905722200000072230000007224000000722b000000da03696e7429037269000000726a000000726d000000722500000072250000007226000000da126368616e67655f73746174655f666c6f617435010000730a00000000021601040108010801726f0000002901720b000000630100000000000000030000000300000043000000734a00000074006401190064026b087314740164038301820174026a037c0083017d017c016a0474056a0683017d027c0264046b04733a74016405830182017c0274077c00190064063c007c02530029074eda0c53594e435f454e41424c4544547a1453796e63206973206e6f7420656e61626c65642172010000007a1d43616e6e6f742062652061206e656761746976652062616c616e636521721200000029087222000000722b000000722c000000722d000000da0a62616c616e63655f6f667223000000723100000072340000002903720b0000007235000000da0b6e65775f62616c616e6365722500000072250000007226000000da0d73796e635f72657365727665733e010000730c000000000214010a010c0110010c0172730000006302000000000000000a000000030000004300000073b200000074007c00190064016b08731474016402830182017c0164036b0172206403530074026a037c0083017d0274026a047c0274058302733e740164048301820174067c0019005c027d037d047c037c0414007d057c037c0117007d067c057c061b007d077c047c0718007d087c0874076405190014007d097c087c0938007d087c077c0937007d077c0864036b04739674016406830182017c067c07670274067c003c007c067c071b0074087c003c007c08530029074e547a1b52535750204d61726b657420646f6573206e6f742065786973742172010000007a18496e76616c696420746f6b656e20696e746572666163652172160000007a14546f6b656e2072657365727665206572726f72212909722a000000722b000000722c000000722d000000722e000000722f000000723400000072220000007232000000290a720b00000072280000007235000000723a000000723b000000724e00000072400000007241000000724d0000007250000000722500000072250000007226000000724900000048010000732400000000011401080104010a010e0106010c0108010801080108010c010801080110010c010c0172490000002902720b00000072290000006302000000000000000a000000030000004300000073b200000074007c00190064016b08731474016402830182017c0164036b0172206403530074026a037c0083017d0274026a047c0274058302733e740164048301820174067c0019005c027d037d047c037c0414007d057c047c0117007d067c057c061b007d077c037c0718007d087c0874076405190014007d097c087c0938007d087c077c0937007d077c0864036b04739674016406830182017c077c06670274067c003c007c077c061b0074087c003c007c08530029074e547a1b52535750204d61726b657420646f6573206e6f742065786973742172010000007a18496e76616c696420746f6b656e20696e746572666163652172160000007a14546f6b656e2072657365727665206572726f72212909722a000000722b000000722c000000722d000000722e000000722f000000723400000072220000007232000000290a720b00000072290000007235000000723a000000723b000000724e0000007241000000724000000072600000007250000000722500000072250000007226000000724b0000005d010000732400000000011401080104010a010e0106010c0108010801080108010c010801080110010c010c01724b000000290272030000007204000000290272030000007204000000290372030000007204000000720800000029027201000000720100000029017201000000290172010000002902720100000046290272010000004629014e29014629014629217230000000da09696d706f72746c6962722c000000da0446756e63722f000000da0448617368722a0000007232000000723300000072340000007265000000724a00000072220000007227000000da085f5f6578706f7274da03737472da05666c6f617472360000007238000000723e0000007242000000724300000072440000007246000000da04626f6f6c725f00000072630000007268000000726c000000726f00000072730000007249000000724b0000007225000000722500000072250000007226000000da083c6d6f64756c653e01000000735e0000000801040110010e010a010c010e01060108010a010801060108010e020c03080c060100011612060112040601141606011418060114080601140506010601100c06010001184606010001183a060114220601160806011608060110091015