Contract con_nft_marketplace_v9


Contract Code


  
1 I = importlib
2 allowed_currency = Variable()
3 operator = Variable()
4 market = Hash(default_value=0)
5 auctions = Hash(default_value=0)
6 treasury = Variable()
7 royalty_receivers = Hash(default_value=False)
8 old_market_version = ForeignHash(foreign_contract="con_nft_marketplace_v4", foreign_name="market")
9
10 forced_collection_interface = [I.Func('transfer', args=('name', 'amount', 'to')), I.Func(
11 'approve', args=('amount', 'name', 'to')), I.Func('transfer_from', args=(
12 'name', 'amount', 'to', 'main_account'))]
13
14
15 @construct
16 def seed():
17 allowed_currency.set("currency")
18 operator.set("ff61544ea94eaaeb5df08ed863c4a938e9129aba6ceee5f31b6681bdede11b89")
19 treasury.set("ff61544ea94eaaeb5df08ed863c4a938e9129aba6ceee5f31b6681bdede11b89")
20
21
22 @export
23 def sell_nft(name_of_nft: str, collection_contract: str, amount: int, currency_price: float, royalty_percentage: float):
24 assert name_of_nft != "", "Name cannot be empty"
25 assert collection_contract != "", "Collection contract cannot be empty"
26 assert amount > 0, 'Cannot sell negative NFT amount'
27 assert currency_price > 0, 'Cannot sell for negative balances!'
28 collection = I.import_module(collection_contract)
29 assert I.enforce_interface(collection, forced_collection_interface
30 ), 'Invalid collection interface!'
31 collection.transfer_from(name=name_of_nft, amount=amount, to=ctx.this, main_account=ctx.caller)
32
33 listing_unique_id = block_num # block_num is a global enviroment variable that is the current block number
34 for i in range(amount):
35 market[ctx.caller, collection_contract, name_of_nft, listing_unique_id + i] = {"amount": 1, "price": currency_price}
36
37 if royalty_receivers[collection_contract, name_of_nft] == False:
38 if(royalty_percentage == None):
39 royalty_percentage = 0.0
40 assert royalty_percentage <= 50, "Over 50% royalty is not allowed"
41 assert royalty_percentage >= 0, "Under 0% royalty is not allowed"
42 royalty_receivers[collection_contract, name_of_nft] = {"receiver": ctx.caller, "royalty_percentage": royalty_percentage}
43
44 return f"Successfully listed {amount} {name_of_nft} for {currency_price}"
45
46
47 @export
48 def refund_nft(name_of_nft: str, collection_contract: str, listing_id: int, version:int=5):
49 if(version == 4):
50 old_marketplace = I.import_module("con_nft_marketplace_v4")
51 old_marketplace.refund_nft(name_of_nft=name_of_nft, collection_contract=collection_contract)
52 return f"Successfully refunded {name_of_nft}"
53
54 assert name_of_nft != "", "Name cannot be empty"
55 assert collection_contract != "", "Collection contract cannot be empty"
56 assert listing_id != "", "Listing ID cannot be empty"
57 market_entry = market[ctx.caller, collection_contract, name_of_nft, listing_id]
58 collection = I.import_module(collection_contract)
59 collection.transfer(name=name_of_nft, amount=market_entry["amount"], to=ctx.caller)
60 market[ctx.caller, collection_contract, name_of_nft, listing_id] = {"amount":0, "price":market_entry["price"]}
61
62 return f"Successfully refunded {name_of_nft}"
63
64
65 @export
66 def buy_nft(name: str, collection_contract: str, seller: str, listing_id:int, version:int=5):
67 if(version == 4):
68 old_marketplace = I.import_module("con_nft_marketplace_v4")
69 old_marketplace.refund_nft(name=name, collection_contract=collection_contract, seller=seller, amount=1)
70 return f"Successfully bought {name}"
71
72 assert name != "", "Name cannot be empty"
73 assert collection_contract != "", "Collection contract cannot be empty"
74 assert seller != "", "Seller cannot be empty"
75 assert listing_id != "", "Listing ID cannot be empty"
76 collection = I.import_module(collection_contract)
77 currency = I.import_module(allowed_currency.get())
78 assert I.enforce_interface(collection, forced_collection_interface
79 ), 'Invalid collection interface!'
80 fee = ((market[seller, collection_contract, name, listing_id]["price"])/100*2)
81 royalty = ((market[seller, collection_contract, name, listing_id]["price"])/100*royalty_receivers[collection_contract, name]["royalty_percentage"])
82 currency.transfer_from(amount=(market[seller, collection_contract, name, listing_id]["price"]) - fee - royalty, to=seller, main_account=ctx.caller)
83 currency.transfer_from(amount=fee, to=treasury.get(), main_account=ctx.caller)
84
85 if royalty > 0:
86 currency.transfer_from(amount=royalty, to=royalty_receivers[collection_contract, name]["receiver"], main_account=ctx.caller)
87
88 old_market_entry = market[seller, collection_contract, name, listing_id]
89 market[seller, collection_contract, name, listing_id] = {"amount": 0, "price": old_market_entry["price"]}
90 collection.transfer(name=name, amount=1, to=ctx.caller)
91
92 return f"Successfully bought {name}"
93
94 @export
95 def setup_auction(name_of_nft: str, collection_contract: str, start_currency_price: float, future_royalty_percentage: float, auction_start: datetime.datetime, auction_end: datetime.datetime):
96 assert name_of_nft != "", "Name cannot be empty"
97 assert collection_contract != "", "Collection contract cannot be empty"
98 assert start_currency_price > 0, 'Cannot auction for negative balances!'
99 assert future_royalty_percentage <= 50, "Over 50% royalty is not allowed"
100 assert future_royalty_percentage >= 0, "Under 0% royalty is not allowed"
101 assert auction_start > now, 'Auction cannot start in the past!'
102 assert auction_end > auction_start, 'Auction cannot end before it starts!'
103 assert auction_end < auction_start + datetime.timedelta(days=30), 'Auction cannot last longer than 30 days!'
104 assert auction_start < auction_end - datetime.timedelta(days=1), 'Auction cannot start and end on the same day!'
105
106 collection = I.import_module(collection_contract)
107 assert I.enforce_interface(collection, forced_collection_interface
108 ), 'Invalid collection interface!'
109 collection.transfer_from(name=name_of_nft, amount=1, to=ctx.this, main_account=ctx.caller)
110
111 listing_unique_id = block_num # block_num is a global enviroment variable that is the current block number
112 auctions[ctx.caller, collection_contract, name_of_nft, listing_unique_id] = {"current_bid": start_currency_price, "current_highest_bidder": None, "future_royalty_percentage": future_royalty_percentage, "auction_start": auction_start, "auction_end": auction_end}
113
114 @export
115 def bid_auction(seller: str, name_of_nft: str, collection_contract: str, auction_id: int, bid: float):
116 assert name_of_nft != "", "Name cannot be empty"
117 assert collection_contract != "", "Collection contract cannot be empty"
118 assert seller != "", "Seller cannot be empty"
119 assert auction_id != "", "Auction ID cannot be empty"
120 assert bid > 0, "Bid must be higher than 0"
121
122 auction = auctions[seller, collection_contract, name_of_nft, auction_id]
123 assert now > auction["auction_start"], "Auction has not started yet"
124 assert now < auction["auction_end"], "Auction has ended"
125
126 highest_bid = auction["current_bid"]
127 highest_bidder = auction["current_highest_bidder"]
128 assert bid > highest_bid, "Bid must be higher than the current highest bid"
129 assert highest_bidder != ctx.caller, "You are already the highest bidder"
130
131 currency.transfer_from(amount=bid, to=ctx.this, main_account=ctx.caller)
132 auction['current_bid'] = bid
133 auction['current_highest_bidder'] = ctx.caller
134 auctions[seller, collection_contract, name_of_nft, auction_id] = auction
135
136 return f"Successfully bid {bid} on {name_of_nft}"
137
138 @export
139 def cancel_auction(seller: str, name_of_nft: str, collection_contract: str, auction_id: int):
140 assert name_of_nft != "", "Name cannot be empty"
141 assert collection_contract != "", "Collection contract cannot be empty"
142 assert seller != "", "Seller cannot be empty"
143 assert auction_id != "", "Auction ID cannot be empty"
144
145 auction = auctions[seller, collection_contract, name_of_nft, auction_id]
146 assert auction != 0, "Auction does not exist"
147 assert now < auction["auction_start"], "Auction has already started"
148 assert ctx.caller == seller, "Only the seller can cancel the auction"
149
150 currency.transfer(amount=auction["current_bid"], to=auction["current_highest_bidder"], main_account=ctx.this)
151 collection = I.import_module(collection_contract)
152 collection.transfer(name=name_of_nft, amount=1, to=ctx.caller)
153
154 auctions[seller, collection_contract, name_of_nft, auction_id] = 0
155
156 return f"Successfully cancelled Auction for {name_of_nft}"
157
158 @export
159 def finalize_auction(seller: str, name_of_nft: str, collection_contract: str, auction_id: int):
160 assert name_of_nft != "", "Name cannot be empty"
161 assert collection_contract != "", "Collection contract cannot be empty"
162 assert seller != "", "Seller cannot be empty"
163 assert auction_id != "", "Auction ID cannot be empty"
164
165 auction = auctions[seller, collection_contract, name_of_nft, auction_id]
166 assert auction != 0, "Auction does not exist"
167 assert now > auction["auction_end"], "Auction has not ended yet"
168
169 currency.transfer(amount=auction["current_bid"], to=seller, main_account=ctx.this)
170 collection = I.import_module(collection_contract)
171 collection.transfer(name=name_of_nft, amount=1, to=auction["current_highest_bidder"])
172
173 auctions[seller, collection_contract, name_of_nft, auction_id] = 0
174 royalty_receivers[collection_contract, name_of_nft] = {"receiver": seller, "percentage": auction["future_royalty_percentage"]}
175
176 return f"Successfully finalized Auction for {name_of_nft}"
177
178
179 @export
180 def change_allowed_currency(contract: str):
181 assert ctx.caller == operator.get(), "Only the operator can do this"
182 allowed_currency.set(contract)
183
184 @export
185 def change_treasury(address: str):
186 assert ctx.caller == operator.get(), "Only the operator can do this"
187 treasury.set(address)
188
189 @export
190 def change_operator(address: str):
191 assert ctx.caller == operator.get(), "Only the operator can do this"
192 operator.set(address)
193

Byte Code

e3000000000000000000000000080000004000000073ae01000065005a0165026400640164028d025a0365026400640364028d025a04650564046400640564068d035a06650564046400640764068d035a0765026400640864028d025a08650564096400640a64068d035a09650a640b64056400640c640d8d045a0b65016a0c640e643664128d0265016a0c6413643764128d0265016a0c6414643864128d0267035a0d6416641784005a0e650f640083016510651065116512651264189c056419641a840483015a13650f6400830164396510651065116511641c9c04641d641e840583015a14650f64008301643a65106510651065116511641f9c0564206421840583015a15650f64008301651065106512651265166a1665166a1664229c0664236424840483015a17650f640083016510651065106511651264259c0564266427840483015a18650f64008301651065106510651164289c046429642a840483015a19650f64008301651065106510651164289c04642b642c840483015a1a650f640083016510642d9c01642e642f840483015a1b650f64008301651064309c0164316432840483015a1c650f64008301651064309c0164336434840483015a1d64355300293bda16636f6e5f6e66745f6d61726b6574706c6163655f7639da10616c6c6f7765645f63757272656e63792902da08636f6e7472616374da046e616d65da086f70657261746f72e900000000da066d61726b65742903da0d64656661756c745f76616c756572030000007204000000da0861756374696f6e73da08747265617375727946da11726f79616c74795f726563656976657273da16636f6e5f6e66745f6d61726b6574706c6163655f7634da126f6c645f6d61726b65745f76657273696f6e2904da10666f726569676e5f636f6e7472616374da0c666f726569676e5f6e616d6572030000007204000000da087472616e736665727204000000da06616d6f756e74da02746f2901da0461726773da07617070726f7665da0d7472616e736665725f66726f6dda0c6d61696e5f6163636f756e74630000000000000000000000000200000043000000732200000074006a0164018301010074026a0164028301010074036a016402830101006400530029034eda0863757272656e6379da40666636313534346561393465616165623564663038656438363363346139333865393132396162613663656565356633316236363831626465646531316238392904da125f5f616c6c6f7765645f63757272656e6379da03736574da0a5f5f6f70657261746f72da0a5f5f7472656173757279a900721d000000721d000000da00da045f5f5f5f14000000730a00000000010a01040106010401721f0000002905da0b6e616d655f6f665f6e6674da13636f6c6c656374696f6e5f636f6e74726163747211000000da0e63757272656e63795f7072696365da12726f79616c74795f70657263656e7461676563050000000000000008000000080000004300000073100100007c0064016b03731074006402830182017c0164016b03732074006403830182017c0264046b04733074006405830182017c0364046b047340740064068301820174016a027c0183017d0574016a037c0574048302735e74006407830182017c056a057c007c0274066a0774066a0864088d04010074097d06782c740a7c02830144005d207d0764097c03640a9c02740b74066a087c017c007c067c07170066043c0071825700740c7c017c0066021900640b6b0272fa7c0464006b0272c6740d640c83017d047c04640d6b0173d67400640e830182017c0464046b0573e67400640f8301820174066a087c0464109c02740c7c017c0066023c0064117c029b0064127c009b0064137c039b009d06530029144e721e0000007a144e616d652063616e6e6f7420626520656d7074797a23436f6c6c656374696f6e20636f6e74726163742063616e6e6f7420626520656d70747972060000007a1f43616e6e6f742073656c6c206e65676174697665204e465420616d6f756e747a2243616e6e6f742073656c6c20666f72206e656761746976652062616c616e636573217a1d496e76616c696420636f6c6c656374696f6e20696e746572666163652129047204000000721100000072120000007216000000e90100000029027211000000da057072696365467a03302e30e9320000007a1f4f7665722035302520726f79616c7479206973206e6f7420616c6c6f7765647a1f556e64657220302520726f79616c7479206973206e6f7420616c6c6f7765642902da08726563656976657272230000007a145375636365737366756c6c79206c697374656420fa01207a0520666f7220290eda0e417373657274696f6e4572726f72da0149da0d696d706f72745f6d6f64756c65da11656e666f7263655f696e74657266616365da1b666f726365645f636f6c6c656374696f6e5f696e746572666163657215000000da03637478da0474686973da0663616c6c6572da09626c6f636b5f6e756dda0572616e6765da085f5f6d61726b6574da135f5f726f79616c74795f726563656976657273da07646563696d616c290872200000007221000000721100000072220000007223000000da0a636f6c6c656374696f6eda116c697374696e675f756e697175655f6964da0169721d000000721d000000721e000000da0873656c6c5f6e66741c0000007326000000000310011001100110010a010e0106010c010a0104010e0220011001080108011001100214017239000000e905000000290472200000007221000000da0a6c697374696e675f6964da0776657273696f6e63040000000000000007000000060000004300000073b20000007c0364016b02722a74006a01640283017d047c046a027c007c0164038d02010064047c009b009d0253007c0064056b03733a74036406830182017c0164056b03734a74036407830182017c0264056b03735a7403640883018201740474056a067c017c007c02660419007d0574006a017c0183017d067c066a077c007c056409190074056a06640a8d030100640b7c05640c1900640d9c02740474056a067c017c007c0266043c0064047c009b009d025300290e4ee904000000720c0000002902722000000072210000007a165375636365737366756c6c7920726566756e64656420721e0000007a144e616d652063616e6e6f7420626520656d7074797a23436f6c6c656374696f6e20636f6e74726163742063616e6e6f7420626520656d7074797a1a4c697374696e672049442063616e6e6f7420626520656d70747972110000002903720400000072110000007212000000720600000072250000002902721100000072250000002908722a000000722b000000da0a726566756e645f6e667472290000007233000000722e00000072300000007210000000290772200000007221000000723b000000723c000000da0f6f6c645f6d61726b6574706c616365da0c6d61726b65745f656e7472797236000000721d000000721d000000721e000000723e00000036000000731e000000000308010a01060108010a011001100110010a0108010a010c010a021c01723e000000290572040000007221000000da0673656c6c6572723b000000723c0000006305000000000000000b0000000600000043000000738c0100007c0464016b02722e74006a01640283017d057c056a027c007c017c02640364048d04010064057c009b009d0253007c0064066b03733e74036407830182017c0164066b03734e74036408830182017c0264066b03735e74036409830182017c0364066b03736e7403640a8301820174006a017c0183017d0674006a0174046a05830083017d0774006a067c0674078302739a7403640b8301820174087c027c017c007c0366041900640c1900640d1b00640e14007d0874087c027c017c007c0366041900640c1900640d1b0074097c017c0066021900640f190014007d097c076a0a74087c027c017c007c0366041900640c19007c0818007c0918007c02740b6a0c64108d0301007c076a0a7c08740d6a058300740b6a0c64108d0301007c0964116b04900172467c076a0a7c0974097c017c006602190064121900740b6a0c64108d03010074087c027c017c007c03660419007d0a64117c0a640c190064139c0274087c027c017c007c0366043c007c066a0e7c006403740b6a0c64148d03010064057c009b009d02530029154e723d000000720c0000007224000000290472040000007221000000724100000072110000007a145375636365737366756c6c7920626f7567687420721e0000007a144e616d652063616e6e6f7420626520656d7074797a23436f6c6c656374696f6e20636f6e74726163742063616e6e6f7420626520656d7074797a1653656c6c65722063616e6e6f7420626520656d7074797a1a4c697374696e672049442063616e6e6f7420626520656d7074797a1d496e76616c696420636f6c6c656374696f6e20696e74657266616365217225000000e964000000e90200000072230000002903721100000072120000007216000000720600000072270000002902721100000072250000002903720400000072110000007212000000290f722a000000722b000000723e00000072290000007219000000da03676574722c000000722d000000723300000072340000007215000000722e0000007230000000721c0000007210000000290b720400000072210000007241000000723b000000723c000000723f00000072360000007217000000da03666565da07726f79616c7479da106f6c645f6d61726b65745f656e747279721d000000721d000000721e000000da076275795f6e66744b000000733a000000000308010a0106010c010a0110011001100110010a010e010e0106021c022001080104011c010a010c010a010a010801160110010201180112017248000000290672200000007221000000da1473746172745f63757272656e63795f7072696365da196675747572655f726f79616c74795f70657263656e74616765da0d61756374696f6e5f7374617274da0b61756374696f6e5f656e6463060000000000000008000000060000004300000073020100007c0064016b03731074006402830182017c0164016b03732074006403830182017c0264046b04733074006405830182017c0364066b01734074006407830182017c0364046b05735074006408830182017c0474016b04736074006409830182017c057c046b0473707400640a830182017c057c0474026a03640b640c8d0117006b00738c7400640d830182017c047c0574026a03640e640c8d0118006b0073a87400640f8301820174046a057c0183017d0674046a067c067407830273c674006410830182017c066a087c00640e74096a0a74096a0b64118d040100740c7d077c0264007c037c047c0564129c05740d74096a0b7c017c007c0766043c006400530029134e721e0000007a144e616d652063616e6e6f7420626520656d7074797a23436f6c6c656374696f6e20636f6e74726163742063616e6e6f7420626520656d70747972060000007a2543616e6e6f742061756374696f6e20666f72206e656761746976652062616c616e6365732172260000007a1f4f7665722035302520726f79616c7479206973206e6f7420616c6c6f7765647a1f556e64657220302520726f79616c7479206973206e6f7420616c6c6f7765647a2141756374696f6e2063616e6e6f7420737461727420696e207468652070617374217a2441756374696f6e2063616e6e6f7420656e64206265666f72652069742073746172747321e91e0000002901da04646179737a2841756374696f6e2063616e6e6f74206c617374206c6f6e676572207468616e20333020646179732172240000007a2d41756374696f6e2063616e6e6f7420737461727420616e6420656e64206f6e207468652073616d6520646179217a1d496e76616c696420636f6c6c656374696f6e20696e7465726661636521290472040000007211000000721200000072160000002905da0b63757272656e745f626964da1663757272656e745f686967686573745f626964646572724a000000724b000000724c000000290e7229000000da036e6f77da086461746574696d65da0974696d6564656c7461722a000000722b000000722c000000722d0000007215000000722e000000722f00000072300000007231000000da0a5f5f61756374696f6e732908722000000072210000007249000000724a000000724b000000724c00000072360000007237000000721d000000721d000000721e000000da0d73657475705f61756374696f6e6f00000073280000000004100110011001100110011001100116010601160106010a010e0106010c010a0104020201040172550000002905724100000072200000007221000000da0a61756374696f6e5f6964da0362696463050000000000000008000000060000004300000073000100007c0164016b03731074006402830182017c0264016b03732074006403830182017c0064016b03733074006404830182017c0364016b03734074006405830182017c0464066b047350740064078301820174017c007c027c017c03660419007d0574027c05640819006b047374740064098301820174027c05640a19006b0073887400640b830182017c05640c19007d067c05640d19007d077c047c066b0473a87400640e830182017c0774036a046b0373ba7400640f8301820174056a067c0474036a0774036a0464108d0301007c047c05640c3c0074036a047c05640d3c007c0574017c007c027c017c0366043c0064117c049b0064127c019b009d04530029134e721e0000007a144e616d652063616e6e6f7420626520656d7074797a23436f6c6c656374696f6e20636f6e74726163742063616e6e6f7420626520656d7074797a1653656c6c65722063616e6e6f7420626520656d7074797a1a41756374696f6e2049442063616e6e6f7420626520656d70747972060000007a19426964206d75737420626520686967686572207468616e2030724b0000007a1b41756374696f6e20686173206e6f74207374617274656420796574724c0000007a1141756374696f6e2068617320656e646564724f00000072500000007a2f426964206d75737420626520686967686572207468616e207468652063757272656e742068696768657374206269647a22596f752061726520616c72656164792074686520686967686573742062696464657229037211000000721200000072160000007a115375636365737366756c6c7920626964207a04206f6e202908722900000072540000007251000000722e000000723000000072170000007215000000722f000000290872410000007220000000722100000072560000007257000000da0761756374696f6eda0b686967686573745f626964da0e686967686573745f626964646572721d000000721d000000721e000000da0b6269645f61756374696f6e8a00000073220000000003100110011001100110011001140114010801080110011201140108010a011001725b0000002904724100000072200000007221000000725600000063040000000000000006000000060000004300000073d60000007c0164016b03731074006402830182017c0264016b03732074006403830182017c0064016b03733074006404830182017c0364016b037340740064058301820174017c007c027c017c03660419007d047c0464066b037360740064078301820174027c04640819006b007374740064098301820174036a047c006b0273867400640a8301820174056a067c04640b19007c04640c190074036a07640d8d03010074086a097c0283017d057c056a067c01640e74036a04640f8d030100640674017c007c027c017c0366043c0064107c019b009d02530029114e721e0000007a144e616d652063616e6e6f7420626520656d7074797a23436f6c6c656374696f6e20636f6e74726163742063616e6e6f7420626520656d7074797a1653656c6c65722063616e6e6f7420626520656d7074797a1a41756374696f6e2049442063616e6e6f7420626520656d70747972060000007a1641756374696f6e20646f6573206e6f74206578697374724b0000007a1b41756374696f6e2068617320616c726561647920737461727465647a264f6e6c79207468652073656c6c65722063616e2063616e63656c207468652061756374696f6e724f00000072500000002903721100000072120000007216000000722400000029037204000000721100000072120000007a235375636365737366756c6c792063616e63656c6c65642041756374696f6e20666f7220290a722900000072540000007251000000722e000000723000000072170000007210000000722f000000722a000000722b0000002906724100000072200000007221000000725600000072580000007236000000721d000000721d000000721e000000da0e63616e63656c5f61756374696f6ea0000000731c0000000003100110011001100110011001140112010c010e010a0112011001725c00000063040000000000000006000000060000004300000073d80000007c0164016b03731074006402830182017c0264016b03732074006403830182017c0064016b03733074006404830182017c0364016b037340740064058301820174017c007c027c017c03660419007d047c0464066b037360740064078301820174027c04640819006b047374740064098301820174036a047c04640a19007c0074056a06640b8d03010074076a087c0283017d057c056a047c01640c7c04640d1900640e8d030100640674017c007c027c017c0366043c007c007c04640f190064109c0274097c027c0166023c0064117c019b009d02530029124e721e0000007a144e616d652063616e6e6f7420626520656d7074797a23436f6c6c656374696f6e20636f6e74726163742063616e6e6f7420626520656d7074797a1653656c6c65722063616e6e6f7420626520656d7074797a1a41756374696f6e2049442063616e6e6f7420626520656d70747972060000007a1641756374696f6e20646f6573206e6f74206578697374724c0000007a1941756374696f6e20686173206e6f7420656e64656420796574724f0000002903721100000072120000007216000000722400000072500000002903720400000072110000007212000000724a00000029027227000000da0a70657263656e746167657a235375636365737366756c6c792066696e616c697a65642041756374696f6e20666f7220290a72290000007254000000725100000072170000007210000000722e000000722f000000722a000000722b00000072340000002906724100000072200000007221000000725600000072580000007236000000721d000000721d000000721e000000da1066696e616c697a655f61756374696f6eb3000000731e000000000310011001100110011001100114010c010a010a010a010a0110021601725e00000029017203000000630100000000000000010000000200000043000000732400000074006a0174026a0383006b027316740464018301820174056a067c00830101006400530029024e7a1d4f6e6c7920746865206f70657261746f722063616e20646f20746869732907722e0000007230000000721b000000724400000072290000007219000000721a00000029017203000000721d000000721d000000721e000000da176368616e67655f616c6c6f7765645f63757272656e6379c8000000730400000000021601725f0000002901da0761646472657373630100000000000000010000000200000043000000732400000074006a0174026a0383006b027316740464018301820174056a067c00830101006400530029024e7a1d4f6e6c7920746865206f70657261746f722063616e20646f20746869732907722e0000007230000000721b00000072440000007229000000721c000000721a00000029017260000000721d000000721d000000721e000000da0f6368616e67655f7472656173757279ce0000007304000000000216017261000000630100000000000000010000000200000043000000732400000074006a0174026a0383006b027316740464018301820174026a057c00830101006400530029024e7a1d4f6e6c7920746865206f70657261746f722063616e20646f20746869732906722e0000007230000000721b00000072440000007229000000721a00000029017260000000721d000000721d000000721e000000da0f6368616e67655f6f70657261746f72d400000073040000000002160172620000004e29037204000000721100000072120000002903721100000072040000007212000000290472040000007211000000721200000072160000002901723a0000002901723a000000291eda09696d706f72746c6962722a000000da085661726961626c657219000000721b000000da044861736872330000007254000000721c0000007234000000da0b466f726569676e48617368da145f5f6f6c645f6d61726b65745f76657273696f6eda0446756e63722d000000721f000000da085f5f6578706f7274da03737472da03696e74da05666c6f61747239000000723e000000724800000072520000007255000000725b000000725c000000725e000000725f00000072610000007262000000721d000000721d000000721d000000721e000000da083c6d6f64756c653e0100000073560000000401040108010c0106010801060108010c0104010a01020104010a01060116010c0308080601060112180602181306021a22060104010401161806010601121406010601101106010401121306011005060110050601