Contract con_gamma_phi_dao_v1
Creator | ae9cfa894495930b8d2f1707ab936325b5c848ace677bb8ba41dfe7dcdb3e3e6 |
Creation Hash | 876f74c6e7e0ef604fd7b34e167691376250471d89e8a58e79e2bd25480ff3c5 |
Created On | 797 days ago - 2/17/2022, 12:52:35 AM UTC+0 |
Contract Code
1
# con_gamma_phi_dao_v1
2
3
# Imports
4
I = importlib
5
6
7
# State
8
settings = Hash(default_value=None)
9
stakes = Hash(default_value=0)
10
total_staked = Variable()
11
12
13
# DAO
14
proposal_id = Variable()
15
finished_proposals = Hash()
16
sig = Hash(default_value=False)
17
proposal_details = Hash()
18
status = Hash()
19
20
21
# Constants
22
TOKEN_CONTRACT_STR = 'token'
23
OWNER_STR = 'owner'
24
MINIMUM_PROPOSAL_DURATION_STR = 'min_proposal_duration'
25
REQUIRED_APPROVAL_PERCENTAGE_STR = 'required_approval_percentage'
26
MINIMUM_QUORUM_STR = 'min_quorum'
27
STAKING_LOCKUP_DAYS_STR = 'stake_lockup'
28
29
30
# Actions
31
metadata = Hash(default_value=None)
32
contracts_list = Variable()
33
state = {
34
'stakes': stakes, # should this be read only?
35
'settings': settings, # should this be read only?
36
'metadata': metadata,
37
'total_staked': total_staked,
38
'TOKEN_CONTRACT_STR': TOKEN_CONTRACT_STR,
39
'OWNER_STR': OWNER_STR,
40
'MINIMUM_PROPOSAL_DURATION_STR': MINIMUM_PROPOSAL_DURATION_STR,
41
'REQUIRED_APPROVAL_PERCENTAGE_STR': REQUIRED_APPROVAL_PERCENTAGE_STR,
42
'MINIMUM_QUORUM_STR': MINIMUM_QUORUM_STR,
43
'STAKING_LOCKUP_DAYS_STR': STAKING_LOCKUP_DAYS_STR,
44
}
45
actions = Hash()
46
47
48
# Action interface
49
action_interface = [
50
I.Func('interact', args=('payload', 'state', 'caller')),
51
]
52
53
54
@construct
55
def init(token_contract: str = 'con_phi_lst001'):
56
settings[OWNER_STR] = ctx.caller
57
settings[TOKEN_CONTRACT_STR] = token_contract
58
59
settings[STAKING_LOCKUP_DAYS_STR] = 21
60
total_staked.set(0)
61
contracts_list.set([])
62
63
# DAO
64
proposal_id.set(0)
65
settings[MINIMUM_PROPOSAL_DURATION_STR] = 7 #Number is in days
66
settings[REQUIRED_APPROVAL_PERCENTAGE_STR] = 0.5 #Keep this at 50%, unless there are special circumstances
67
settings[MINIMUM_QUORUM_STR] = 0.1 #Set minimum amount of votes needed
68
69
70
def register_action(action: str, contract: str):
71
assert actions[action] is None, 'Action already registered!'
72
# Attempt to import the contract to make sure it is already submitted
73
p = I.import_module(contract)
74
75
# Assert ownership is election_house and interface is correct
76
assert I.owner_of(p) == ctx.this, \
77
'This contract must control the action contract!'
78
79
assert I.enforce_interface(p, action_interface), \
80
'Action contract does not follow the correct interface!'
81
82
contracts = contracts_list.get()
83
contracts.append(contract)
84
contracts_list.set(contracts)
85
actions[action] = contract
86
87
88
def override_action(action: str, contract: str):
89
original_contract = actions[action]
90
assert original_contract is not None, 'Action not already registered!'
91
# Attempt to import the contract to make sure it is already submitted
92
p = I.import_module(contract)
93
94
# Assert ownership is election_house and interface is correct
95
assert I.owner_of(p) == ctx.this, \
96
'This contract must control the action contract!'
97
98
assert I.enforce_interface(p, action_interface), \
99
'Action contract does not follow the correct interface!'
100
101
contracts = contracts_list.get()
102
if original_contract in contracts:
103
contracts.remove(original_contract)
104
contracts.append(contract)
105
contracts_list.set(contracts)
106
actions[action] = contract
107
108
109
def unregister_action(action: str):
110
contract = actions[action]
111
assert contract is not None, 'Action does not exist!'
112
113
contracts = contracts_list.get()
114
if contract in contracts:
115
contracts.remove(contract)
116
contracts_list.set(contracts)
117
actions[action] = None
118
119
120
@export
121
def force_register_action(action: str, contract: str):
122
assert ctx.caller == settings[OWNER_STR], 'Only the owner can directly call this method.'
123
register_action(action, contract)
124
125
126
@export
127
def force_override_action(action: str, contract: str):
128
assert ctx.caller == settings[OWNER_STR], 'Only the owner can directly call this method.'
129
override_action(action, contract)
130
131
132
@export
133
def force_unregister_action(action: str):
134
assert ctx.caller == settings[OWNER_STR], 'Only the owner can directly call this method.'
135
unregister_action(action)
136
137
138
139
# Do not export this one
140
def interact_internal(action: str, payload: dict, caller: str) -> Any:
141
contract = actions[action]
142
assert contract is not None, 'Invalid action!'
143
144
module = I.import_module(contract)
145
146
result = module.interact(payload, state, caller)
147
return result
148
149
150
@export # Safe to export
151
def interact(action: str, payload: dict) -> Any:
152
return interact_internal(action, payload, ctx.caller)
153
154
155
# Do not export this one
156
def bulk_interact_internal(action: str, payloads: list, caller: str):
157
for payload in payloads:
158
interact_internal(action, payload, caller)
159
160
161
@export # Safe to export
162
def bulk_interact(action: str, payloads: list):
163
bulk_interact_internal(action, payloads, ctx.caller)
164
165
166
@export
167
def force_change_setting(key: str, value: Any, to_float: bool = False):
168
assert ctx.caller == settings[OWNER_STR], 'Only the owner can directly change settings.'
169
if to_float:
170
value = decimal(value)
171
settings[key] = value
172
173
174
def transfer(token_contract: str, amount: float, to: str):
175
t_c = I.import_module(token_contract)
176
t_c.transfer(amount=amount, to=to)
177
178
179
def approve(token_contract: str, amount: float, to: str):
180
t_c = I.import_module(token_contract)
181
t_c.approve(amount=amount, to=to)
182
183
184
@export
185
def force_transfer(token_contract: str, amount: float, to: str):
186
assert ctx.caller == settings[OWNER_STR], 'Only the owner can call this method.'
187
transfer(token_contract, amount, to)
188
189
190
@export
191
def force_approve(token_contract: str, amount: float, to: str):
192
assert ctx.caller == settings[OWNER_STR], 'Only the owner can call this method.'
193
approve(token_contract, amount, to)
194
195
196
@export
197
def stake(amount: float):
198
assert amount >= 0, 'Must be non-negative.'
199
current_amount = stakes[ctx.caller] or 0
200
if current_amount > amount:
201
# unstake
202
assert (stakes[ctx.caller, 'time'] + datetime.timedelta(days=1) * (settings[STAKING_LOCKUP_DAYS_STR])) <= now, "Cannot unstake yet!"
203
amount_to_unstake = current_amount - amount
204
I.import_module(settings[TOKEN_CONTRACT_STR]).transfer(
205
to=ctx.caller,
206
amount=amount_to_unstake
207
)
208
total_staked.set(total_staked.get() - amount_to_unstake)
209
elif current_amount < amount:
210
# stake
211
amount_to_stake = amount - current_amount
212
I.import_module(settings[TOKEN_CONTRACT_STR]).transfer_from(
213
to=ctx.this,
214
amount=amount_to_stake,
215
main_account=ctx.caller
216
)
217
stakes[ctx.caller, 'time'] = now
218
total_staked.set(total_staked.get() + amount_to_stake)
219
stakes[ctx.caller] = amount
220
221
222
@export
223
def create_register_action_proposal(action: str, contract: str, voting_time_in_days: int, description: str):
224
assert voting_time_in_days >= settings[MINIMUM_PROPOSAL_DURATION_STR]
225
p_id = proposal_id.get()
226
proposal_id.set(p_id + 1)
227
proposal_details[p_id, "action"] = action
228
proposal_details[p_id, "contract"] = contract
229
proposal_details[p_id, "type"] = "register_action"
230
modify_proposal(p_id, description, voting_time_in_days)
231
return p_id
232
233
234
@export
235
def create_override_action_proposal(action: str, contract: str, voting_time_in_days: int, description: str):
236
assert voting_time_in_days >= settings[MINIMUM_PROPOSAL_DURATION_STR]
237
p_id = proposal_id.get()
238
proposal_id.set(p_id + 1)
239
proposal_details[p_id, "action"] = action
240
proposal_details[p_id, "contract"] = contract
241
proposal_details[p_id, "type"] = "override_action"
242
modify_proposal(p_id, description, voting_time_in_days)
243
return p_id
244
245
246
@export
247
def create_unregister_action_proposal(action: str, voting_time_in_days: int, description: str):
248
assert voting_time_in_days >= settings[MINIMUM_PROPOSAL_DURATION_STR]
249
p_id = proposal_id.get()
250
proposal_id.set(p_id + 1)
251
proposal_details[p_id, "action"] = action
252
proposal_details[p_id, "type"] = "unregister_action"
253
modify_proposal(p_id, description, voting_time_in_days)
254
return p_id
255
256
257
@export
258
def create_interact_proposal(action: str, payload: dict, voting_time_in_days: int, description: str, caller: str = None):
259
assert voting_time_in_days >= settings[MINIMUM_PROPOSAL_DURATION_STR]
260
p_id = proposal_id.get()
261
proposal_id.set(p_id + 1)
262
proposal_details[p_id, "action"] = action
263
proposal_details[p_id, "payload"] = payload
264
if caller is not None:
265
proposal_details[p_id, "caller"] = caller
266
proposal_details[p_id, "type"] = "interact"
267
modify_proposal(p_id, description, voting_time_in_days)
268
return p_id
269
270
271
@export
272
def create_bulk_interact_proposal(action: str, payloads: dict, voting_time_in_days: int, description: str, caller: str = None):
273
assert voting_time_in_days >= settings[MINIMUM_PROPOSAL_DURATION_STR]
274
p_id = proposal_id.get()
275
proposal_id.set(p_id + 1)
276
proposal_details[p_id, "action"] = action
277
proposal_details[p_id, "payloads"] = payloads
278
if caller is not None:
279
proposal_details[p_id, "caller"] = caller
280
proposal_details[p_id, "type"] = "bulk_interact"
281
modify_proposal(p_id, description, voting_time_in_days)
282
return p_id
283
284
285
@export
286
def create_change_setting_proposal(setting: str, value: Any, voting_time_in_days: int, description: str, to_float: bool = False):
287
assert voting_time_in_days >= settings[MINIMUM_PROPOSAL_DURATION_STR]
288
assert setting != OWNER_STR, 'Only the owner can change the owner setting.'
289
p_id = proposal_id.get()
290
proposal_id.set(p_id + 1)
291
if to_float:
292
value = decimal(value)
293
proposal_details[p_id, "setting"] = setting
294
proposal_details[p_id, "value"] = value
295
proposal_details[p_id, "type"] = "change_setting"
296
modify_proposal(p_id, description, voting_time_in_days)
297
return p_id
298
299
300
@export
301
def create_transfer_proposal(token_contract: str, amount: float, to: str, description: str, voting_time_in_days: int): #Transfer tokens held by the AMM treasury here
302
assert voting_time_in_days >= settings[MINIMUM_PROPOSAL_DURATION_STR]
303
p_id = proposal_id.get()
304
proposal_id.set(p_id + 1)
305
proposal_details[p_id, "token_contract"] = token_contract
306
proposal_details[p_id, "amount"] = amount
307
proposal_details[p_id, "receiver"] = to
308
proposal_details[p_id, "type"] = "transfer"
309
modify_proposal(p_id, description, voting_time_in_days)
310
return p_id
311
312
313
@export
314
def create_approval_proposal(token_contract: str, amount: float, to: str, description: str, voting_time_in_days: int): #Approve the transfer of tokens held by the AMM treasury here
315
assert voting_time_in_days >= settings[MINIMUM_PROPOSAL_DURATION_STR]
316
p_id = proposal_id.get()
317
proposal_id.set(p_id + 1)
318
proposal_details[p_id, "token_contract"] = token_contract
319
proposal_details[p_id, "amount"] = amount
320
proposal_details[p_id, "receiver"] = to
321
proposal_details[p_id, "type"] = "approval"
322
modify_proposal(p_id, description, voting_time_in_days)
323
return p_id
324
325
326
@export
327
def vote(p_id: int, result: bool): #Vote here
328
sig[p_id, ctx.caller] = result
329
voters = proposal_details[p_id, "voters"] or []
330
assert ctx.caller not in voters, 'You have already voted.'
331
voters.append(ctx.caller)
332
proposal_details[p_id, "voters"] = voters
333
334
335
@export
336
def determine_results(p_id: int) -> bool: #Vote resolution takes place here
337
assert (proposal_details[p_id, "time"] + datetime.timedelta(days=1) * (proposal_details[p_id, "duration"])) <= now, "Proposal not over!" #Checks if proposal has concluded
338
assert finished_proposals[p_id] is not True, "Proposal already resolved" #Checks that the proposal has not been resolved before (to prevent double spends)
339
assert p_id < proposal_id.get()
340
finished_proposals[p_id] = True #Adds the proposal to the list of resolved proposals
341
approvals = 0
342
total_votes = 0
343
for x in proposal_details[p_id, "voters"]:
344
stake = stakes[x] or 0
345
if sig[p_id, x] == True:
346
approvals += stake
347
total_votes += stake
348
quorum = total_staked.get()
349
if approvals < (quorum * settings[MINIMUM_QUORUM_STR]): #Checks that the minimum approval percentage has been reached (quorum)
350
status[p_id] = False
351
return False
352
if approvals / total_votes >= settings[REQUIRED_APPROVAL_PERCENTAGE_STR]: #Checks that the approval percentage of the votes has been reached (% of total votes)
353
if proposal_details[p_id, "type"] == "transfer":
354
transfer(
355
I.import_module(proposal_details[p_id, "token_contract"]),
356
amount=proposal_details[p_id, "amount"],
357
to=proposal_details[p_id, "receiver"],
358
)
359
elif proposal_details[p_id, "type"] == "approval":
360
approve(
361
I.import_module(proposal_details[p_id, "token_contract"]),
362
amount=proposal_details[p_id, "amount"],
363
to=proposal_details[p_id, "receiver"],
364
)
365
elif proposal_details[p_id, "type"] == "register_action":
366
register_action(
367
action=proposal_details[p_id, "action"],
368
contract=proposal_details[p_id, "contract"]
369
)
370
elif proposal_details[p_id, "type"] == "unregister_action":
371
unregister_action(
372
action=proposal_details[p_id, "action"],
373
)
374
elif proposal_details[p_id, "type"] == "override_action":
375
override_action(
376
action=proposal_details[p_id, "action"],
377
contract=proposal_details[p_id, "contract"]
378
)
379
elif proposal_details[p_id, "type"] == "interact":
380
interact_internal(
381
action=proposal_details[p_id, "action"],
382
payload=proposal_details[p_id, "payload"],
383
caller=proposal_details[p_id, "caller"] or ctx.this,
384
)
385
elif proposal_details[p_id, "type"] == "bulk_interact":
386
bulk_interact_internal(
387
action=proposal_details[p_id, "action"],
388
payloads=proposal_details[p_id, "payloads"],
389
caller=proposal_details[p_id, "caller"] or ctx.this,
390
)
391
elif proposal_details[p_id, "type"] == "change_setting":
392
# allowlist settings?
393
settings[proposal_details[p_id, "setting"]] = proposal_details[p_id, "value"]
394
status[p_id] = True
395
return True
396
else:
397
status[p_id] = False
398
return False
399
400
401
@export
402
def proposal_information(p_id: int): #Get proposal information, provided as a dictionary
403
info = {
404
"setting": proposal_details[p_id, "setting"],
405
"value": proposal_details[p_id, "value"],
406
"token_contract": proposal_details[p_id, "token_contract"],
407
"proposal_creator": proposal_details[p_id, "proposal_creator"],
408
"description": proposal_details[p_id, "description"],
409
"time": proposal_details[p_id, "time"],
410
"type": proposal_details[p_id, "type"],
411
"duration": proposal_details[p_id, "duration"],
412
"receiver": proposal_details[p_id, "receiver"]
413
}
414
return info
415
416
417
def modify_proposal(p_id: int, description: str, voting_time_in_days: int):
418
proposal_details[p_id, "proposal_creator"] = ctx.caller
419
proposal_details[p_id, "description"] = description
420
proposal_details[p_id, "time"] = now
421
proposal_details[p_id, "duration"] = voting_time_in_days
422
423
Byte Code
e30000000000000000000000000b00000040000000738203000065005a01650264006401640264038d035a03650264046401640564038d035a0465056401640664078d025a0665056401640864078d025a0765026401640964078d025a086502640a6401640b64038d035a0965026401640c64078d025a0a65026401640d64078d025a0b640e5a0c640f5a0d64105a0e64115a0f64125a1064135a11650264006401641464038d035a1265056401641564078d025a136504650365126506650c650d650e650f6510651164169c0a5a1465026401641764078d025a1565016a166418646b641c8d0267015a17646c6518641e9c01641f642084055a196518651864219c026422642384045a1a6518651864219c026424642584045a1b651864269c016427642884045a1c651d640183016518651864219c026429642a840483015a1e651d640183016518651864219c02642b642c840483015a1f651d64018301651864269c01642d642e840483015a206518652165186522642f9c046430643184045a23651d6401830165186521652264329c0364336418840483015a2465186525651864349c036435643684045a26651d640183016518652564379c0264386439840483015a27651d64018301646d651865226528643a9c03643b643c840583015a296518652a6518643d9c03643e643f84045a2b6518652a6518643d9c036440644184045a2c651d640183016518652a6518643d9c0364426443840483015a2d651d640183016518652a6518643d9c0364446445840483015a2e651d64018301652a64469c0164476448840483015a2f651d64018301651865186530651864499c04644a644b840483015a31651d64018301651865186530651864499c04644c644d840483015a32651d64018301651865306518644e9c03644f6450840483015a33651d64018301646e6518652165306518651864519c0564526453840583015a34651d64018301646f6518652165306518651864549c0564556456840583015a35651d6401830164706518652265306518652864579c0564586459840583015a36651d640183016518652a651865186530645a9c05645b645c840483015a37651d640183016518652a651865186530645a9c05645d645e840483015a38651d6401830165306528645f9c0264606461840483015a39651d640183016530652864629c0264636464840483015a3a651d64018301653064659c0164666467840483015a3b65306518653064689c036469646a84045a3c6400530029714eda14636f6e5f67616d6d615f7068695f64616f5f7631da0873657474696e67732903da0d64656661756c745f76616c7565da08636f6e7472616374da046e616d65e900000000da067374616b6573da0c746f74616c5f7374616b6564290272040000007205000000da0b70726f706f73616c5f6964da1266696e69736865645f70726f706f73616c7346da03736967da1070726f706f73616c5f64657461696c73da06737461747573da05746f6b656eda056f776e6572da156d696e5f70726f706f73616c5f6475726174696f6eda1c72657175697265645f617070726f76616c5f70657263656e74616765da0a6d696e5f71756f72756dda0c7374616b655f6c6f636b7570da086d65746164617461da0e636f6e7472616374735f6c697374290a7207000000720200000072140000007208000000da12544f4b454e5f434f4e54524143545f535452da094f574e45525f535452da1d4d494e494d554d5f50524f504f53414c5f4455524154494f4e5f535452da2052455155495245445f415050524f56414c5f50455243454e544147455f535452da124d494e494d554d5f51554f52554d5f535452da175354414b494e475f4c4f434b55505f444159535f535452da07616374696f6e73da08696e746572616374da077061796c6f6164da057374617465da0663616c6c65722901da0461726773da0e636f6e5f7068695f6c73743030312901da0e746f6b656e5f636f6e7472616374630100000000000000010000000300000043000000735c00000074006a01740274033c007c00740274043c006401740274053c0074066a0764028301010074086a0767008301010074096a0764028301010064037402740a3c00740b640483017402740c3c00740b640583017402740d3c006400530029064ee9150000007206000000e9070000007a03302e357a03302e31290eda036374787220000000da0a5f5f73657474696e677372170000007216000000721b000000da0e5f5f746f74616c5f7374616b6564da03736574da105f5f636f6e7472616374735f6c697374da0d5f5f70726f706f73616c5f69647218000000da07646563696d616c7219000000721a00000029017223000000a900722d000000da00da045f5f5f5f23000000731200000000010a01080108010a010a010a0108010c01722f0000002902da06616374696f6e7204000000630200000000000000040000000300000043000000737200000074007c00190064006b087314740164018301820174026a037c0183017d0274026a047c02830174056a066b027336740164028301820174026a077c0274088302734a740164038301820174096a0a83007d037c036a0b7c018301010074096a0c7c03830101007c0174007c003c006400530029044e7a1a416374696f6e20616c72656164792072656769737465726564217a2f5468697320636f6e7472616374206d75737420636f6e74726f6c2074686520616374696f6e20636f6e7472616374217a36416374696f6e20636f6e747261637420646f6573206e6f7420666f6c6c6f772074686520636f727265637420696e7465726661636521290dda095f5f616374696f6e73da0e417373657274696f6e4572726f72da0149da0d696d706f72745f6d6f64756c65da086f776e65725f6f667226000000da0474686973da11656e666f7263655f696e74657266616365da10616374696f6e5f696e74657266616365722a000000da03676574da06617070656e647229000000290472300000007204000000da0170da09636f6e747261637473722d000000722d000000722e000000da115f5f72656769737465725f616374696f6e2f0000007314000000000114010a01080110010e01060108010a010a01723d000000630200000000000000050000000300000043000000738800000074007c0019007d027c0264006b097318740164018301820174026a037c0183017d0374026a047c03830174056a066b02733a740164028301820174026a077c0374088302734e740164038301820174096a0a83007d047c027c046b0672687c046a0b7c02830101007c046a0c7c018301010074096a0d7c04830101007c0174007c003c006400530029044e7a1e416374696f6e206e6f7420616c72656164792072656769737465726564217a2f5468697320636f6e7472616374206d75737420636f6e74726f6c2074686520616374696f6e20636f6e7472616374217a36416374696f6e20636f6e747261637420646f6573206e6f7420666f6c6c6f772074686520636f727265637420696e7465726661636521290e723100000072320000007233000000723400000072350000007226000000723600000072370000007238000000722a0000007239000000da0672656d6f7665723a0000007229000000290572300000007204000000da116f726967696e616c5f636f6e7472616374723b000000723c000000722d000000722d000000722e000000da115f5f6f766572726964655f616374696f6e3c000000731a0000000001080110010a01080110010e010601080108010a010a010a01724000000029017230000000630100000000000000030000000300000043000000734800000074007c0019007d017c0164006b097318740164018301820174026a0383007d027c017c026b0672327c026a047c018301010074026a057c0283010100640074007c003c006400530029024e7a16416374696f6e20646f6573206e6f7420657869737421290672310000007232000000722a0000007239000000723e0000007229000000290372300000007204000000723c000000722d000000722d000000722e000000da135f5f756e72656769737465725f616374696f6e4c000000730e000000000108011001080108010a010a017241000000630200000000000000020000000300000043000000732400000074006a017402740319006b027316740464018301820174057c007c01830201006400530029024e7a2d4f6e6c7920746865206f776e65722063616e206469726563746c792063616c6c2074686973206d6574686f642e290672260000007220000000722700000072170000007232000000723d000000290272300000007204000000722d000000722d000000722e000000da15666f7263655f72656769737465725f616374696f6e5600000073060000000002100106017242000000630200000000000000020000000300000043000000732400000074006a017402740319006b027316740464018301820174057c007c01830201006400530029024e7a2d4f6e6c7920746865206f776e65722063616e206469726563746c792063616c6c2074686973206d6574686f642e2906722600000072200000007227000000721700000072320000007240000000290272300000007204000000722d000000722d000000722e000000da15666f7263655f6f766572726964655f616374696f6e5d00000073060000000002100106017243000000630100000000000000010000000300000043000000732200000074006a017402740319006b027316740464018301820174057c00830101006400530029024e7a2d4f6e6c7920746865206f776e65722063616e206469726563746c792063616c6c2074686973206d6574686f642e290672260000007220000000722700000072170000007232000000724100000029017230000000722d000000722d000000722e000000da17666f7263655f756e72656769737465725f616374696f6e640000007306000000000210010601724400000029047230000000721e0000007220000000da0672657475726e630300000000000000060000000400000043000000733400000074007c0019007d037c0364006b097318740164018301820174026a037c0383017d047c046a047c0174057c0283037d057c05530029024e7a0f496e76616c696420616374696f6e2129067231000000723200000072330000007234000000721d000000721f00000029067230000000721e00000072200000007204000000da066d6f64756c65da06726573756c74722d000000722d000000722e000000da135f5f696e7465726163745f696e7465726e616c6b000000730a0000000001080110010a010e01724800000029037230000000721e0000007245000000630200000000000000020000000400000043000000730e00000074007c007c0174016a028303530029014e290372480000007226000000722000000029027230000000721e000000722d000000722d000000722e000000721d000000730000007302000000000229037230000000da087061796c6f6164737220000000630300000000000000040000000500000043000000731e00000078187c0144005d107d0374007c007c037c0283030100710657006400530029014e290172480000002904723000000072490000007220000000721e000000722d000000722d000000722e000000da185f5f62756c6b5f696e7465726163745f696e7465726e616c78000000730400000000010a01724a000000290272300000007249000000630200000000000000020000000400000043000000731200000074007c007c0174016a02830301006400530029014e2903724a00000072260000007220000000290272300000007249000000722d000000722d000000722e000000da0d62756c6b5f696e7465726163747d00000073020000000002724b0000002903da036b6579da0576616c7565da08746f5f666c6f6174630300000000000000030000000300000043000000732e00000074006a017402740319006b02731674046401830182017c02722274057c0183017d017c0174027c003c006400530029024e7a2c4f6e6c7920746865206f776e65722063616e206469726563746c79206368616e67652073657474696e67732e290672260000007220000000722700000072170000007232000000722c0000002903724c000000724d000000724e000000722d000000722d000000722e000000da14666f7263655f6368616e67655f73657474696e6782000000730a00000000021001060104010801724f00000029037223000000da06616d6f756e74da02746f630300000000000000040000000400000043000000731c00000074006a017c0083017d037c036a027c017c0264018d0201006400530029024e290272500000007251000000290372330000007234000000da087472616e736665722904722300000072500000007251000000da03745f63722d000000722d000000722e000000da0a5f5f7472616e736665728b000000730400000000010a017254000000630300000000000000040000000400000043000000731c00000074006a017c0083017d037c036a027c017c0264018d0201006400530029024e290272500000007251000000290372330000007234000000da07617070726f766529047223000000725000000072510000007253000000722d000000722d000000722e000000da095f5f617070726f766590000000730400000000010a017256000000630300000000000000030000000400000043000000732600000074006a017402740319006b027316740464018301820174057c007c017c02830301006400530029024e7a244f6e6c7920746865206f776e65722063616e2063616c6c2074686973206d6574686f642e29067226000000722000000072270000007217000000723200000072540000002903722300000072500000007251000000722d000000722d000000722e000000da0e666f7263655f7472616e736665729500000073060000000002100106017257000000630300000000000000030000000400000043000000732600000074006a017402740319006b027316740464018301820174057c007c017c02830301006400530029024e7a244f6e6c7920746865206f776e65722063616e2063616c6c2074686973206d6574686f642e29067226000000722000000072270000007217000000723200000072560000002903722300000072500000007251000000722d000000722d000000722e000000da0d666f7263655f617070726f76659c000000730600000000021001060172580000002901725000000063010000000000000004000000050000004300000073e60000007c0064016b0573107400640283018201740174026a031900701c64017d017c017c006b04728a740174026a0364036602190074046a05640464058d017406740719001400170074086b01735474006406830182017c017c0018007d0274096a0a7406740b190083016a0c74026a037c0264078d020100740d6a0e740d6a0f83007c021800830101006e4e7c017c006b0072d87c007c0118007d0374096a0a7406740b190083016a1074026a117c0374026a0364088d0301007408740174026a03640366023c00740d6a0e740d6a0f83007c031700830101007c00740174026a033c006400530029094e72060000007a154d757374206265206e6f6e2d6e656761746976652eda0474696d65e9010000002901da04646179737a1343616e6e6f7420756e7374616b652079657421290272510000007250000000290372510000007250000000da0c6d61696e5f6163636f756e7429127232000000da085f5f7374616b657372260000007220000000da086461746574696d65da0974696d6564656c74617227000000721b000000da036e6f777233000000723400000072160000007252000000722800000072290000007239000000da0d7472616e736665725f66726f6d723600000029047250000000da0e63757272656e745f616d6f756e74da11616d6f756e745f746f5f756e7374616b65da0f616d6f756e745f746f5f7374616b65722d000000722d000000722e000000da057374616b65a30000007322000000000210010e01080116010a010e010801120108011401080108010e0110010e0112017265000000290472300000007204000000da13766f74696e675f74696d655f696e5f64617973da0b6465736372697074696f6e630400000000000000050000000400000043000000735a0000007c027400740119006b0573107402820174036a0483007d0474036a057c0464011700830101007c0074067c04640266023c007c0174067c04640366023c00640474067c04640566023c0074077c047c037c02830301007c04530029064e725a00000072300000007204000000da0f72656769737465725f616374696f6eda04747970652908722700000072180000007232000000722b00000072390000007229000000da125f5f70726f706f73616c5f64657461696c73da115f5f6d6f646966795f70726f706f73616c29057230000000720400000072660000007267000000da04705f6964722d000000722d000000722e000000da1f6372656174655f72656769737465725f616374696f6e5f70726f706f73616cb800000073100000000003100108010e010c010c010c010c01726d000000630400000000000000050000000400000043000000735a0000007c027400740119006b0573107402820174036a0483007d0474036a057c0464011700830101007c0074067c04640266023c007c0174067c04640366023c00640474067c04640566023c0074077c047c037c02830301007c04530029064e725a00000072300000007204000000da0f6f766572726964655f616374696f6e72690000002908722700000072180000007232000000722b00000072390000007229000000726a000000726b00000029057230000000720400000072660000007267000000726c000000722d000000722d000000722e000000da1f6372656174655f6f766572726964655f616374696f6e5f70726f706f73616cc500000073100000000003100108010e010c010c010c010c01726f0000002903723000000072660000007267000000630300000000000000040000000400000043000000734e0000007c017400740119006b0573107402820174036a0483007d0374036a057c0364011700830101007c0074067c03640266023c00640374067c03640466023c0074077c037c027c01830301007c03530029054e725a0000007230000000da11756e72656769737465725f616374696f6e72690000002908722700000072180000007232000000722b00000072390000007229000000726a000000726b0000002904723000000072660000007267000000726c000000722d000000722d000000722e000000da216372656174655f756e72656769737465725f616374696f6e5f70726f706f73616cd2000000730e0000000003100108010e010c010c010c01727100000029057230000000721e000000726600000072670000007220000000630500000000000000060000000400000043000000736e0000007c027400740119006b0573107402820174036a0483007d0574036a057c0564011700830101007c0074067c05640266023c007c0174067c05640366023c007c0464006b0972527c0474067c05640466023c00640574067c05640666023c0074077c057c037c02830301007c05530029074e725a0000007230000000721e0000007220000000721d00000072690000002908722700000072180000007232000000722b00000072390000007229000000726a000000726b00000029067230000000721e000000726600000072670000007220000000726c000000722d000000722d000000722e000000da186372656174655f696e7465726163745f70726f706f73616cde00000073140000000003100108010e010c010c0108010c010c010c017272000000290572300000007249000000726600000072670000007220000000630500000000000000060000000400000043000000736e0000007c027400740119006b0573107402820174036a0483007d0574036a057c0564011700830101007c0074067c05640266023c007c0174067c05640366023c007c0464006b0972527c0474067c05640466023c00640574067c05640666023c0074077c057c037c02830301007c05530029074e725a000000723000000072490000007220000000724b00000072690000002908722700000072180000007232000000722b00000072390000007229000000726a000000726b000000290672300000007249000000726600000072670000007220000000726c000000722d000000722d000000722e000000da1d6372656174655f62756c6b5f696e7465726163745f70726f706f73616ced00000073140000000003100108010e010c010c0108010c010c010c0172730000002905da0773657474696e67724d00000072660000007267000000724e00000063050000000000000006000000040000004300000073760000007c027400740119006b057310740282017c0074036b037320740264018301820174046a0583007d0574046a067c0564021700830101007c04724274077c0183017d017c0074087c05640366023c007c0174087c05640466023c00640574087c05640666023c0074097c057c037c02830301007c05530029074e7a2c4f6e6c7920746865206f776e65722063616e206368616e676520746865206f776e65722073657474696e672e725a0000007274000000724d000000da0e6368616e67655f73657474696e677269000000290a7227000000721800000072320000007217000000722b00000072390000007229000000722c000000726a000000726b00000029067274000000724d00000072660000007267000000724e000000726c000000722d000000722d000000722e000000da1e6372656174655f6368616e67655f73657474696e675f70726f706f73616cfc000000731600000000031001100108010e01040108010c010c010c010c01727600000029057223000000725000000072510000007267000000726600000063050000000000000006000000040000004300000073660000007c047400740119006b0573107402820174036a0483007d0574036a057c0564011700830101007c0074067c05640266023c007c0174067c05640366023c007c0274067c05640466023c00640574067c05640666023c0074077c057c037c04830301007c05530029074e725a00000072230000007250000000da087265636569766572725200000072690000002908722700000072180000007232000000722b00000072390000007229000000726a000000726b000000290672230000007250000000725100000072670000007266000000726c000000722d000000722d000000722e000000da186372656174655f7472616e736665725f70726f706f73616c0c01000073120000000003100108010e010c010c010c010c010c01727800000063050000000000000006000000040000004300000073660000007c047400740119006b0573107402820174036a0483007d0574036a057c0564011700830101007c0074067c05640266023c007c0174067c05640366023c007c0274067c05640466023c00640574067c05640666023c0074077c057c037c04830301007c05530029074e725a000000722300000072500000007277000000da08617070726f76616c72690000002908722700000072180000007232000000722b00000072390000007229000000726a000000726b000000290672230000007250000000725100000072670000007266000000726c000000722d000000722d000000722e000000da186372656174655f617070726f76616c5f70726f706f73616c1a01000073120000000003100108010e010c010c010c010c010c01727a0000002902726c0000007247000000630200000000000000030000000400000043000000734c0000007c0174007c0074016a0266023c0074037c00640166021900701c67007d0274016a027c026b07733074046402830182017c026a0574016a02830101007c0274037c00640166023c006400530029034eda06766f746572737a17596f75206861766520616c726561647920766f7465642e2906da055f5f73696772260000007220000000726a0000007232000000723a0000002903726c0000007247000000727b000000722d000000722d000000722e000000da04766f746528010000730a00000000020e01100112010c01727d0000002902726c000000724500000063010000000000000006000000060000004300000073b202000074007c0064016602190074016a02640264038d0174007c006404660219001400170074036b017330740464058301820174057c00190064066b09734474046407830182017c0074066a0783006b00735474048201640674057c003c0064087d0164087d02784074007c0064096602190044005d307d0374087c031900708064087d0474097c007c036602190064066b02729a7c017c0437007d017c027c0437007d0271725700740a6a0783007d057c017c05740b740c190014006b0072ca640a740d7c003c00640a53007c017c021b00740b740e19006b05900272a274007c00640b66021900640c6b029001721e740f74106a1174007c00640d66021900830174007c00640e6602190074007c00640f6602190064108d03010090016e7874007c00640b6602190064116b0290017260741274106a1174007c00640d66021900830174007c00640e6602190074007c00640f6602190064108d03010090016e3674007c00640b6602190064126b0290017292741374007c0064136602190074007c0064146602190064158d02010090016e0474007c00640b6602190064166b02900172b8741474007c0064136602190064178d0101006ede74007c00640b6602190064186b02900172e8741574007c0064136602190074007c0064146602190064158d0201006eae74007c00640b6602190064196b029002722a741674007c0064136602190074007c00641a6602190074007c00641b660219009002702274176a18641c8d0301006e6c74007c00640b66021900641d6b029002726c741974007c0064136602190074007c00641e6602190074007c00641b660219009002706474176a18641f8d0301006e2a74007c00640b6602190064206b029002729674007c00642166021900740b74007c006422660219003c006406740d7c003c0064065300640a740d7c003c00640a53006400530029234e7259000000725a0000002901725b000000da086475726174696f6e7a1250726f706f73616c206e6f74206f76657221547a1950726f706f73616c20616c7265616479207265736f6c7665647206000000727b00000046726900000072520000007223000000725000000072770000002902725000000072510000007279000000726800000072300000007204000000290272300000007204000000727000000029017230000000726e000000721d000000721e000000722000000029037230000000721e0000007220000000724b000000724900000029037230000000724900000072200000007275000000724d0000007274000000291a726a000000725e000000725f00000072600000007232000000da145f5f66696e69736865645f70726f706f73616c73722b0000007239000000725d000000727c00000072280000007227000000721a000000da085f5f73746174757372190000007254000000723300000072340000007256000000723d00000072410000007240000000724800000072260000007236000000724a0000002906726c000000da09617070726f76616c73da0b746f74616c5f766f746573da01787265000000da0671756f72756d722d000000722d000000722e000000da1164657465726d696e655f726573756c747331010000735e000000000214011c011401100108010401040112010c01100108010c010801100108010401120112010a010c011a0112010a010c011a0112010c0114011201140112010c01120112010c010a011a011201060110011a011202180108010402080172850000002901726c000000630100000000000000020000000b00000043000000736400000074007c0064016602190074007c0064026602190074007c0064036602190074007c0064046602190074007c0064056602190074007c0064066602190074007c0064076602190074007c0064086602190074007c00640966021900640a9c097d017c015300290b4e7274000000724d0000007223000000da1070726f706f73616c5f63726561746f72726700000072590000007269000000727e000000727700000029097274000000724d00000072230000007286000000726700000072590000007269000000727e00000072770000002901726a0000002902726c000000da04696e666f722d000000722d000000722e000000da1470726f706f73616c5f696e666f726d6174696f6e66010000731200000000020a010a010a010a010c0112010a01100172880000002903726c00000072670000007266000000630300000000000000030000000400000043000000733600000074006a0174027c00640166023c007c0174027c00640266023c00740374027c00640366023c007c0274027c00640466023c006400530029054e728600000072670000007259000000727e000000290472260000007220000000726a00000072600000002903726c00000072670000007266000000722d000000722d000000722e000000726b00000073010000730800000000010e010c010c01726b0000002903721e000000721f00000072200000002901722200000029014629014e29014e290146293dda09696d706f72746c69627233000000da04486173687227000000725d000000da085661726961626c657228000000722b000000727f000000727c000000726a00000072800000007216000000721700000072180000007219000000721a000000721b000000da0a5f5f6d65746164617461722a000000721f0000007231000000da0446756e637238000000da03737472722f000000723d00000072400000007241000000da085f5f6578706f7274724200000072430000007244000000da0464696374da03416e797248000000721d000000da046c697374724a000000724b000000da04626f6f6c724f000000da05666c6f617472540000007256000000725700000072580000007265000000da03696e74726d000000726f00000072710000007272000000727300000072760000007278000000727a000000727d00000072850000007288000000726b000000722d000000722d000000722d000000722e000000da083c6d6f64756c653e0100000073a80000000401060108010e020c010c01040108010e01040108010c01040104010401040104010401060108010401080106010201040102010201020108010c011003100c100d10100e0a060112060601120606011006140806011404120506011204060116081205120506011406060114060601101406010401120b06010401120b06010401100a06021a0d06021a0d06021a0e06010601120c06010601120c06011208060112340601100c