From 3fe4668a1e84313be4348f4b12ee72b9031a6521 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Sun, 20 Nov 2022 21:00:14 -0800 Subject: [PATCH 001/111] feat(db): replace most db with graph --- lib/bot-core.ts | 45 +--- lib/create-db.ts | 99 ++------- lib/cron.ts | 555 +++++++++++++++++++++++++---------------------- lib/db.ts | 492 +++++++++++++---------------------------- lib/graph.ts | 39 ++++ package.json | 7 +- 6 files changed, 517 insertions(+), 720 deletions(-) create mode 100644 lib/graph.ts diff --git a/lib/bot-core.ts b/lib/bot-core.ts index 4f50ffb..4c1c787 100644 --- a/lib/bot-core.ts +++ b/lib/bot-core.ts @@ -1,23 +1,12 @@ import {BigNumber, utils} from "ethers"; import {getRealityETHV30} from "./ethers"; -import {Wallet} from "@ethersproject/wallet"; -import {createAccount} from "./db"; -const Web3 = require('web3') const _contract = require('./abi/RealityETH_v3_0.json') -const _batchedSend = require('web3-batched-send') -const escape = require('markdown-escape') +const Web3 = require('web3') const web3 = new Web3(process.env.WEB3_PROVIDER_URL) -const batchedSend = _batchedSend( - web3, // Your web3 object. - // The address of the transaction batcher contract you wish to use. The addresses for the different networks are listed below. If the one you need is missing, feel free to deploy it yourself and make a PR to save the address here for others to use. - process.env.TRANSACTION_BATCHER_CONTRACT_ADDRESS, - process.env.PRIVATE_KEY, // The private key of the account you want to send transactions from. - 12000 // The debounce timeout period in milliseconds in which transactions are batched. - ) const contract = new web3.eth.Contract( _contract, - process.env.REALITITY_ETH_V30 + process.env.REALITY_ETH_V30 ) interface RealityBanResult { @@ -25,9 +14,10 @@ interface RealityBanResult { questionUrl: string } -export const reportUser = async (lang: string, hasBanningPermission: boolean, fromUsername: string, UserID: string, platform: string, group: string, inviteURL: string, groupID: string, rules: string, message: string, messageBackup: string): Promise => { +export const reportUser = async (batchedSend:any, lang: string, hasBanningPermission: boolean, fromUsername: string, UserID: string, platform: string, group: string, inviteURL: string, groupID: string, rules: string, message: string, messageBackup: string, reportedBy: string): Promise => { const minBond = utils.parseUnits('5', 18); // 5 DAI const questionId = await askQuestionWithMinBond( + batchedSend, lang, fromUsername, UserID, @@ -38,6 +28,7 @@ export const reportUser = async (lang: string, hasBanningPermission: boolean, fr rules, message, messageBackup, + reportedBy, minBond ); @@ -47,24 +38,24 @@ export const reportUser = async (lang: string, hasBanningPermission: boolean, fr return { questionId: questionId, - questionUrl: `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITITY_ETH_V30}-${questionId}` + questionUrl: `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${questionId}` }; } -async function askQuestionWithMinBond(lang: string, fromUsername: string, UserID: string, platform: string, group: string, inviteURL: string, groupID: string, rulesUrl: string|BigNumber, message: string, messageBackup: string, minBond: number|BigNumber): Promise { +async function askQuestionWithMinBond(batchedSend: any, lang: string, fromUsername: string, UserID: string, platform: string, group: string, inviteURL: string, groupID: string, rulesUrl: string|BigNumber, message: string, messageBackup: string, reportedBy: string, minBond: number|BigNumber): Promise { // A question is automatically created in Realitio with an answer in favor of banning the user. // Bond of the answer: 1 xDAI (initially the answer can be omitted). - const realityETHV30 = getRealityETHV30(process.env.REALITITY_ETH_V30, process.env.PRIVATE_KEY); + const realityETHV30 = getRealityETHV30(process.env.REALITY_ETH_V30, process.env.PRIVATE_KEY); const delim = '\u241f'; const category = 'misc'; const openingTs = Math.floor(new Date().getTime()/1000); - const question = fromUsername+delim+UserID+delim+platform+delim+group+delim+inviteURL+delim+groupID+delim+rulesUrl+delim+message+delim+messageBackup+delim+category+delim+lang; + const question = fromUsername+delim+UserID+delim+platform+delim+group+delim+inviteURL+delim+groupID+delim+rulesUrl+delim+message+delim+messageBackup+delim+category+delim+lang+delim+reportedBy; const arbitrator = process.env.REALITIO_ARBITRATOR; const templateId = process.env.TEMPLATE_ID; const timeout = 86400; - const reality = process.env.REALITITY_ETH_V30; + const reality = process.env.REALITY_ETH_V30; const txnBatchSender = process.env.TRANSACTION_BATCHER_CONTRACT_ADDRESS; const nonce = 0; const contentHash = web3.utils.soliditySha3( @@ -101,7 +92,7 @@ async function answerQuestion(questionId: string, privateKey: string): Promise { - const wallet = Wallet.createRandom(); - - await createAccount( - db, - wallet.address, - wallet.privateKey, - platform, - userId - ); - - return wallet.address } \ No newline at end of file diff --git a/lib/create-db.ts b/lib/create-db.ts index 8e86869..5c1b586 100644 --- a/lib/create-db.ts +++ b/lib/create-db.ts @@ -1,7 +1,7 @@ const Database = require('better-sqlite3'); (async () => { - const db = new Database('database.db', { verbose: console.log }); + const db = new Database('database.db'); db.pragma('journal_mode = WAL'); /** @@ -15,99 +15,32 @@ const Database = require('better-sqlite3'); `CREATE TABLE groups ( platform TEXT, group_id TEXT, + channel_id TEXT, + thread_id_rules TEXT, + thread_id_notifications TEXT, + thread_id_welcome TEXT, invite_url TEXT, - address TEXT, - permission BOOLEAN, + invite_url_channel TEXT, + greeting_mode INTEGER, lang TEXT, + rules TEXT PRIMARY KEY (platform, group_id))` ); - /** - * `question_id` is the id of the question in reality.eth - * `platform` can be `telegram`, `reddit`, etc. - * `group_id` is the id of the group on the platform (eg. group on telegram, subreddit on reddit, etc.). - * `user_id` is the id of the banned user in `platform`. - * `chat_id` is the id of the banned user in `platform`. - * `active` indicates whether the user is currently banned. - * `finalized` indicates if the question has finalized. - */ - await db.exec( - `CREATE TABLE reports ( - question_id TEXT PRIMARY KEY, - platform TEXT, - group_id TEXT, - user_id TEXT, - username TEXT, - msg_id TEXT, - timestamp INTEGER, - active_timestamp INTEGER, - active BOOLEAN, - timeServed INTEGER, - finalized BOOLEAN, - arbitrationRequested BOOLEAN, - msgBackup TEXT, - evidenceIndex INTEGER, - bond_paid INTEGER - )` - ); - - /** - * `question_id` is the id of the question in reality.eth - * `platform` can be `telegram`, `reddit`, etc. - * `group_id` is the id of the group on the platform (eg. group on telegram, subreddit on reddit, etc.). - * `user_id` is the id of the banned user in `platform`. - * `chat_id` is the id of the banned user in `platform`. - * `active` indicates whether the user is currently banned. - * `finalized` indicates if the question has finalized. - */ - await db.exec( - `CREATE TABLE reportRequests ( - platform TEXT, - group_id TEXT, - user_id TEXT, - username TEXT, - msg_id TEXT, - confirmations INTEGER, - confirmed BOOLEAN, - msgBackup TEXT, - msgRequestId TEXT, - PRIMARY KEY (platform, group_id, user_id, msg_id))` - ); - /** - * `question_id` is the id of the question in reality.eth - * `platform` can be `telegram`, `reddit`, etc. - * `group_id` is the id of the group on the platform (eg. group on telegram, subreddit on reddit, etc.). - * `user_id` is the id of the banned user in `platform`. - * `chat_id` is the id of the banned user in `platform`. - * `active` indicates whether the user is currently banned. - * `finalized` indicates if the question has finalized. - */ - await db.exec( - `CREATE TABLE allowance ( - platform TEXT, - group_id TEXT, - user_id TEXT, - report_allowance INTEGER, - evidence_allowance INTEGER, - timestamp_refresh INTEGER, - question_id_last TEXT, - timestamp_last_question INTEGER, - PRIMARY KEY (platform, group_id, user_id))` - ); /** * `platform` can be `telegram`, `reddit`, etc. * `group_id` is the id of the group on the platform (eg. group on telegram, subreddit on reddit, etc.). * `rules` the group rules. eg ipfs cid string. * `timestamp` the timestamp when the rules were set. */ - await db.exec( - `CREATE TABLE rules ( - platform TEXT, - group_id TEXT, - rules TEXT, - timestamp INTEGER, - PRIMARY KEY (platform, group_id, timestamp))` - ); + await db.exec( + `CREATE TABLE rules ( + platform TEXT, + group_id TEXT, + rules TEXT, + timestamp INTEGER, + PRIMARY KEY (platform, group_id, timestamp))` + ); db.close(); })(); \ No newline at end of file diff --git a/lib/cron.ts b/lib/cron.ts index 4cd48c3..b1b9a0c 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -1,302 +1,331 @@ require('dotenv').config() const ModeratorBot = require('node-telegram-bot-api'); -//import * as TelegramBot from "node-telegram-bot-api"; -import {openDb, getFinalRecord, getRule, getCurrentRecord, setReportArbitration, getDisputedReports, setReport} from "./db"; -//import {getModerateBilling} from "./ethers"; +import {openDb, getChannelID, getLang} from "./db"; import request from "graphql-request"; import {BigNumber} from "ethers"; import TelegramBot from "node-telegram-bot-api"; +import langJson from "./telegram/assets/lang.json"; +import {Wallet} from "@ethersproject/wallet"; + const db = openDb(); +const bot: TelegramBot = new ModeratorBot(process.env.BOT_TOKEN, {polling: false}); +const channelIDs : Map = new Map(); +const lang : Map = new Map(); + +// Only need DB for +// - channelID +// - finalizedReportCount +// Can put in DB or make template +// - language (for new reports) +// - rules (for new reports) (async ()=> { - const t0 = Date.now(); - const bot: TelegramBot = new ModeratorBot(process.env.BOT_TOKEN, {polling: false}); + const botaddress = await (await new Wallet(process.env.PRIVATE_KEY)).address; + const timestampLastUpdated = 0; + const timestampNew = Math.floor(Date.now()/1000); + const graphSyncingPeriod = 300; const reports = {}; - (await getDisputedReports(db)).forEach((report) => { - reports[report.question_id] = report; - }); + /* + var moderationTypes: string = ''; + for (const lang in templates[process.env.CHAIN_ID]) + for (const template in templates[process.env.CHAIN_ID][lang]) + moderationTypes += '\"'+process.env.REALITY_ETH_V30+'-0x'+Number(templates[process.env.CHAIN_ID][lang][template]).toString(16)+"\","; + */ + // dispute final + // dispute appealsPossible + // dispute disputesAppeal + // dispute created + // dispute appeal ruling funded + // realityQuestionUnanswered and finalized + // realityQuestionAnswered and finalized + // realityQuestionAnswered and not finalized + // jannies sheriff + // jannies deputysheriff + const lastPageUpdated = 0; + const queryModeration = getQuery(lastPageUpdated, timestampLastUpdated, botaddress, timestampNew, graphSyncingPeriod) - const query = `{ - questions( - where: { - bond_not: null, id_in: ${JSON.stringify(Object.keys(reports))} - } - ) { - id - answer - finalize_ts - arbitrationRequested - disputeId - bond - ruling - } - }`; - const result = await request( - 'https://api.thegraph.com/subgraphs/name/shotaronowhere/kleros-moderate-rinkeby', - query - ) - for (const question of result.questions) { - console.log((Date.now()-t0)/1000); - const answer = question.answer == null? null : BigNumber.from(question.answer); - const report = reports[question.id]; - const botUser = await bot.getChatMember(report.group_id,String((await bot.getMe()).id)); - const msgLink = 'https://t.me/c/' + report.group_id.substring(4) + '/' + report.msg_id; - const appealUrl = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITITY_ETH_V30}-${question.id}\n`; - const reportHistoryFinal = await getFinalRecord(db, report.platform, report.group_id, report.user_id); - const finalized = question.finalize_ts <= Math.ceil(+new Date() / 1000) + 60; // 1 min buffer for graph syncing and finality - if(question.arbitrationRequested === true){ - if(report.arbitrationRequested != true){ - //await bot.restrictChatMember(report.group_id, report.user_id, {can_send_messages: true}); - await setReport(db, question.id, false, true, report.activeTimestamp, 0, question.bond); - const reportHistoryCurrent = await getCurrentRecord(db, report.platform, report.group_id, report.user_id); - if (botUser.can_send_messages == true ){ - await bot.sendMessage(report.group_id, `Arbitration is requested for the [question](${appealUrl}) about *${report.username}*'s conduct due to the [message](${msgLink}) ([backup](${report.msgBackup})). Consequences of the report are lifted for the duration of the [dispute](https://court.kleros.io/cases/${BigNumber.from(question.disputeId).toNumber()}) (on Gnosis Chain).`, {parse_mode: 'Markdown'}); - } - if(reportHistoryCurrent == 0){ - const options = {can_send_messages: true, can_send_media_messages: true, can_send_polls: true, can_send_other_messages: true, can_add_web_page_previews: true, can_change_info: false, can_pin_messages: false}; - if (botUser.status == "administrator" && botUser.can_restrict_members == true){ - await bot.restrictChatMember(report.group_id, report.user_id, options); - } else { - if (botUser.can_send_messages == true ){ - await bot.sendMessage(report.group_id, `My admin rights are limited. I am unable to lift the temporary mute on *${report.username}* for the duration of the dispute. Please ask an admin of the group to lift the mute on *${report.username}*, if one exists.`); - } - } - } else - handleCurrentTelegramUnrestrict(bot, report, reportHistoryCurrent+reportHistoryFinal); - await setReportArbitration(db, question.id, 0); - } else if (question.ruling != null){ - const msgLink = 'https://t.me/c/' + report.group_id.substring(4) + '/' + report.msg_id; - if (botUser.can_send_messages == true ){ - await bot.sendMessage(report.group_id, `The dispute over *${report.username}*'s [message](${msgLink}) ([backup](${report.msgBackup})) resolved.`, {parse_mode: 'Markdown'}); - } - if (question.ruling == 1){ // check rulings - handleFinalizedTelegram(bot, report, question, 1, reportHistoryFinal); - } else{ - handleFinalizedTelegram(bot, report, question, 2, reportHistoryFinal); - } + console.log(queryModeration); + + const moderationActions = await request( + 'https://api.thegraph.com/subgraphs/name/shotaronowhere/kleros-moderate-goerli', + queryModeration + ); + + for (const data of moderationActions.disputesFinal) { + const settings = getGroupSettings(data.moderationInfo.user.group.groupID); + // settings[1] language + try{ + const msgLink = data.message; + const disputeURL = `https://resolve.kleros.io/${BigNumber.from(data.id).toNumber()}`; + // check rulings, note down shift since reality uses 0,1 for no, yes and kleros uses 1,2 for yes, no + const message = (data.finalRuling === 1)? 'broke the rules' : 'did not break the rules' + try{ + await bot.sendMessage(settings[0], `The [dispute](${disputeURL}) over *${data.moderationInfo.user.username}*'s [message](${msgLink}) ([backup](${data.moderationInfo.messageBackup})) resolved. *${data.moderationInfo.user.username}* ${message}`, {parse_mode: 'Markdown'}); + } catch(e){ + console.log(e) } - continue; + + } catch(e){ + console.log(e) } - const rules = await getRule(db, 'telegram', String(report.group_id), Math.floor(Date.now()/1000)); + } - // only final records considered for now. - if (answer == null && !finalized) - continue; - const latestReportState = (answer == null)? 2: answer.toNumber(); + for (const data of moderationActions.disputesAppealPossible) { + const settings = getGroupSettings(data.moderationInfo.user.group.groupID); + // settings[1] language + try{ + bot.sendMessage(settings[0], `The dispute id ${data.id} has concluded it's current round. The ruling is ${data.currentRuling}. An appeal is possible.`); + //TODO + //await bot.sendMessage(settings[0], `The current dispute over the [question](${realityURL}) about *${report.username}*'s conduct due to the [message](${msgLink}) ([backup](${report.msgBackup})) has concluded it's current round. *${report.username}*'s conduct ${disputeInfo[question.disputeId].currentRulling == 2? 'broke the rules': 'did not break the rules'} If you think the decision is incorrect, you can request an [appeal](https://resolve.kleros.io/cases/${BigNumber.from(question.disputeId).toNumber()})`, {parse_mode: 'Markdown'}); + } catch(e){ + console.log(e) + } + } + for (const data of moderationActions.disputesCreated) { + const settings = getGroupSettings(data.moderationInfo.user.group.groupID); + // settings[1] language + const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; + const disputeURL = `https://resolve.kleros.io/${BigNumber.from(data.id).toNumber()}`; + try{ + await bot.sendMessage(settings[0], `Arbitration is requested for the [question](${realityURL}) about *${data.moderationInfo.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})). Consequences of the report are lifted for the duration of the [dispute](${disputeURL}) (on Gnosis Chain).`, {parse_mode: 'Markdown'}); + handleTelegramUpdateRestrict(bot,settings[0],data,timestampNew, false); + } catch (e){ + console.log(e) + } + } - if (finalized){ - if (report.platform === 'telegram') { - if (botUser.can_send_messages == true ){ - await bot.sendMessage(report.group_id, `The report on Reality is finalized.`, {parse_mode: 'Markdown'}); - } - handleFinalizedTelegram(bot, report, question, latestReportState, reportHistoryFinal); - } else { - console.error(`Invalid platform: ${report.platform}`); - } - } else if (question.bond != report.bond_paid) { - if (latestReportState === 1) { - // ban - await setReport(db, question.id, true, finalized, Math.ceil(+new Date() / 1000), 0, question.bond); - const currentRecord = await getCurrentRecord(db, report.platform, report.group_id, report.user_id); - const reportHistoryCurrent = reportHistoryFinal + currentRecord; - if (report.platform === 'telegram') { - // @ts-ignore - const msgLink = 'https://t.me/c/' + report.group_id.substring(4) + '/' + report.msg_id; - if (botUser.can_send_messages == true ){ - await bot.sendMessage(report.group_id, `The question, \n\n\"Did *${report.username}*'s conduct due to this [message](${msgLink}) ([backup](${report.msgBackup})) violate the [rules](${rules})?\",\n\nis answered with *Yes*.\n\nDo you think this answer is true? If not, you can [correct](${appealUrl}) the answer.`, {parse_mode: 'Markdown'}); - await bot.sendMessage(report.group_id, `*${report.username}* is muted while the question is answered with yes and the answer is not yet final.`, {parse_mode: 'Markdown'}); - } - var options; - switch(reportHistoryCurrent){ - case 1:{ - const paroleDate = Math.ceil(+new Date() / 1000) + 86400; - options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false, until_date: paroleDate}; - break; - } - case 2:{ - const paroleDate = Math.ceil(+new Date() / 1000) + 604800; - options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false, until_date: paroleDate}; - break; - } - default:{ - options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false}; - break; - } - } - if (botUser.status == "administrator" && botUser.can_restrict_members == true ){ - await bot.restrictChatMember(report.group_id, report.user_id, options); - } else if (botUser.can_send_messages == true){ - await bot.sendMessage(report.group_id, `My admin rights are limited. I am unable to mute *${report.username}*. Please ask an admin to apply the mute.`); - } - } else { - console.error(`Invalid platform: ${report.platform}`); - } - } else { - // unban - await setReport(db, question.id, false, finalized, Math.floor(Date.now()/1000), 0, question.bond); - const reportHistoryCurrent = reportHistoryFinal + await getCurrentRecord(db, report.platform, report.group_id, report.user_id); + for (const data of moderationActions.disputesAppealFunded) { + const settings = getGroupSettings(data.moderationInfo.user.group.groupID); + // settings[1] language + try{ + bot.sendMessage(settings[0], "An appeal has been funded"); + } catch(e){ + console.log(e) + } + } - if (report.platform === 'telegram') { - // @ts-ignore - const msgLink = 'https://t.me/c/' + report.group_id.substring(4) + '/' + report.msg_id; - if (botUser.can_send_messages === true) - await bot.sendMessage(report.group_id, `The question, \n\n\"Did *${report.username}*'s conduct due to this [message](${msgLink}) ([backup](${report.msgBackup})) violate the [rules](${rules})?\",\n\nis answered with *No*.\n\nDo you think this answer is true? If not, you can [correct](${appealUrl}) the answer.`, {parse_mode: 'Markdown'}); - handleCurrentTelegramUnrestrict(bot, report, reportHistoryCurrent); - } else { - console.error(`Invalid platform: ${report.platform}`); - } - } + for(const data of moderationActions.realityQuestionUnansweredFinalized){ + const settings = getGroupSettings(data.user.group.groupID); + // settings[1] language + try{ + bot.sendMessage(settings[0], `The reality question ${data.id} was unanswered`); + } catch(e){ + console.log(e) } } -})() -const handleCurrentTelegramUnrestrict = async (bot: TelegramBot, report: any, reportHistoryCurrent: number) => { - const botUser = await bot.getChatMember(report.group_id,String((await bot.getMe()).id)); - switch(reportHistoryCurrent){ - case 0:{ - const options = {can_send_messages: true, can_send_media_messages: true, can_send_polls: true, can_send_other_messages: true, can_add_web_page_previews: true, can_change_info: false, can_pin_messages: false}; - if (botUser.status === "administrator" && botUser.can_restrict_members === true){ - if (botUser.can_restrict_members === true){ - await bot.restrictChatMember(report.group_id, report.user_id, options); - } - if (botUser.can_send_messages === true){ - await bot.sendMessage(report.group_id, `*${report.username}* has not broken the rules and all temporary mutes are lifted.`, {parse_mode: 'Markdown'}); - } - } else { - if (botUser.can_send_messages === true ){ - await bot.sendMessage(report.group_id, `My admin rights are limited. I am unable to remove any temporary mute on *${report.username}*. Please ask an admin to remove any temporary mute.`); - } - } - break; + for(const data of moderationActions.realityQuestionAnsweredFinalized){ + const settings = getGroupSettings(data.moderationInfo.user.group.groupID); + // settings[1] language + try{ + //bot.sendMessage(settings[0], `The reality question ${data.id} is finalized with ${data.currentAnswer}`); + + await bot.sendMessage(settings[0], `The report on Reality is finalized.`, {parse_mode: 'Markdown'}); + // finalize + await handleTelegramFinalize(bot, settings[0], data, timestampNew, botaddress); + } catch(e){ + console.log(e) } - case 1:{ - const paroleDate = Math.ceil(+new Date() / 1000) + 86400; - const options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false, until_date: paroleDate}; + } - if (botUser.status === "administrator" && botUser.can_restrict_members === true){ - await bot.restrictChatMember(report.group_id, report.user_id, options); - if (botUser.can_send_messages === true) - await bot.sendMessage(report.group_id, `*${report.username}* has broken the rules once. The ban on *${report.username}* is lifted to 24 hours.`, {parse_mode: 'Markdown'}); - } else { - if (botUser.can_send_messages === true ){ - await bot.sendMessage(report.group_id, `*${report.username}* has broken the rule at least once. My admin rights are limited. I am unable to apply the remporary mute of 24 hours on *${report.username}*. Please ask an admin of the group to apply the temporary 24 hour ban if not already applied.`); - } - } - break; + for(const data of moderationActions.realityQuestionAnsweredNotFinalized){ + const settings = getGroupSettings(data.moderationInfo.user.group.groupID); + // settings[1] language + try{ + bot.sendMessage(settings[0], `The reality question ${data.id} was answered with ${data.currentAnswer}`); + const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; + await bot.sendMessage(settings[0], `The question, \n\n\"Did *${data.moderationInfo.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) violate the [rules](${data.moderationInfo.rules})?\",\n\nis answered with *Yes*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, {parse_mode: 'Markdown'}); + handleTelegramUpdateRestrict(bot,settings[0], data,timestampNew, data.currentAnswer.equals("0x0000000000000000000000000000000000000000000000000000000000000001")); + } catch(e){ + console.log(e) } - case 2:{ - const paroleDate = Math.ceil(+new Date() / 1000) + 604800; - const options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false, until_date: paroleDate}; + } - if (botUser.status === "administrator" && botUser.can_restrict_members === true){ - await bot.restrictChatMember(report.group_id, report.user_id, options); - if (botUser.can_send_messages === true) - await bot.sendMessage(report.group_id, `*${report.username}* has broken the rules two times. The ban on *${report.username}* is lifted to 7 days.`, {parse_mode: 'Markdown'}); - } else if (botUser.can_send_messages === true ){ - await bot.sendMessage(report.group_id, `*${report.username}* has broken the rule at least two times. My admin rights are limited. I am unable to apply the temporary mute of 7 days on *${report.username}*. Please ask an admin of the group to apply the 7 day mute if not already applied.`); - } - break; + for(const data of moderationActions.sheriff){ + const settings = getGroupSettings(data.group.groupID); + // settings[1] language + try{ + bot.sendMessage(settings[0], `There's a new sheriff in town ${data.sheriff.userID}`); + } catch(e){ + console.log(e) + } + } + + for(const data of moderationActions.deputySheriff){ + const settings = getGroupSettings(data.group.groupID); + // settings[1] language + try{ + bot.sendMessage(settings[0], `There's a new deputy sheriff in town ${data.sheriff.userID}`); + } catch(e){ + console.log(e) + } + } + + return; + +})() + +const getGroupSettings = async (chatId: number): Promise<[string, string]> => { + var language = lang.get(chatId); + if (!language){ + language = getLang(db, 'telegram', String(chatId)); + lang.set(chatId, language); + } + var channelId = channelIDs.get(chatId) + if (!channelId){ + channelId = getChannelID(db, 'telegram', String(chatId)) + if (channelId === '0'){ + channelIDs.set(chatId, String(chatId)); + channelId = String(chatId) + }else + channelIDs.set(chatId, channelId); } - default:{ - const options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false}; + return [channelId, language] +} + - if (botUser.status === "administrator" && botUser.can_restrict_members === true){ - await bot.restrictChatMember(report.group_id, report.user_id, options); - if (botUser.can_send_messages === true) - await bot.sendMessage(report.group_id, `*${report.username}* has broken the rule at least three times. A permanent mute is imposed on *${report.username}*.`, {parse_mode: 'Markdown'}); - } else if (botUser.can_send_messages === true ){ - await bot.sendMessage(report.group_id, `*${report.username}* has broken the rule at least three times. My admin rights are limited. I am unable to apply the permanent mute on *${report.username}*. Please ask an admin of the group to apply the permanent mute if not already applied.`); +const handleTelegramUpdateRestrict = async (bot: TelegramBot, channelID: string, moderationInfo: any, timestampNew: number, restrict: boolean) => { + try{ + if (restrict){ + var duration: string; + if(moderationInfo.user.history.countBrokeRulesArbitrated == 1) + duration = 'first time and is subject to a 1 day'; + else if (moderationInfo.user.history.countBrokeRulesArbitrated == 2) + duration = 'second time and is subject to a 1 week'; + else + duration = 'third time and is subject to a 1 year'; + + await bot.sendMessage(channelID, `*${moderationInfo.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messsageBackup})) violated the [rules](${moderationInfo.rulesUrl}) for the ${duration} ban.`, {parse_mode: 'Markdown'}); + await bot.banChatMember(moderationInfo.user.group.groupID, moderationInfo.user.userID, Number(moderationInfo.user.history.timestampParole)); + } else { + const options = timestampNew > Number(moderationInfo.user.history.timestampParole)? {can_send_messages: true, can_send_media_messages: true, can_send_polls: true, can_send_other_messages: true, can_add_web_page_previews: true, can_change_info: false, can_pin_messages: false}: {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false, until_date: Number(moderationInfo.user.userHistory.timestampParole)}; + await bot.restrictChatMember(moderationInfo.user.group.groupID, moderationInfo.user.userID, options); + if (timestampNew > Number(moderationInfo.user.history.timestampParole)) + await bot.sendMessage(channelID, `*${moderationInfo.user.userID}* has no other active reports. All bans are lifted.`, {parse_mode: 'Markdown'}); + else { + const date = new Date(Number(moderationInfo.user.history.timestampParole) * 1000).toISOString(); + await bot.sendMessage(moderationInfo.user.group.groupID, `*${moderationInfo.user.username}* has other active reports. The ban on *${moderationInfo.user.username}* is reduced and now expires on ${date}`, {parse_mode: 'Markdown'}); } - break; } + } catch(e){ + console.log(e) + await bot.sendMessage(moderationInfo.user.group.groupID, `My admin rights are limited. I am unable to lift the ban/mute duration for *${moderationInfo.user.username}*. Please ask an admin.`); + } +} + +const handleTelegramFinalize = async (bot: TelegramBot, channelID: string, realityCheck: any, timestampNew: number, botaddress: string) => { + const finalizedCount = await getFinalizedCount(realityCheck.moderationInfo.user, timestampNew, botaddress); + if (finalizedCount == 1){ + + } + var duration: string; + if(finalizedCount == 1) + duration = 'first time and is subject to a 1 day'; + else if (finalizedCount == 2) + duration = 'second time and is subject to a 1 week'; + else + duration = 'third time and is subject to a 1 year'; + try{ + await bot.sendMessage(channelID, `*${realityCheck.moderationInfo.user.username}*'s conduct due to this [message](${realityCheck.moderationInfo.message}) ([backup](${realityCheck.moderationInfo.messsageBackup})) violated the [rules](${realityCheck.moderationInfo.rulesUrl}) for the ${duration} ban.`, {parse_mode: 'Markdown'}); + await bot.banChatMember(realityCheck.moderationInfo.user.group.groupID, realityCheck.moderationInfo.userID, Number(realityCheck.moderationInfo.user.history.timestampParole)); + + } catch(e){ + await bot.sendMessage(channelID, `My admin rights are limited. I am unable to lift any active mute on *${realityCheck.moderationInfo.user.username}*. Please ask an admin to remove any mute related to this question.`); } } -const handleFinalizedTelegram = async (bot: any, report: any, question: any, latestReportState: number, reportHistory: number) => { - const msgLink = 'https://t.me/c/' + report.group_id.substring(4) + '/' + report.msg_id; - const botUser = await bot.getChatMember(report.group_id,String((await bot.getMe()).id)); - const rules = await getRule(db, 'telegram', String(report.group_id), Math.floor(Date.now()/1000)); - const bond = question.bond == null? 0: question.bond; - if (latestReportState === 1){ - const activeTimestamp = latestReportState === report.active ? report.activeTimestamp : Math.ceil(+new Date() / 1000); - switch(reportHistory){ - case 0:{ - if (botUser.can_send_messages === true ){ - await bot.sendMessage(report.group_id, `*${report.username}*'s conduct due to this [message](${msgLink}) ([backup](${report.msgBackup})) violated the [rules](${rules}) for the first time and is subject to a 1 day ban.`, {parse_mode: 'Markdown'}); - } - const paroleDate = Math.ceil(+new Date() / 1000) + 86400; - if (botUser.status === "administrator" && botUser.can_restrict_members === true ){ - try{ - await bot.banChatMember(report.group_id, report.user_id, {until_date: paroleDate}); - } catch { - if (botUser.can_send_messages === true ){ - await bot.sendMessage(report.group_id, `My admin rights are limited. I am unable to ban *${report.username}* for 24 hours. Please ask an admin to apply the 24 hour ban.`); - } - console.log("ban error"); + +const getFinalizedCount = async (moderationInfo: any, timestampNew: number, botaddress: string): Promise => { + const queryOptimisticallyFinalized =`{ + realityChecks(where: {deadline_lt: ${timestampNew}, currentAnswer: "0x0000000000000000000000000000000000000000000000000000000000000001", moderationInfo_: {askedBy: "${botaddress}", user: "${moderationInfo.user}"}}) { + id + } + }`; + const moderationActions = await request( + 'https://api.thegraph.com/subgraphs/name/shotaronowhere/kleros-moderate-goerli', + queryOptimisticallyFinalized + ); + return moderationInfo.user.history.countBrokeRulesArbitrated + moderationActions.data.length; +} + +const getQuery = (lastPageUpdated: number, timestampLastUpdated: number, botaddress: string, timestampNew: number, graphSyncingPeriod: number): string => { + const moderationInfoContent = ` id + message + messageBackup + moderationType + rulesUrl + user { + username + userID + group { + groupID } - } - await setReport(db, question.id, true, true, activeTimestamp, 0, bond); - break; - } - case 1:{ - if (botUser.can_send_messages === true ){ - await bot.sendMessage(report.group_id, `*${report.username}*'s conduct due to this [message](${msgLink}) ([backup](${report.msgBackup})) violated the [rules](${rules}) for the second time and is subject to a 1 week ban.`, {parse_mode: 'Markdown'}); - } - const paroleDate = Math.ceil(+new Date() / 1000) + 604800; - if (botUser.status === "administrator" && botUser.can_restrict_members === true ){ - try{ - await bot.banChatMember(report.group_id, report.user_id, {until_date: paroleDate}); - } catch { - if (botUser.can_send_messages === true ){ - await bot.sendMessage(report.group_id, `My admin rights are limited. I am unable to ban *${report.username}* for 7 days. Please ask an admin to apply the 7 day ban.`); - } - console.log("ban error"); + history{ + timestampParole + countBrokeRulesArbitrated } - } - await setReport(db, question.id, true, true, activeTimestamp, 0, bond); - break; + }`; + const moderationInfo = `moderationInfo { + ${moderationInfoContent} + }`; +return `{ + disputesFinal: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastAppealPossible_gt: ${timestampLastUpdated}, finalRuling_not: null, moderationInfo_: {askedBy: "${botaddress}"}}) { + id + finalRuling + } + disputesAppealPossible: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastAppealPossible_gt: ${timestampLastUpdated}, finalRuling: null, moderationInfo_: {askedBy: "${botaddress}"}}) { + id + currentRuling + ${moderationInfo} + } + disputesAppeal: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastAppeal_gt: ${timestampLastUpdated}, finalRuling: null, moderationInfo_: {askedBy: "${botaddress}"}}) { + id + currentRuling + ${moderationInfo} + } + disputesCreated: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastUpdated_gt: ${timestampLastUpdated}, finalRuling: null, currentRuling: null, rulingFunded: null, moderationInfo_: {askedBy: "${botaddress}"}}) { + id + ${moderationInfo} + } + disputesAppealFunded: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastUpdated_gt: ${timestampLastUpdated}, rulingFunded_not: null, moderationInfo_: {askedBy: "${botaddress}"}}) { + id + rulingFunded + ${moderationInfo} + } + realityQuestionUnansweredFinalized: moderationInfos(first: 1000, skip: ${lastPageUpdated*1000}, where: {deadline_gt: ${timestampLastUpdated}, deadline_lt: ${timestampNew}, reality: null, askedBy: "${botaddress}"}) { + ${moderationInfoContent} + } + realityQuestionAnsweredFinalized: realityChecks(first: 1000, skip: ${lastPageUpdated*1000}, where: {deadline_gt: ${timestampLastUpdated}, deadline_lt: ${timestampNew - graphSyncingPeriod}, moderationInfo_: {askedBy: "${botaddress}"}}) { + id + currentAnswer + timeServed + ${moderationInfo} + } + realityQuestionAnsweredNotFinalized: realityChecks(first: 1000, skip: ${lastPageUpdated*1000}, where: {deadline_gt: ${timestampNew}, moderationInfo_: {askedBy: "${botaddress}"}}) { + id + currentAnswer + ${moderationInfo} + } + sheriffs: jannies(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastUpdatedSheriff_gt: ${timestampLastUpdated}, group_: {botAddress: "${botaddress}"}}) { + id + group{ + groupID } - default:{ - if (botUser.can_send_messages === true ){ - await bot.sendMessage(report.group_id, `*${report.username}*'s conduct due to this [message](${msgLink}) ([backup](${report.msgBackup})) violated the [rules](${rules}) for the third time and is subject to a permanent ban.`, {parse_mode: 'Markdown'}); - } - if (botUser.status === "administrator" && botUser.can_restrict_members === true ){ - try{ - await bot.banChatMember(report.group_id, report.user_id); - } catch { - if (botUser.can_send_messages === true ){ - await bot.sendMessage(report.group_id, `My admin rights are limited. I am unable to permaban *${report.username}*. Please ask an admin to apply the permaban.`); - } - console.log("ban error"); - } - } - await setReport(db, question.id, true, true, activeTimestamp, 0, bond); - break; + sheriff{ + userID } } - } else{ - await setReport(db, question.id, false, true, report.activeTimestamp, 0, bond); - const reportHistoryCurrent = await getCurrentRecord(db, report.platform, report.group_id, report.user_id); - if (botUser.can_send_messages === true ){ - await bot.sendMessage(report.group_id, `*${report.username}*'s conduct due to this [message](${msgLink}) ([backup](${report.msgBackup})) did not violate the [rules](${rules}).`, {parse_mode: 'Markdown'}); - } - if(reportHistoryCurrent === 0){ - const options = {can_send_messages: true, can_send_media_messages: true, can_send_polls: true, can_send_other_messages: true, can_add_web_page_previews: true, can_change_info: false, can_pin_messages: false}; - if (botUser.status === "administrator" && botUser.can_restrict_members === true ){ - try{ - await bot.restrictChatMember(report.group_id, report.user_id, options); - } catch{ - if (botUser.can_send_messages === true ){ - await bot.sendMessage(report.group_id, `My admin rights are limited. I am unable to lift any active mute on *${report.username}*. Please ask an admin to remove any mute related to this question.`); - } - console.log("unrestrict error"); - } + deputySheriffs: jannies(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastUpdatedDeputySheriff_gt: ${timestampLastUpdated}, group_: {botAddress: "${botaddress}"}}) { + id + group{ + groupID + } + deputySheriff{ + userID } - } else{ - handleCurrentTelegramUnrestrict(bot, report, reportHistoryCurrent+reportHistory); } - } -} + }`; +} \ No newline at end of file diff --git a/lib/db.ts b/lib/db.ts index aede64b..0ed78ce 100644 --- a/lib/db.ts +++ b/lib/db.ts @@ -1,60 +1,12 @@ const Database = require('better-sqlite3'); +import { groupSettings } from "../types"; export function openDb() { - const db = new Database('database.db', { verbose: console.log }); + const db = new Database('database.db'); db.pragma('journal_mode = WAL'); return db; } -const createAccount = (db: any, address: string, privateKey: string, platform: string, userId: string) => { - try{ - const stmt = db.prepare('INSERT INTO accounts (address, private_key, platform, user_id) VALUES (?, ?, ?, ?);'); - stmt.run(address, privateKey, platform, userId); - } catch(err){ - console.log("db error: createAccount"); - console.log(err); - } -} - -const questionAnswered = (db: any, questionId: string) => { - try{ - const stmt = db.prepare('SELECT COUNT(*) as total FROM reports WHERE question_id = ? AND bond_paid > 0;'); - const result = stmt.get(questionId); - return result.total > 0; - } catch(err) { - console.log("db error: quesitonAnswered"); - console.log(err); - } -} - -const setAccount = (db: any, platform: string, groupId: string, address: string) => { - try{ - const stmt = db.prepare( - `INSERT INTO groups (platform, group_id, address) - VALUES (?, ?, ?) - ON CONFLICT(platform, group_id) DO UPDATE SET - address=$address;`); - const info = stmt.run(platform, groupId, address); - } catch(err){ - console.log("db error: setAccount"); - console.log(err); - } -} - -const setPermissions = (db: any, platform: string, groupId: string, permission: boolean) => { - try{ - const stmt = db.prepare( - `INSERT INTO groups (platform, group_id, permission) - VALUES (?, ?, ?) - ON CONFLICT(platform, group_id) DO UPDATE SET - permission=?;`); - const info = stmt.run(platform, groupId, Number(permission), Number(permission)); - } catch(err) { - console.log("db error: setPermissions"); - console.log(err); - } -} - const setLang = (db: any, platform: string, groupId: string, lang: string) => { try{ const stmt = db.prepare( @@ -83,403 +35,265 @@ const setInviteURL = (db: any, platform: string, groupId: string, inviteUrl: str } } -const getGroup = (db: any, platform: string, groupId: string) => { +const setInviteURLChannel = (db: any, platform: string, groupId: string, inviteUrlChannel: string) => { try{ + console.log('yo'); const stmt = db.prepare( - `SELECT groups.address, private_key FROM accounts - LEFT JOIN groups ON groups.address = accounts.address - WHERE groups.platform = ? AND groups.group_id = ?` - ); - return stmt.get(platform, groupId); + `INSERT INTO groups (platform, group_id, invite_url_channel) + VALUES (?, ?, ?) + ON CONFLICT (platform, group_id) DO UPDATE SET + invite_url_channel = ?;`); + const info = stmt.run(platform, groupId, inviteUrlChannel, inviteUrlChannel); } catch(err) { - console.log("db error: getGroup"); + console.log("db error: setInviteURLChannel"); console.log(err); - } + } } -const getInviteURL = (db: any, platform: string, groupId: string) => { +const setChannelID = (db: any, platform: string, groupId: string, channel_id: string) => { try{ - const stmt = db.prepare('SELECT invite_url FROM groups WHERE platform = ? AND group_id = ?'); - return stmt.get(platform, groupId)?.invite_url || ''; - } catch(err){ - console.log("db error: getInviteURL"); + const stmt = db.prepare( + `INSERT INTO groups (platform, group_id, channel_id) + VALUES (?, ?, ?) + ON CONFLICT (platform, group_id) DO UPDATE SET + channel_id = ?;`); + const info = stmt.run(platform, groupId, channel_id, channel_id); + } catch(err) { + console.log("db error: set setChannelID"); console.log(err); } } -const getPermissions = (db:any, platform: string, groupId: string) => { +const dbstart = (db: any, platform: string, groupId: string) => { try{ - const stmt = db.prepare('SELECT permission FROM groups WHERE platform = ? AND group_id = ?'); - return stmt.get(platform, groupId)?.permission || ''; - } catch(err){ - console.log("db error: getPermissions"); + const stmt = db.prepare( + `INSERT INTO groups (platform, group_id) + VALUES (?, ?);`); + const info = stmt.run(platform, groupId); + } catch(err) { + console.log("db error: set dbstart"); console.log(err); } } -const getLang = (db:any, platform: string, groupId: string) => { +const dbstarted = (db: any, platform: string, groupId: string) => { try{ - const stmt = db.prepare('SELECT lang FROM groups WHERE platform = ? AND group_id = ?'); - return stmt.get(platform, groupId)?.lang || ''; - } catch(err){ - console.log("db error: getLang"); + const stmt = db.prepare( + `INSERT INTO groups (platform, group_id) + VALUES (?, ?);`); + const info = stmt.run(platform, groupId); + } catch(err) { + console.log("db error: set dbstarted"); console.log(err); } } -const setRules = (db:any, platform: string, groupId: string, rules: string, timestamp: number) => { +const setGreetingMode = (db: any, platform: string, groupId: string, greeting_mode: number) => { try{ const stmt = db.prepare( - `INSERT INTO rules (platform, group_id, rules, timestamp) - VALUES (?, ?, ?, ?);`); - const info = stmt.run(platform, groupId, rules, timestamp); + `INSERT INTO groups (platform, group_id, greeting_mode) + VALUES (?, ?, ?) + ON CONFLICT (platform, group_id) DO UPDATE SET + greeting_mode = ?;`); + const info = stmt.run(platform, groupId, greeting_mode, greeting_mode); } catch(err) { - console.log("db error: setRules"); + console.log("db error: set setGreetingMode"); console.log(err); } } -const getRule = (db:any, platform: string, groupId: string, timestamp: number) => { +const setThreadID = (db: any, platform: string, groupId: string, thread_id_rules: string, thread_id_notifications: string) => { try{ - const stmt = db.prepare(`SELECT rules - FROM rules - WHERE platform = ? and group_id = ? and timestamp < ? - ORDER BY timestamp DESC;`); - return stmt.get(platform, groupId,timestamp)?.rules || ''; - } catch(err){ - console.log("db error: getRule"); + const stmt = db.prepare( + `INSERT INTO groups (platform, group_id, thread_id_rules, thread_id_notifications) + VALUES (?, ?, ?, ?) + ON CONFLICT (platform, group_id) DO UPDATE SET + thread_id_rules = ?, thread_id_notifications = ?;`); + const info = stmt.run(platform, groupId, thread_id_rules, thread_id_notifications, thread_id_rules, thread_id_notifications); + } catch(err) { + console.log("db error: set setThreadID"); console.log(err); } } -const addReport = ( - db: any, - questionId: string, - platform: string, - groupId: string, - userId: string, - username: string, - msgId: string, - active: boolean, - msgBackup: string, - evidenceIndex: number, - bond_paid: number, - msgTimestamp: number - ) => { - try{ - const stmt = db.prepare( - `INSERT INTO reports (question_id, - platform, - group_id, - user_id, - username, - msg_id, - timestamp, - active_timestamp, - active, - timeServed, - finalized, - arbitrationRequested, - msgBackup, - evidenceIndex, - bond_paid) - VALUES (?, - ?, - ?, - ?, - ?, - ?, - ?, - ?, - ?, - ?, - 0, - 0, - ?, - ?, - ?);`); - const info = stmt.run( - questionId, - platform, - groupId, - userId, - username, - msgId, - msgTimestamp, - active? Number(Math.floor(Date.now()/1000)): 0, - 0, - Number(active), - msgBackup, - evidenceIndex, - bond_paid); - } catch(err) { - console.log("db error: addReport"); - console.log(err); - } - -} - -const getReportRequest = (db: any, platform: string, groupId: string, msgId: string) => { +const eraseThreadID = (db: any, platform: string, groupId: string) => { try{ - const stmt = db.prepare('SELECT * FROM reportRequests WHERE platform = ? AND group_id = ? AND msg_id = ?;'); - return stmt.get(platform, groupId,msgId); - } catch(err){ - console.log("db error: getReportRequest"); + const stmt = db.prepare( + `INSERT INTO groups (platform, group_id, thread_id_rules, thread_id_notifications, thread_id_welcome) + VALUES (?, ?, ?, ?) + ON CONFLICT (platform, group_id) DO UPDATE SET + thread_id_rules = ?, thread_id_notifications = ?, thread_id_welcome = ?;`); + const info = stmt.run(platform, groupId, '', '', '', '', '', ''); + } catch(err) { + console.log("db error: set eraseThreadID"); console.log(err); } } -const addReportRequest = ( - db: any, - platform: string, - groupId: string, - userId: string, - username: string, - msgId: string, - msgBackup: string, - msgRequestId: string - ) => { - try{ - const stmt = db.prepare( - `INSERT INTO reportRequests ( - platform, - group_id, - user_id, - username, - msg_id, - confirmations, - confirmed, - msgBackup, - msgRequestId) - VALUES ($platform, - ?, - ?, - ?, - ?, - 1, - 0, - ?, - ?);`); - const info = stmt.run( - platform, - groupId, - userId, - username, - msgId, - msgBackup, - msgRequestId - ); - } catch(err) { - console.log("db error: addReportRequest"); - console.log(err); - } -} - -const setReport = (db: any, questionId: string, active: boolean, finalized: boolean, activeTimestamp: number, timeServed: number, bond_paid: number) => { +const setThreadIDWelcome = (db: any, platform: string, groupId: string, thread_id_welcome: string) => { try{ const stmt = db.prepare( - 'UPDATE reports SET active = ?, finalized = ?, active_timestamp = ?, timeServed = ?, bond_paid = ? WHERE question_id = ?', - ); - const info = stmt.run(Number(active), finalized, activeTimestamp, timeServed, bond_paid, questionId); + `INSERT INTO groups (platform, group_id, thread_id_welcome) + VALUES (?, ?, ?) + ON CONFLICT (platform, group_id) DO UPDATE SET + thread_id_welcome = ?;`); + const info = stmt.run(platform, groupId, thread_id_welcome, thread_id_welcome); } catch(err) { - console.log("db error: setReport"); + console.log("db error: set setThreadIDWelcome"); console.log(err); } } -const setReportArbitration = (db: any, questionId: string, timeServed: number) => { + +const getGroup = (db: any, platform: string, groupId: string) => { try{ const stmt = db.prepare( - `UPDATE reports SET - arbitrationRequested = 1, timeServed = ?, active = 0 - WHERE question_id = ?`, - ); - const info = stmt.run(timeServed, questionId); + `SELECT groups.address, private_key FROM accounts + LEFT JOIN groups ON groups.address = accounts.address + WHERE groups.platform = ? AND groups.group_id = ?` + ); + return stmt.get(platform, groupId); } catch(err) { - console.log("db error: setReportArbitration"); + console.log("db error: getGroup"); console.log(err); - } + } } -const getDisputedReports = (db: any) => { +const getInviteURL = (db: any, platform: string, groupId: string) => { try{ - const stmt = db.prepare('SELECT * FROM reports WHERE finalized = 0;'); - return stmt.all(); + const stmt = db.prepare('SELECT invite_url FROM groups WHERE platform = ? AND group_id = ?'); + return stmt.get(platform, groupId)?.invite_url || ''; } catch(err){ - console.log("db error: getDisputedReports"); + console.log("db error: getInviteURL"); console.log(err); } } -const getDisputedReportsInfo = (db:any, platform: string, groupId: string) => { +const getInviteURLChannel = (db: any, platform: string, groupId: string) => { try{ - const stmt = db.prepare('SELECT * FROM reports WHERE finalized = 0 AND group_id = ? AND platform = ? AND bond_paid > 0'); - return stmt.all(groupId, platform); + const stmt = db.prepare('SELECT invite_url_channel FROM groups WHERE platform = ? AND group_id = ?'); + return stmt.get(platform, groupId)?.invite_url_channel || ''; } catch(err){ - console.log("db error: getDisputedReports"); + console.log("db error: getInviteURLChannel"); console.log(err); } } -const getDisputedReportsUserInfo = (db:any, platform: string, groupId: string, userId: string) => { +const getGreetingMode = (db: any, platform: string, groupId: string): boolean => { try{ - const stmt = db.prepare('SELECT * FROM reports WHERE user_id = ? AND group_id = ? AND platform = ?'); - return stmt.all(userId, groupId, platform); + const stmt = db.prepare('SELECT greeting_mode FROM groups WHERE platform = ? AND group_id = ?'); + return stmt.get(platform, groupId)?.greeting_mode === 1; } catch(err){ - console.log("db error: getDisputedReportsUserInfo"); + console.log("db error: getGreetingMode"); console.log(err); } } -const getConcurrentReports = (db: any, platform: string, groupId: string, userId: string, timestamp: number) => { +const getChannelID = (db: any, platform: string, groupId: string): string => { try{ - const stmt = db.prepare('SELECT question_id, msg_id, group_id, timestamp FROM reports WHERE timestamp BETWEEN ? AND ? AND user_id = ? AND group_id = ? AND platform = ?'); - return stmt.all(timestamp - 3600, timestamp + 3600, userId, groupId, platform); + const stmt = db.prepare('SELECT channel_id FROM groups WHERE platform = ? AND group_id = ?'); + return stmt.get(platform, groupId)?.channel_id; } catch(err){ - console.log("db error: getConcurrentReports"); + console.log("db error: getChannelID"); console.log(err); } } -const getQuestionId = (db: any, platform: string, groupId: string, userId: string, msgId: string) => { +const getGroupSettings = (db: any, platform: string, groupId: string): groupSettings => { try{ - const stmt = db.prepare(`SELECT question_id FROM reports WHERE platform = ? AND group_id = ? AND user_id = ? AND msg_id = ?`); - return stmt.get(platform, groupId, userId, msgId)?.question_id || ''; - } catch{ - console.log("db error: getQuestionId"); + const stmt = db.prepare('SELECT * FROM groups WHERE platform = ? AND group_id = ?'); + return stmt.get(platform, groupId); + } catch(err){ + console.log("db error: getGroupSettings"); + console.log(err); } } -const getAllowance = (db: any, platform: string, groupId: string, userId: string): Promise<{report_allowance: number, evidence_allowance: number, timestamp_refresh: number, question_id_last: string, timestamp_last_question: number} | undefined> => { +const getThreadIDRules = (db: any, platform: string, groupId: string) => { try{ - const stmt = db.prepare('SELECT report_allowance, evidence_allowance, timestamp_refresh, question_id_last, timestamp_last_question FROM allowance WHERE user_id = ? AND group_id = ? AND platform = ?'); - return stmt.all(userId, groupId, platform); - } catch{ - console.log("db error: getAllowance"); + const stmt = db.prepare('SELECT thread_id_rules FROM groups WHERE platform = ? AND group_id = ?'); + return stmt.get(platform, groupId)?.thread_id_rules || ''; + } catch(err){ + console.log("db error: getThreadIDRules"); + console.log(err); } } -const setAllowanceAsked = ( - db: any, - questionIdLast: string, - platform: string, - groupId: string, - userId: string) => { - try{ - const stmt = db.prepare('UPDATE allowance SET question_id_last = ?, timestamp_last_question = ? WHERE platform = ? AND group_id = ? AND user_id = ?'); - const info = stmt.run(questionIdLast, Math.floor(Date.now()/1000), platform, groupId, userId); - } catch { - console.log("db error: setAllowanceAsked"); - } -} - -const setAllowance = async( - db: any, - platform: string, - groupId: string, - userId: string, - reportAllowance: number, - evidenceAllowance: number, - timeRefresh: number - ) => { - try{ - const stmt = db.prepare( - `INSERT INTO allowance (platform, group_id, user_id, report_allowance, evidence_allowance, timestamp_refresh) - VALUES ($platform, $group_id, $user_id, $report_allowance, $evidence_allowance, $timestamp_refresh) - ON CONFLICT(platform, group_id, user_id) DO UPDATE SET - report_allowance=$report_allowance, evidence_allowance = $evidence_allowance, timestamp_refresh = $timestamp_refresh;` - ); - const info = stmt.run(platform, groupId, userId, reportAllowance, evidenceAllowance, timeRefresh); - } catch { - console.log("db error: setAllowance"); - } +const getThreadIDWelcome = (db: any, platform: string, groupId: string) => { + try{ + const stmt = db.prepare('SELECT thread_id_welcome FROM groups WHERE platform = ? AND group_id = ?'); + return stmt.get(platform, groupId)?.thread_id_welcome || ''; + } catch(err){ + console.log("db error: getThreadIDWelcome"); + console.log(err); + } } -const getActiveEvidenceGroupId = (db: any, platform: string, groupId: string, evidenceIndex: number) => { +const getThreadIDNotifications = (db: any, platform: string, groupId: string) => { try{ - const stmt = db.prepare( `SELECT question_id FROM reports WHERE platform = ? AND group_id = ? AND evidenceIndex = ? AND finalized = 0`); - return stmt.get(platform, groupId, evidenceIndex); - } catch(err) { - console.log("db error: getActiveEvidenceGroupId"); + const stmt = db.prepare('SELECT thread_id_notifications FROM groups WHERE platform = ? AND group_id = ?'); + return stmt.get(platform, groupId)?.thread_id_notifications || ''; + } catch(err){ + console.log("db error: getThreadIDNotifications"); console.log(err); } -} +} -const getFinalRecord = (db: any, platform: string, groupId: string, userId: string) => { +const getLang = (db:any, platform: string, groupId: string): string => { try{ - const stmt = db.prepare( - `SELECT COUNT(*) as total FROM reports - WHERE active = TRUE - AND finalized = TRUE - AND platform = ? - AND group_id = ? - AND user_id = ?` - ); - return stmt.get(platform, groupId, userId)?.total || 0; - } catch(err) { - console.log("db error: getFinalRecord"); + const stmt = db.prepare('SELECT lang FROM groups WHERE platform = ? AND group_id = ?'); + return stmt.get(platform, groupId)?.lang; + } catch(err){ + console.log("db error: getLang"); console.log(err); } } -const getRecordCount = async(db: any, platform: string, groupId: string) => { +const setRules = (db:any, platform: string, groupId: string, rules: string, timestamp: number) => { try{ - const stmt = db.prepare( - `SELECT COUNT(*) as total FROM reports - WHERE platform = ? AND group_id = ?` - ); - return stmt.get(platform, groupId)?.total || 0; + const stmt = db.prepare( + `INSERT INTO rules (platform, group_id, rules, timestamp) + VALUES (?, ?, ?, ?);`); + const info = stmt.run(platform, groupId, rules, timestamp); } catch(err) { - console.log("db error: getRecordCount"); + console.log("db error: setRules"); console.log(err); } } -const getCurrentRecord = async(db: any, platform: string, groupId: string, userId: string) => { + +const getRule = (db:any, platform: string, groupId: string, timestamp: number): string => { try{ - const stmt = db.prepare( - `SELECT COUNT(*) as total FROM reports - WHERE active = TRUE - AND platform = $platform - AND finalized = 0 - AND group_id = $group_id - AND user_id = $user_id` - ); - return stmt.get(platform, groupId, userId)?.total || 0; - } catch(err) { - console.log("db error: getRecordCount"); - console.log(err); + const stmt = db.prepare(`SELECT rules + FROM rules + WHERE platform = ? and group_id = ? and timestamp < ? + ORDER BY timestamp DESC;`); + return stmt.get(platform, groupId,timestamp)?.rules; + } catch(err){ + console.log("db error: getRule " + err); } } export { getInviteURL, - getQuestionId, setInviteURL, - setAccount, - getRecordCount, + getInviteURLChannel, + setInviteURLChannel, + getThreadIDWelcome, + getGroupSettings, + setThreadIDWelcome, + setChannelID, + getChannelID, + dbstart, + dbstarted, + getGreetingMode, + eraseThreadID, + setGreetingMode, setLang, getLang, - getGroup, - getActiveEvidenceGroupId, - createAccount, setRules, - getReportRequest, - addReportRequest, - setAllowanceAsked, - questionAnswered, - getPermissions, - getAllowance, - setAllowance, - setPermissions, - getRule, - addReport, - setReport, - getDisputedReports, - getDisputedReportsUserInfo, - getDisputedReportsInfo, - getConcurrentReports, - getFinalRecord, - getCurrentRecord, - setReportArbitration + setThreadID, + getThreadIDNotifications, + getThreadIDRules, + getRule } diff --git a/lib/graph.ts b/lib/graph.ts new file mode 100644 index 0000000..ad0d439 --- /dev/null +++ b/lib/graph.ts @@ -0,0 +1,39 @@ +import request from "graphql-request"; + +const getQuestionId = async (botAddress: string, platform: string, groupId: string, userId: string, msgId: string): Promise => { + const query = `{ + moderationInfos(where: {message: "https://t.me/c/${groupId.substring(4)}/${msgId}",user_: {id:"${botAddress}${platform}${userId}", group: "${botAddress}Telegram${groupId}"}}) { + id + } + }`; + try{ + const result = await request( + 'https://api.thegraph.com/subgraphs/name/shotaronowhere/kleros-moderate-goerli', + query + ); + console.log(result) + return (result)?.data?.moderationInfos[0]?.id; + } catch(e){ + console.log(e) + return undefined + } +} + +const existsQuestionId = async (question_id: string): Promise => { + const query = `{ + moderationInfos(where: {id: "${question_id}"}){ + id + } + }`; + try{ + return (await request( + 'https://api.thegraph.com/subgraphs/name/shotaronowhere/kleros-moderate-goerli', + query + ))?.data.moderationInfos.length === 1; + } catch(e){ + console.log(e) + return undefined + } +} + +export{getQuestionId, existsQuestionId} \ No newline at end of file diff --git a/package.json b/package.json index aec8058..0ce3ee4 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,8 @@ "main": "index.js", "license": "MIT", "dependencies": { + "@aws-sdk/client-dynamodb": "^3.210.0", + "@aws-sdk/lib-dynamodb": "^3.210.0", "@graphprotocol/graph-cli": "^0.25.1", "@graphprotocol/graph-ts": "^0.27.0", "@types/node-telegram-bot-api": "^0.57.1", @@ -14,7 +16,7 @@ "graphql-request": "^3.7.0", "markdown-escape": "^1.1.0", "node-fetch": "2", - "node-telegram-bot-api": "^0.58.0", + "node-telegram-bot-api": "^0.60.0", "pm2": "^5.2.0", "sqlite": "^4.0.23", "sqlite3": "^5.0.2", @@ -30,8 +32,11 @@ }, "scripts": { "start-telegram-bot": "npx ts-node lib/telegram/index.ts", + "start-telegram-bot-prod": "node lib/telegram/index.js", "create-db": "npx ts-node lib/create-db.ts", "cron": "npx ts-node lib/cron.ts", + "cron-prod": "node lib/cron.js", + "build": "npx tsc lib/telegram/index.ts lib/cron.ts --resolveJsonModule --esModuleInterop", "typechain:build": "npx typechain --target ethers-v5 --out-dir lib/typechain lib/abi/*.json", "graph:codegen": "cd subgraph && graph codegen", "graph:build": "cd subgraph && graph build", From 97877e0a248b09d919352011c0ccb5274e6df03a Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Sun, 20 Nov 2022 21:01:02 -0800 Subject: [PATCH 002/111] feat(subgraph): moderation indexing --- subgraph/abis/KlerosLiquid.json | 746 ++++++++++++++++++ subgraph/schema.graphql | 143 ++-- subgraph/src/KlerosLiquid.ts | 45 ++ .../Realitio_v2_1_ArbitratorWithAppeals.ts | 113 ++- subgraph/src/reality-ethv-30.ts | 347 ++++---- subgraph/subgraph.yaml | 84 +- 6 files changed, 1129 insertions(+), 349 deletions(-) create mode 100644 subgraph/abis/KlerosLiquid.json create mode 100644 subgraph/src/KlerosLiquid.ts diff --git a/subgraph/abis/KlerosLiquid.json b/subgraph/abis/KlerosLiquid.json new file mode 100644 index 0000000..48b56c0 --- /dev/null +++ b/subgraph/abis/KlerosLiquid.json @@ -0,0 +1,746 @@ +[ + { + "constant": false, + "inputs": [{ "name": "_pinakion", "type": "address" }], + "name": "changePinakion", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "RNBlock", + "outputs": [{ "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "disputesWithoutJurors", + "outputs": [{ "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "passPhase", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "governor", + "outputs": [{ "name": "", "type": "address" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "lastDelayedSetStake", + "outputs": [{ "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [{ "name": "_disputeID", "type": "uint256" }], + "name": "disputeStatus", + "outputs": [{ "name": "status", "type": "uint8" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [{ "name": "_disputeID", "type": "uint256" }], + "name": "passPeriod", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "maxDrawingTime", + "outputs": [{ "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [{ "name": "_disputeID", "type": "uint256" }], + "name": "currentRuling", + "outputs": [{ "name": "ruling", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [{ "name": "", "type": "uint256" }], + "name": "courts", + "outputs": [ + { "name": "parent", "type": "uint96" }, + { "name": "hiddenVotes", "type": "bool" }, + { "name": "minStake", "type": "uint256" }, + { "name": "alpha", "type": "uint256" }, + { "name": "feeForJuror", "type": "uint256" }, + { "name": "jurorsForCourtJump", "type": "uint256" } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "_disputeID", "type": "uint256" }, + { "name": "_appeal", "type": "uint256" }, + { "name": "_iterations", "type": "uint256" } + ], + "name": "execute", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "ALPHA_DIVISOR", + "outputs": [{ "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "_disputeID", "type": "uint256" }, + { "name": "_voteIDs", "type": "uint256[]" }, + { "name": "_choice", "type": "uint256" }, + { "name": "_salt", "type": "uint256" } + ], + "name": "castVote", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "_subcourtID", "type": "uint96" }, + { "name": "_minStake", "type": "uint256" } + ], + "name": "changeSubcourtMinStake", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [{ "name": "_subcourtID", "type": "uint96" }], + "name": "getSubcourt", + "outputs": [ + { "name": "children", "type": "uint256[]" }, + { "name": "timesPerPeriod", "type": "uint256[4]" } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "_disputeID", "type": "uint256" }, + { "name": "_extraData", "type": "bytes" } + ], + "name": "appeal", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "_from", "type": "address" }, + { "name": "_to", "type": "address" }, + { "name": "_amount", "type": "uint256" } + ], + "name": "onTransfer", + "outputs": [{ "name": "allowed", "type": "bool" }], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [{ "name": "", "type": "uint256" }], + "name": "disputes", + "outputs": [ + { "name": "subcourtID", "type": "uint96" }, + { "name": "arbitrated", "type": "address" }, + { "name": "numberOfChoices", "type": "uint256" }, + { "name": "period", "type": "uint8" }, + { "name": "lastPeriodChange", "type": "uint256" }, + { "name": "drawsInRound", "type": "uint256" }, + { "name": "commitsInRound", "type": "uint256" }, + { "name": "ruled", "type": "bool" } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "_subcourtID", "type": "uint96" }, + { "name": "_timesPerPeriod", "type": "uint256[4]" } + ], + "name": "changeSubcourtTimesPerPeriod", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "_subcourtID", "type": "uint96" }, + { "name": "_feeForJuror", "type": "uint256" } + ], + "name": "changeSubcourtJurorFee", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "_subcourtID", "type": "uint96" }, + { "name": "_alpha", "type": "uint256" } + ], + "name": "changeSubcourtAlpha", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "_disputeID", "type": "uint256" }, + { "name": "_voteIDs", "type": "uint256[]" }, + { "name": "_commit", "type": "bytes32" } + ], + "name": "castCommit", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "RN", + "outputs": [{ "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "RNGenerator", + "outputs": [{ "name": "", "type": "address" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "_destination", "type": "address" }, + { "name": "_amount", "type": "uint256" }, + { "name": "_data", "type": "bytes" } + ], + "name": "executeGovernorProposal", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [{ "name": "_minStakingTime", "type": "uint256" }], + "name": "changeMinStakingTime", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "NON_PAYABLE_AMOUNT", + "outputs": [{ "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "_subcourtID", "type": "uint96" }, + { "name": "_stake", "type": "uint128" } + ], + "name": "setStake", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [{ "name": "_disputeID", "type": "uint256" }], + "name": "executeRuling", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { "name": "_disputeID", "type": "uint256" }, + { "name": "_appeal", "type": "uint256" }, + { "name": "_voteID", "type": "uint256" } + ], + "name": "getVote", + "outputs": [ + { "name": "account", "type": "address" }, + { "name": "commit", "type": "bytes32" }, + { "name": "choice", "type": "uint256" }, + { "name": "voted", "type": "bool" } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [{ "name": "_RNGenerator", "type": "address" }], + "name": "changeRNGenerator", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [{ "name": "_iterations", "type": "uint256" }], + "name": "executeDelayedSetStakes", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { "name": "_account", "type": "address" }, + { "name": "_subcourtID", "type": "uint96" } + ], + "name": "stakeOf", + "outputs": [{ "name": "stake", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "_subcourtID", "type": "uint96" }, + { "name": "_jurorsForCourtJump", "type": "uint256" } + ], + "name": "changeSubcourtJurorsForJump", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [{ "name": "_disputeID", "type": "uint256" }], + "name": "appealPeriod", + "outputs": [ + { "name": "start", "type": "uint256" }, + { "name": "end", "type": "uint256" } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "phase", + "outputs": [{ "name": "", "type": "uint8" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_STAKE_PATHS", + "outputs": [{ "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [{ "name": "", "type": "uint256" }], + "name": "delayedSetStakes", + "outputs": [ + { "name": "account", "type": "address" }, + { "name": "subcourtID", "type": "uint96" }, + { "name": "stake", "type": "uint128" } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "lastPhaseChange", + "outputs": [{ "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "minStakingTime", + "outputs": [{ "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "nextDelayedSetStake", + "outputs": [{ "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "_numberOfChoices", "type": "uint256" }, + { "name": "_extraData", "type": "bytes" } + ], + "name": "createDispute", + "outputs": [{ "name": "disputeID", "type": "uint256" }], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "_disputeID", "type": "uint256" }, + { "name": "_iterations", "type": "uint256" } + ], + "name": "drawJurors", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "_parent", "type": "uint96" }, + { "name": "_hiddenVotes", "type": "bool" }, + { "name": "_minStake", "type": "uint256" }, + { "name": "_alpha", "type": "uint256" }, + { "name": "_feeForJuror", "type": "uint256" }, + { "name": "_jurorsForCourtJump", "type": "uint256" }, + { "name": "_timesPerPeriod", "type": "uint256[4]" }, + { "name": "_sortitionSumTreeK", "type": "uint256" } + ], + "name": "createSubcourt", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [{ "name": "_account", "type": "address" }], + "name": "getJuror", + "outputs": [{ "name": "subcourtIDs", "type": "uint96[]" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "_owner", "type": "address" }, + { "name": "_spender", "type": "address" }, + { "name": "_amount", "type": "uint256" } + ], + "name": "onApprove", + "outputs": [{ "name": "allowed", "type": "bool" }], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [{ "name": "", "type": "address" }], + "name": "jurors", + "outputs": [ + { "name": "stakedTokens", "type": "uint256" }, + { "name": "lockedTokens", "type": "uint256" } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [{ "name": "_maxDrawingTime", "type": "uint256" }], + "name": "changeMaxDrawingTime", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [{ "name": "_disputeID", "type": "uint256" }], + "name": "getDispute", + "outputs": [ + { "name": "votesLengths", "type": "uint256[]" }, + { "name": "tokensAtStakePerJuror", "type": "uint256[]" }, + { "name": "totalFeesForJurors", "type": "uint256[]" }, + { "name": "votesInEachRound", "type": "uint256[]" }, + { "name": "repartitionsInEachRound", "type": "uint256[]" }, + { "name": "penaltiesInEachRound", "type": "uint256[]" } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { "name": "_disputeID", "type": "uint256" }, + { "name": "_appeal", "type": "uint256" } + ], + "name": "getVoteCounter", + "outputs": [ + { "name": "winningChoice", "type": "uint256" }, + { "name": "counts", "type": "uint256[]" }, + { "name": "tied", "type": "bool" } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [{ "name": "_governor", "type": "address" }], + "name": "changeGovernor", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_JURORS", + "outputs": [{ "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { "name": "_disputeID", "type": "uint256" }, + { "name": "_extraData", "type": "bytes" } + ], + "name": "appealCost", + "outputs": [{ "name": "cost", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [{ "name": "_owner", "type": "address" }], + "name": "proxyPayment", + "outputs": [{ "name": "allowed", "type": "bool" }], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "lockInsolventTransfers", + "outputs": [{ "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [{ "name": "_extraData", "type": "bytes" }], + "name": "arbitrationCost", + "outputs": [{ "name": "cost", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "pinakion", + "outputs": [{ "name": "", "type": "address" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "name": "_governor", "type": "address" }, + { "name": "_pinakion", "type": "address" }, + { "name": "_RNGenerator", "type": "address" }, + { "name": "_minStakingTime", "type": "uint256" }, + { "name": "_maxDrawingTime", "type": "uint256" }, + { "name": "_hiddenVotes", "type": "bool" }, + { "name": "_minStake", "type": "uint256" }, + { "name": "_alpha", "type": "uint256" }, + { "name": "_feeForJuror", "type": "uint256" }, + { "name": "_jurorsForCourtJump", "type": "uint256" }, + { "name": "_timesPerPeriod", "type": "uint256[4]" }, + { "name": "_sortitionSumTreeK", "type": "uint256" } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "name": "_phase", "type": "uint8" }], + "name": "NewPhase", + "type": "event", + "_alias": "NewPhase" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "_disputeID", "type": "uint256" }, + { "indexed": false, "name": "_period", "type": "uint8" } + ], + "name": "NewPeriod", + "type": "event", + "_alias": "NewPeriod" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "_address", "type": "address" }, + { "indexed": false, "name": "_subcourtID", "type": "uint256" }, + { "indexed": false, "name": "_stake", "type": "uint128" }, + { "indexed": false, "name": "_newTotalStake", "type": "uint256" } + ], + "name": "StakeSet", + "type": "event", + "_alias": "StakeSet" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "_address", "type": "address" }, + { "indexed": true, "name": "_disputeID", "type": "uint256" }, + { "indexed": false, "name": "_appeal", "type": "uint256" }, + { "indexed": false, "name": "_voteID", "type": "uint256" } + ], + "name": "Draw", + "type": "event", + "_alias": "Draw" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "_address", "type": "address" }, + { "indexed": true, "name": "_disputeID", "type": "uint256" }, + { "indexed": false, "name": "_tokenAmount", "type": "int256" }, + { "indexed": false, "name": "_ETHAmount", "type": "int256" } + ], + "name": "TokenAndETHShift", + "type": "event", + "_alias": "TokenAndETHShift" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "_disputeID", "type": "uint256" }, + { "indexed": true, "name": "_arbitrable", "type": "address" } + ], + "name": "DisputeCreation", + "type": "event", + "_alias": "DisputeCreation" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "_disputeID", "type": "uint256" }, + { "indexed": true, "name": "_arbitrable", "type": "address" } + ], + "name": "AppealPossible", + "type": "event", + "_alias": "AppealPossible" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "_disputeID", "type": "uint256" }, + { "indexed": true, "name": "_arbitrable", "type": "address" } + ], + "name": "AppealDecision", + "type": "event", + "_alias": "AppealDecision" + } + ] + \ No newline at end of file diff --git a/subgraph/schema.graphql b/subgraph/schema.graphql index 64aa2f4..d09e02e 100644 --- a/subgraph/schema.graphql +++ b/subgraph/schema.graphql @@ -1,91 +1,86 @@ -type Question @entity { +type ModerationDispute @entity{ id: ID! - timeout: BigInt! - finalize_ts: BigInt - bond: BigInt - user: User! - rulesUrl: String - message: String - messageBackup: String - askedBy: Bytes - answer: Bytes - arbitrationRequested: Boolean - appeals: BigInt - ruling: BigInt - disputeId: BigInt + timestampLastUpdated: BigInt! + timestampLastRound: BigInt + timestampLastAppeal: BigInt + timestampLastAppealPossible: BigInt + rulingFunded: BigInt + currentRuling: BigInt + finalRuling: BigInt + moderationInfo: ModerationInfo! } -type User @entity{ +type ModerationInfo @entity(immutable: true){ id: ID! - username: String - userID: String - group: Group! - questions: [Question!]! @derivedFrom(field: "user") + moderationType: BigInt! + rulesUrl: String! + message: String! + messageBackup: String! + reportedBy: User! + askedBy: Bytes! + deadline: BigInt + timeout: BigInt! + user: User! + dispute: ModerationDispute @derivedFrom(field: "moderationInfo") + reality: RealityCheck } -type Group @entity{ +type RealityCheck @entity{ id: ID! - name: String - platform: String! - groupID: String! - users: [User!]! @derivedFrom(field: "group") -} - -type Contribution @entity { - id: ID! - _localDisputeID: BigInt! # uint256 - _round: BigInt! # uint256 - ruling: BigInt! # uint256 - _contributor: Bytes! # address - _amount: BigInt! # uint256 -} - -type Dispute @entity { - id: ID! - _arbitrator: Bytes! # address - _disputeID: BigInt! # uint256 - _metaEvidenceID: BigInt! # uint256 - _evidenceGroupID: BigInt! # uint256 -} - -type DisputeIDToQuestionID @entity { - id: ID! - _questionID: String! # bytes32 + currentAnswer: Bytes + deadline: BigInt! + timeServed: BigInt + blocknumberLastUpdated: BigInt + timestampLastUpdated: BigInt + moderationInfo: ModerationInfo! @derivedFrom(field: "reality") } -type Evidence @entity { - id: ID! - _arbitrator: Bytes! # address - _evidenceGroupID: BigInt! # uint256 - _party: Bytes! # address - _evidence: String! # string +type UserHistory @entity{ + id: ID! + user: User! + timestampLastUpdated: BigInt! + timestampParole: BigInt! + countBrokeRulesOptimisticAndArbitrated: Int! + countBrokeRulesArbitrated: Int! + countReportsMade: Int! + countReportsMadeAndResponded: Int! + timestampLastReport: BigInt! } -type MetaEvidence @entity { - id: ID! - _metaEvidenceID: BigInt! # uint256 - _evidence: String! # string +type User @entity(immutable: true){ + id: ID! + username: String + userID: String! + group: Group! + history: UserHistory @derivedFrom(field: "user") + moderation: [ModerationInfo!]! @derivedFrom(field: "user") } -type Ruling @entity { - id: ID! - _arbitrator: Bytes! # address - _disputeID: BigInt! # uint256 - _ruling: BigInt! # uint256 +type Janny @entity{ + id: ID! + group: Group! + blocknumberLastUpdatedSheriff: BigInt + blocknumberLastUpdatedDeputySheriff: BigInt + timestampLastUpdatedSheriff: BigInt + timestampLastUpdatedDeputySheriff: BigInt + sheriff: User + deputySheriff: User } -type RulingFunded @entity { - id: ID! - _localDisputeID: BigInt! # uint256 - _round: BigInt! # uint256 - _ruling: BigInt! # uint256 +type Group @entity(immutable: true){ + id: ID! + name: String + platform: String! + groupID: String! + botAddress: Bytes! + users: [User!]! @derivedFrom(field: "group") } -type Withdrawal @entity { - id: ID! - _localDisputeID: BigInt! # uint256 - _round: BigInt! # uint256 - _ruling: BigInt! # uint256 - _contributor: Bytes! # address - _reward: BigInt! # uint256 -} +type Group @entity(immutable: true){ + id: ID! + name: String + platform: String! + groupID: String! + botAddress: Bytes! + users: [User!]! @derivedFrom(field: "group") +} \ No newline at end of file diff --git a/subgraph/src/KlerosLiquid.ts b/subgraph/src/KlerosLiquid.ts new file mode 100644 index 0000000..bdebd0c --- /dev/null +++ b/subgraph/src/KlerosLiquid.ts @@ -0,0 +1,45 @@ +import { + AppealPossible as AppealPossibleEvent, + AppealDecision as AppealDecisionEvent, + KlerosLiquid + } from "../generated/KlerosLiquid/KlerosLiquid" + import { + ModerationDispute + } from "../generated/schema" + import { BigInt, log, Address, JSONValueKind, ByteArray } from "@graphprotocol/graph-ts" + + export function handleAppealPossible(event: AppealPossibleEvent): void { + const dispute = ModerationDispute.load(event.params._disputeID.toHexString()) + if (!dispute){ + log.error("Disput not found {}.", [event.params._disputeID.toHexString()]) + return; + } + + let currentRuling = getCurrentRulling(event.params._disputeID, event.address) + dispute.currentRuling = getCurrentRulling(event.params._disputeID, event.address) + dispute.timestampLastAppealPossible = event.block.timestamp + dispute.save() +} + +export function handleAppealDecision(event: AppealDecisionEvent): void { + const dispute = ModerationDispute.load(event.params._disputeID.toHexString()) + if (!dispute){ + log.error("Disput not found {}.", [event.params._disputeID.toHexString()]) + return; + } + dispute.timestampLastAppealPossible = event.block.timestamp + dispute.save() +} + + +function getCurrentRulling(disputeID: BigInt, address: Address): BigInt | null { + log.debug("getCurrentRulling: Asking current rulling in dispute {}", [disputeID.toString()]) + let contract = KlerosLiquid.bind(address) + let callResult = contract.try_currentRuling(disputeID) + if (callResult.reverted) { + log.debug("getCurrentRulling: currentRulling reverted {}.", [disputeID.toHexString()]) + return null + } else { + return callResult.value + } + } \ No newline at end of file diff --git a/subgraph/src/Realitio_v2_1_ArbitratorWithAppeals.ts b/subgraph/src/Realitio_v2_1_ArbitratorWithAppeals.ts index 800534b..9b1faf1 100644 --- a/subgraph/src/Realitio_v2_1_ArbitratorWithAppeals.ts +++ b/subgraph/src/Realitio_v2_1_ArbitratorWithAppeals.ts @@ -1,81 +1,68 @@ import { - Contribution as ContributionEvent, - Dispute as DisputeEvent, DisputeIDToQuestionID as DisputeIDToQuestionIDEvent, - Evidence as EvidenceEvent, - MetaEvidence as MetaEvidenceEvent, - Ruling as RulingEvent, RulingFunded as RulingFundedEvent, - Withdrawal as WithdrawalEvent - } from "../generated/Contract/Contract" - import { - Ruling, - Question, - DisputeIDToQuestionID + Ruling as RulingEvent + } from "../generated/Realitio_v2_1_ArbitratorWithAppeals/Realitio_v2_1_ArbitratorWithAppeals" +import { + ModerationDispute, ModerationInfo, UserHistory, } from "../generated/schema" - import { BigInt, log } from "@graphprotocol/graph-ts" - - - export function handleContribution(event: ContributionEvent): void { - - } - - export function handleDispute(event: DisputeEvent): void { - } + import { log, Bytes, BigInt } from "@graphprotocol/graph-ts" export function handleDisputeIDToQuestionID( event: DisputeIDToQuestionIDEvent ): void { - let question = Question.load(event.params._questionID.toHexString()); - - if (question === null) { - log.error(`handleSubmitAnswerByArbitrator: question ${event.params._questionID.toHexString()} not found`, []) - return; - } - question.disputeId = event.params._disputeID; - question.save(); - - let entity = new DisputeIDToQuestionID(event.params._disputeID.toHexString()); - - entity._questionID = event.params._questionID.toHexString(); - entity.save(); - } - - export function handleEvidence(event: EvidenceEvent): void { + const moderationDispute = new ModerationDispute(event.params._disputeID.toHexString()); + moderationDispute.moderationInfo = event.params._questionID.toHexString() + moderationDispute.timestampLastUpdated = event.block.timestamp + moderationDispute.save(); } - - export function handleMetaEvidence(event: MetaEvidenceEvent): void { - } - + export function handleRuling(event: RulingEvent): void { - let entity = DisputeIDToQuestionID.load( - event.params._disputeID.toHexString() - ) - if (entity === null) { - log.error(`dispute ${event.params._disputeID.toHexString()} not found`, []) + const moderationDispute = ModerationDispute.load(event.params._disputeID.toHexString()); + if (!moderationDispute){ + log.error('Moderation Dispute not found. {}',[event.params._disputeID.toHexString()]); return; } - let question = Question.load(entity._questionID); - - if (question === null) { - log.error(`question ${entity._questionID} not found`, []) + moderationDispute.finalRuling = event.params._ruling + moderationDispute.save() + + const modinfo = ModerationInfo.load(moderationDispute.moderationInfo) + if (!modinfo){ + log.error("ModerationInfo not found {}.", [moderationDispute.moderationInfo]); return; } - question.ruling = event.params._ruling; - question.save(); + const userHistory = UserHistory.load(modinfo.user) + if (!userHistory){ + log.error("UserHistory not found {}.", [modinfo.user]); + return; + } + + if (event.params._ruling.equals(BigInt.fromU32(1))){ + userHistory.countBrokeRulesOptimisticAndArbitrated++ + userHistory.countBrokeRulesArbitrated++ + userHistory.timestampLastUpdated = event.block.timestamp + if(userHistory.countBrokeRulesOptimisticAndArbitrated === 1) + userHistory.timestampParole = event.block.timestamp.plus(BigInt.fromU32(86400)) + if(userHistory.countBrokeRulesOptimisticAndArbitrated === 2) + userHistory.timestampParole = event.block.timestamp.ge(userHistory.timestampParole) ? event.block.timestamp.plus(BigInt.fromU32(604800)) : userHistory.timestampParole.plus(BigInt.fromU32(604800)) + } + userHistory.save() } - // appeal funding + export function handleRulingFunded(event: RulingFundedEvent): void { - let question = Question.load(event.params._localDisputeID.toHexString()); - - if (question === null) { - log.error(`handleRulingFunded: question ${event.params._localDisputeID.toHexString()} not found`, []) + let moderationInfo = ModerationInfo.load(event.params._localDisputeID.toHexString()); + if (!moderationInfo){ + log.error('Moderation Info not found {}.',[event.params._localDisputeID.toHexString()]); return; } - question.appeals = event.params._round; - question.save(); - } - - export function handleWithdrawal(event: WithdrawalEvent): void { - } - \ No newline at end of file + const dispute = moderationInfo.dispute + const dispute_non_null = dispute ? dispute : 'no-dispute'; + const moderationDispute = ModerationDispute.load(dispute_non_null); + if (!moderationDispute){ + log.error('Moderation Dispute not found {}.',[]) + return; + } + moderationDispute.rulingFunded = event.params._ruling + moderationDispute.timestampLastRound = event.block.timestamp + moderationDispute.save(); + } \ No newline at end of file diff --git a/subgraph/src/reality-ethv-30.ts b/subgraph/src/reality-ethv-30.ts index 913f9c4..e60c621 100644 --- a/subgraph/src/reality-ethv-30.ts +++ b/subgraph/src/reality-ethv-30.ts @@ -1,187 +1,214 @@ -import { BigInt, log } from "@graphprotocol/graph-ts" import { - RealityETHV30, - LogAnswerReveal, - LogCancelArbitration, - LogClaim, - LogFinalize, - LogFundAnswerBounty, - LogMinimumBond, - LogNewAnswer, LogNewQuestion, - LogNewTemplate, + LogNewAnswer, LogNotifyOfArbitrationRequest, - LogReopenQuestion, - LogSetQuestionFee, - LogWithdraw, + RealityETHV30 } from "../generated/RealityETHV30/RealityETHV30" -import { Question, User, Group } from "../generated/schema" - -/* -export function handleLogAnswerReveal(event: LogAnswerReveal): void { - // Entities can be loaded from the store using a string ID; this ID - // needs to be unique across all entities of the same type - let entity = ExampleEntity.load(event.transaction.from.toHex()) - - // Entities only exist after they have been saved to the store; - // `null` checks allow to create entities on demand - if (!entity) { - entity = new ExampleEntity(event.transaction.from.toHex()) - - // Entity fields can be set using simple assignments - entity.count = BigInt.fromI32(0) +import { ModerationInfo, User, Group, UserHistory, RealityCheck, Janny } from "../generated/schema" +import { Bytes, log, BigInt } from "@graphprotocol/graph-ts" + +export function handleLogNotifyOfArbitrationRequest(event: LogNotifyOfArbitrationRequest): void { + const moderationInfo = ModerationInfo.load(event.params.question_id.toHexString()) + if (!moderationInfo){ + log.error('moderation info not found. {}',[event.params.question_id.toHexString()]) + return } - - // BigInt and BigDecimal math are supported - entity.count = entity.count + BigInt.fromI32(1) - - // Entity fields can be set based on event parameters - entity.question_id = event.params.question_id - entity.user = event.params.user - - // Entities can be written to the store with `.save()` - entity.save() - - // Note: If a handler doesn't require existing field values, it is faster - // _not_ to load the entity from the store. Instead, create it fresh with - // `new Entity(...)`, set the fields that should be updated and save the - // entity back to the store. Fields that were not set or unset remain - // unchanged, allowing for partial updates to be applied. - - // It is also possible to access smart contracts from mappings. For - // example, the contract that has emitted the event can be connected to - // with: - // - // let contract = Contract.bind(event.address) - // - // The following functions can then be called on this contract to access - // state variables and other data: - // - // - contract.arbitrator_question_fees(...) - // - contract.balanceOf(...) - // - contract.commitments(...) - // - contract.createTemplate(...) - // - contract.getArbitrator(...) - // - contract.getBestAnswer(...) - // - contract.getBond(...) - // - contract.getBounty(...) - // - contract.getContentHash(...) - // - contract.getFinalAnswer(...) - // - contract.getFinalAnswerIfMatches(...) - // - contract.getFinalizeTS(...) - // - contract.getHistoryHash(...) - // - contract.getMinBond(...) - // - contract.getOpeningTS(...) - // - contract.getTimeout(...) - // - contract.isFinalized(...) - // - contract.isPendingArbitration(...) - // - contract.isSettledTooSoon(...) - // - contract.question_claims(...) - // - contract.questions(...) - // - contract.reopened_questions(...) - // - contract.reopener_questions(...) - // - contract.resultFor(...) - // - contract.resultForOnceSettled(...) - // - contract.template_hashes(...) - // - contract.templates(...) -}*/ - -export function handleLogCancelArbitration(event: LogCancelArbitration): void {} - -export function handleLogClaim(event: LogClaim): void {} - -export function handleLogFinalize(event: LogFinalize): void { - let question = Question.load(event.params.question_id.toHexString()); - - if (question === null) { - log.error(`handleSubmitAnswerByArbitrator: question ${event.params.question_id.toHexString()} not found`, []) - return; + let userHistory = UserHistory.load(moderationInfo.user) + if (!userHistory){ + log.error('user history not found. {}',[moderationInfo.user]) + return + } + if(RealityETHV30.bind(event.address).getBestAnswer(event.params.question_id) === new Bytes(1)){ + userHistory.countBrokeRulesOptimisticAndArbitrated-- + userHistory.timestampLastUpdated = event.block.timestamp + if(userHistory.countBrokeRulesOptimisticAndArbitrated === 0) + userHistory.timestampParole.minus(BigInt.fromU32(86400)) + if(userHistory.countBrokeRulesOptimisticAndArbitrated === 1) + userHistory.timestampParole.minus(BigInt.fromU32(604800)) + + userHistory.save() } - - question.finalize_ts = event.block.timestamp; - - question.save(); } -export function handleLogFundAnswerBounty(event: LogFundAnswerBounty): void {} - -export function handleLogMinimumBond(event: LogMinimumBond): void {} - export function handleLogNewAnswer(event: LogNewAnswer): void { - let question = Question.load(event.params.question_id.toHexString()); + + const moderationInfo = ModerationInfo.load(event.params.question_id.toHexString()) + if (!moderationInfo){ + // answer to irrelevant question, skip + return + } - if (question === null) { - log.error(`handleSubmitAnswer: question ${event.params.question_id.toHexString()} not found`, []) - return; - } else { + var realityCheck = RealityCheck.load(event.params.question_id.toHexString()) + if (!realityCheck) + realityCheck = new RealityCheck(event.params.question_id.toHexString()) + + let userHistory = UserHistory.load(moderationInfo.user) + if (!userHistory){ + userHistory = new UserHistory(moderationInfo.user) + userHistory.countBrokeRulesArbitrated = 0 + userHistory.countBrokeRulesOptimisticAndArbitrated = 0 + userHistory.countReportsMade = 0 + userHistory.countReportsMadeAndResponded = 0 + userHistory.timestampLastReport = BigInt.fromU32(0) + userHistory.timestampLastUpdated = BigInt.fromU32(0) + userHistory.timestampParole = BigInt.fromU32(0) + userHistory.user = moderationInfo.user + } - question.finalize_ts = event.block.timestamp.plus(question.timeout); - question.bond = event.params.bond; - question.answer = event.params.answer; + const reportedByUserHistory = UserHistory.load(moderationInfo.reportedBy) + if (!reportedByUserHistory){ + log.error('reportedByUserHistory missing {}',[moderationInfo.reportedBy]); + return; + } + reportedByUserHistory.countReportsMadeAndResponded++ + reportedByUserHistory.save() - question.save(); + const user = User.load(moderationInfo.user) + if (!user){ + log.error('user missing {}',[moderationInfo.user]); + return; + } + + var janny = Janny.load(user.group) + if(!janny){ + janny = new Janny(user.group) + janny.group = user.group } -} -export function handleLogNewQuestion(event: LogNewQuestion): void { - if (event.params.template_id.toU32() === 60){ //XDAI - //if (event.params.template_id.toU32() === 394){ // Rinkeby - const questionString = event.params.question; - const params = questionString.split('\u241f'); - if (params.length < 10) + let sheriffOld = janny.sheriff + let deputySheriffOld = janny.deputySheriff + + if (!sheriffOld){ + janny.sheriff = moderationInfo.reportedBy + janny.blocknumberLastUpdatedSheriff = event.block.number + janny.timestampLastUpdatedSheriff = event.block.number + janny.save() + } else if (!deputySheriffOld){ + janny.deputySheriff = moderationInfo.reportedBy + janny.deputySheriff = moderationInfo.reportedBy + janny.timestampLastUpdatedDeputySheriff = event.block.number + janny.save() + } else { + let non_null_sheriff: string = sheriffOld ? sheriffOld : 'null' // compiles just fine :) + const sheriff = UserHistory.load(non_null_sheriff) + if (!sheriff){ + log.error('sheriff missing {}',[non_null_sheriff]); return; - - const question = new Question(event.params.question_id.toHexString()); - - let group = Group.load(params[4] + params[2]); - if (group === null) { - group = new Group(params[4] + params[2]); - group.groupID = params[4]; - group.platform = params[2]; - group.name = params[3]; - group.save(); } - - let user = User.load(params[1] + params[2]); - if (user === null) { - user = new User(params[1] + params[2]); - user.userID = params[1]; - user.username = params[0]; - user.group = params[4] + params[2]; - user.save(); + if(sheriff.countReportsMadeAndResponded < reportedByUserHistory.countReportsMadeAndResponded){ + janny.sheriff = reportedByUserHistory.user + janny.blocknumberLastUpdatedSheriff = event.block.number + janny.timestampLastUpdatedSheriff = event.block.number + janny.save() + } else{ + let non_null_deputySheriff: string = deputySheriffOld ? deputySheriffOld : 'null' // compiles just fine :) + const deputySheriff = UserHistory.load(non_null_deputySheriff) + if (!deputySheriff){ + log.error('deputy sheriff missing {}',[non_null_deputySheriff]); + return; + } + if(deputySheriff.countReportsMadeAndResponded < reportedByUserHistory.countReportsMadeAndResponded){ + janny.deputySheriff = reportedByUserHistory.user + janny.blocknumberLastUpdatedDeputySheriff = event.block.number + janny.timestampLastUpdatedDeputySheriff = event.block.number + janny.save() + } } - question.rulesUrl = params[5]; - question.message = params[6]; - question.messageBackup = params[7]; - question.askedBy = event.transaction.from; - question.timeout = event.params.timeout; - question.finalize_ts = event.block.timestamp.plus(question.timeout); - question.user = params[1] + params[2]; - - question.save(); } - + + + const currentAnswer = realityCheck.currentAnswer + const yes = Bytes.fromHexString('0x0000000000000000000000000000000000000000000000000000000000000001') + + if(currentAnswer && currentAnswer.equals(yes)){ + if (event.params.answer.notEqual(yes)){ + realityCheck.timeServed = event.block.timestamp.minus(realityCheck.deadline.minus(moderationInfo.timeout)); + userHistory.countBrokeRulesOptimisticAndArbitrated-- + userHistory.timestampLastUpdated = event.block.timestamp + if(userHistory.countBrokeRulesOptimisticAndArbitrated === 0) + userHistory.timestampParole.minus(BigInt.fromU32(86400)) + if(userHistory.countBrokeRulesOptimisticAndArbitrated === 1) + userHistory.timestampParole.minus(BigInt.fromU32(604800)) + } + } else if (event.params.answer.equals(yes)){ + realityCheck.timeServed = BigInt.fromU32(0) + userHistory.countBrokeRulesOptimisticAndArbitrated++ + userHistory.timestampLastUpdated = event.block.timestamp + if(userHistory.countBrokeRulesOptimisticAndArbitrated === 1) + userHistory.timestampParole = event.block.timestamp.plus(BigInt.fromU32(86400)) + if(userHistory.countBrokeRulesOptimisticAndArbitrated === 2) + userHistory.timestampParole = event.block.timestamp.ge(userHistory.timestampParole) ? event.block.timestamp.plus(BigInt.fromU32(604800)) : userHistory.timestampParole.plus(BigInt.fromU32(604800)) + } + + realityCheck.currentAnswer = event.params.answer + realityCheck.blocknumberLastUpdated = event.block.number + realityCheck.timestampLastUpdated = event.block.number + realityCheck.deadline = event.block.timestamp.plus(moderationInfo.timeout); + realityCheck.save() + userHistory.save() } -export function handleLogNewTemplate(event: LogNewTemplate): void {} -export function handleLogNotifyOfArbitrationRequest( - event: LogNotifyOfArbitrationRequest -): void { - let question = Question.load(event.params.question_id.toHexString()); - if (question === null) { - log.error(`handleSubmitAnswerByArbitrator: question ${event.params.question_id.toHexString()} not found`, []) +export function handleLogNewQuestion(event: LogNewQuestion): void { + //if (event.params.template_id.toU32() === 60){ //XDAI + const questionString = event.params.question; + const params = questionString.split('\u241f'); + if (params.length < 10) return; - } - question.arbitrationRequested = true; - - question.save(); -} + let group = Group.load(event.transaction.from.toHexString() + params[2] + params[5]); + if (group === null) { + group = new Group(event.transaction.from.toHexString() + params[2] + params[5]); + group.groupID = params[5]; + group.platform = params[2]; + group.botAddress = event.transaction.from; + group.name = params[3]; -export function handleLogReopenQuestion(event: LogReopenQuestion): void {} + group.save(); + } -export function handleLogSetQuestionFee(event: LogSetQuestionFee): void {} + let user = User.load(event.transaction.from.toHexString() + params[2] + params[1]); + if (user === null) { + user = new User(event.transaction.from.toHexString() + params[2] + params[1]); + user.userID = params[1]; + user.username = params[0]; + user.group = event.transaction.from.toHexString() + params[2] + params[5]; + user.save(); + } -export function handleLogWithdraw(event: LogWithdraw): void {} + const moderationInfo = new ModerationInfo(event.params.question_id.toHexString()); + moderationInfo.moderationType = event.params.template_id; + moderationInfo.reportedBy = event.transaction.from.toHexString()+params[2] + params[9] + if (!User.load(moderationInfo.reportedBy)){ + const userReportedBy = new User(moderationInfo.reportedBy) + userReportedBy.group = user.group + userReportedBy.userID = params[9] + userReportedBy.save() + } + moderationInfo.deadline = event.params.opening_ts.plus(event.params.timeout); + moderationInfo.timeout = event.params.timeout; + moderationInfo.askedBy = event.transaction.from; + moderationInfo.rulesUrl = params[6]; + moderationInfo.message = params[7]; + moderationInfo.reality = event.params.question_id.toHexString() + moderationInfo.messageBackup = params[8]; + moderationInfo.user = event.transaction.from.toHexString() + params[2] + params[1]; + + moderationInfo.save(); + + var reportedByUserHistory = UserHistory.load(moderationInfo.reportedBy) + if (!reportedByUserHistory){ + reportedByUserHistory = new UserHistory(moderationInfo.reportedBy) + reportedByUserHistory.user = moderationInfo.reportedBy + reportedByUserHistory.countReportsMade = 0 + reportedByUserHistory.countBrokeRulesOptimisticAndArbitrated = 0 + reportedByUserHistory.countBrokeRulesArbitrated = 0 + reportedByUserHistory.timestampParole = BigInt.fromU32(0) + reportedByUserHistory.timestampLastUpdated = BigInt.fromU32(0) + reportedByUserHistory.countReportsMadeAndResponded = 0 + } + reportedByUserHistory.countReportsMade++ + reportedByUserHistory.timestampLastReport = event.block.timestamp + reportedByUserHistory.save() +} \ No newline at end of file diff --git a/subgraph/subgraph.yaml b/subgraph/subgraph.yaml index ac4bce9..8c92d01 100644 --- a/subgraph/subgraph.yaml +++ b/subgraph/subgraph.yaml @@ -4,100 +4,80 @@ schema: dataSources: - kind: ethereum name: RealityETHV30 - network: xdai #rinkeby #xdai + network: goerli #goerli #xdai source: - address: "0xE78996A233895bE74a66F451f1019cA9734205cc" # "0xdf33060f476f8cff7511f806c72719394da1ad64" #<-- rinkeby, xdai "0xE78996A233895bE74a66F451f1019cA9734205cc" + address: "0x6F80C5cBCF9FbC2dA2F0675E56A5900BB70Df72f" # "0x6F80C5cBCF9FbC2dA2F0675E56A5900BB70Df72f" #<-- goerli, xdai "0xE78996A233895bE74a66F451f1019cA9734205cc" abi: RealityETHV30 - startBlock: 23143918 # 11138020 # <--- rinkeby, xdai 23143918 + startBlock: 7913496 #7913496 # <--- goerli, xdai 23143918 mapping: kind: ethereum/events apiVersion: 0.0.6 language: wasm/assemblyscript entities: - - LogAnswerReveal - - LogCancelArbitration - - LogClaim - - LogFinalize - - LogFundAnswerBounty - - LogMinimumBond - LogNewAnswer - LogNewQuestion - - LogNewTemplate - LogNotifyOfArbitrationRequest - - LogReopenQuestion - - LogSetQuestionFee - - LogWithdraw + - RealityETHV30 abis: - name: RealityETHV30 file: ./abis/RealityETHV30.json eventHandlers: - - event: LogAnswerReveal(indexed bytes32,indexed address,indexed - bytes32,bytes32,uint256,uint256) - handler: handleLogAnswerReveal - - event: LogCancelArbitration(indexed bytes32) - handler: handleLogCancelArbitration - - event: LogClaim(indexed bytes32,indexed address,uint256) - handler: handleLogClaim - - event: LogFinalize(indexed bytes32,indexed bytes32) - handler: handleLogFinalize - - event: LogFundAnswerBounty(indexed bytes32,uint256,uint256,indexed address) - handler: handleLogFundAnswerBounty - - event: LogMinimumBond(indexed bytes32,uint256) - handler: handleLogMinimumBond - event: LogNewAnswer(bytes32,indexed bytes32,bytes32,indexed address,uint256,uint256,bool) handler: handleLogNewAnswer - event: LogNewQuestion(indexed bytes32,indexed address,uint256,string,indexed bytes32,address,uint32,uint32,uint256,uint256) handler: handleLogNewQuestion - - event: LogNewTemplate(indexed uint256,indexed address,string) - handler: handleLogNewTemplate - event: LogNotifyOfArbitrationRequest(indexed bytes32,indexed address) handler: handleLogNotifyOfArbitrationRequest - - event: LogReopenQuestion(indexed bytes32,indexed bytes32) - handler: handleLogReopenQuestion - - event: LogSetQuestionFee(address,uint256) - handler: handleLogSetQuestionFee - - event: LogWithdraw(indexed address,uint256) - handler: handleLogWithdraw file: ./src/reality-ethv-30.ts - kind: ethereum name: Realitio_v2_1_ArbitratorWithAppeals - network: xdai + network: goerli #xdai source: - address: "0x36a4e90568ce270aB671F55547C5EAe428B6c03A" + address: "0xAa5681047a16F163391377Fd9f78e84355Cc9696" #goerli "0xAa5681047a16F163391377Fd9f78e84355Cc9696" #xdai 0x2a2bAB2C2D4eB5007b0389720b287D4D19dc4001# xdai me "0x36a4e90568ce270aB671F55547C5EAe428B6c03A" abi: Realitio_v2_1_ArbitratorWithAppeals - startBlock: 23143918 # 11138020 rinkeby, xdai 23143918 + startBlock: 7913496 #7913496 #goerli, xdai 23143918 mapping: kind: ethereum/events apiVersion: 0.0.6 language: wasm/assemblyscript entities: - - Contribution - - Dispute - DisputeIDToQuestionID - - Evidence - - MetaEvidence - Ruling - RulingFunded - - Withdrawal abis: - name: Realitio_v2_1_ArbitratorWithAppeals file: ./abis/Realitio_v2_1_ArbitratorWithAppeals.json eventHandlers: - - event: Contribution(indexed uint256,indexed uint256,uint256,indexed address,uint256) - handler: handleContribution - - event: Dispute(indexed address,indexed uint256,uint256,uint256) - handler: handleDispute - event: DisputeIDToQuestionID(indexed uint256,bytes32) handler: handleDisputeIDToQuestionID - event: Evidence(indexed address,indexed uint256,indexed address,string) handler: handleEvidence - - event: MetaEvidence(indexed uint256,string) - handler: handleMetaEvidence - - event: Ruling(indexed address,indexed uint256,uint256) - handler: handleRuling - event: RulingFunded(indexed uint256,indexed uint256,indexed uint256) handler: handleRulingFunded - - event: Withdrawal(indexed uint256,indexed uint256,uint256,indexed address,uint256) - handler: handleWithdrawal + - event: Ruling(indexed address,indexed uint256,uint256) + handler: handleRuling file: ./src/Realitio_v2_1_ArbitratorWithAppeals.ts + - kind: ethereum + name: KlerosLiquid + network: goerli #xdai + source: + address: "0x209469C921db9d5Bd77084370e80B63d5cdD63C1" # goerli 0x209469C921db9d5Bd77084370e80B63d5cdD63C1 + abi: KlerosLiquid + startBlock: 7913496 #7913496 #goerli, xdai 23143918 + mapping: + kind: ethereum/events + apiVersion: 0.0.6 + language: wasm/assemblyscript + entities: + - AppealPossible + - AppealDecision + abis: + - name: KlerosLiquid + file: ./abis/KlerosLiquid.json + eventHandlers: + - event: AppealPossible(indexed uint256,indexed address) + handler: handleAppealPossible + - event: AppealDecision(indexed uint256,indexed address) + handler: handleAppealDecision + file: ./src/KlerosLiquid.ts \ No newline at end of file From d431c8795a85bb7bd5e35d4c76fa753bd41d259e Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Sun, 20 Nov 2022 21:02:33 -0800 Subject: [PATCH 003/111] feat(tg): topics and channel support --- lib/telegram/commands/addEvidence.ts | 109 ++++++----- lib/telegram/commands/getReports.ts | 9 +- lib/telegram/commands/getRules.ts | 7 +- lib/telegram/commands/greeting.ts | 43 +++-- lib/telegram/commands/report.ts | 173 ++++++++++-------- lib/telegram/commands/setChannel.ts | 63 +++++++ lib/telegram/commands/setLanguage.ts | 67 ++++--- lib/telegram/commands/setRules.ts | 46 +++-- lib/telegram/commands/socialConsensus.ts | 86 ++++----- lib/telegram/commands/start.ts | 67 +++++++ lib/telegram/commands/toggleWelcome.ts | 31 ++++ lib/telegram/commands/welcome.ts | 16 +- lib/telegram/index.ts | 219 +++++++++++++++-------- types.d.ts | 11 +- 14 files changed, 615 insertions(+), 332 deletions(-) create mode 100644 lib/telegram/commands/setChannel.ts create mode 100644 lib/telegram/commands/start.ts create mode 100644 lib/telegram/commands/toggleWelcome.ts diff --git a/lib/telegram/commands/addEvidence.ts b/lib/telegram/commands/addEvidence.ts index ea27a3a..1b20d15 100644 --- a/lib/telegram/commands/addEvidence.ts +++ b/lib/telegram/commands/addEvidence.ts @@ -1,16 +1,29 @@ import * as TelegramBot from "node-telegram-bot-api"; import {Wallet} from "@ethersproject/wallet"; import {ipfsPublish, ipfsPublishBuffer} from "../../ipfs-publish"; -import {getRealitioArbitrator} from "../../ethers"; +import { existsQuestionId } from "../../graph"; import fetch from 'node-fetch'; +import { groupSettings } from "../../../types"; import langJson from "../assets/lang.json"; -import {getDisputedReportsInfo, getActiveEvidenceGroupId, setAllowance, getAllowance} from "../../db"; +import { newSettings } from "../../ddb/ddb"; +const _contract = require('../../abi/Realitio_v2_1_ArbitratorWithAppeals.json') +const Web3 = require('web3') +const web3 = new Web3(process.env.WEB3_PROVIDER_URL) -const processCommand = async (bot: TelegramBot, lang: string, msg: TelegramBot.Message, questionId: number|string, address: string, privateKey: string): Promise => { - const evidencePath = await upload(bot, lang, msg, address); - const evidenceJsonPath = await uploadEvidenceJson(lang, msg, evidencePath, address); - await bot.sendMessage(msg.chat.id, `${langJson[lang].addEvidence.submitted}(https://ipfs.kleros.io${evidencePath}).`, {parse_mode: "Markdown"}); - await submitEvidence(evidenceJsonPath, questionId,privateKey); +const contract = new web3.eth.Contract( + _contract, + process.env.REALITIO_ARBITRATOR + ) + +var botAddress: string; + +const processCommand = async (bot: TelegramBot, settings: groupSettings, msg: TelegramBot.Message, questionId: number|string, address: string, batchedSend: any, ): Promise => { + const evidencePath = await upload(bot, settings.lang, msg, address); + const evidenceJsonPath = await uploadEvidenceJson(settings.lang, msg, evidencePath, address); + await bot.sendMessage(settings.channelID, `${langJson[settings.lang].addevidence.submitted}(https://ipfs.kleros.io${evidencePath}).`, {parse_mode: "Markdown"}); + //await bot.sendMessage(channelId, `${langJson[lang].addevidence.submitted}(https://ipfs.kleros.io${evidencePath}).`, {parse_mode: "Markdown"}); + + await submitEvidence(batchedSend, evidenceJsonPath, questionId); return evidenceJsonPath; } @@ -27,7 +40,7 @@ const upload = async (bot: TelegramBot, lang: string, msg: TelegramBot.Message, if (msg.reply_to_message.sticker){ file = await bot.getFile(msg.reply_to_message.sticker.file_id); } else if (msg.reply_to_message.photo){ - file = await bot.getFile(msg.reply_to_message.photo[0].file_id); + file = await bot.getFile(msg.reply_to_message.photo[msg.reply_to_message.photo.length-1].file_id); } else if (msg.reply_to_message.audio){ file = await bot.getFile(msg.reply_to_message.audio.file_id); } else if (msg.reply_to_message.voice){ @@ -57,7 +70,7 @@ const uploadFileEvidence = async (filePath: string, fileName: string): Promise => { const enc = new TextEncoder(); const author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' ID:'+msg.reply_to_message.from.id ; - const fileName = `${langJson[lang].addevidence.location}.txt`; + const fileName = `${langJson[lang]["addevidence"].location}.txt`; const chatHistory = `${langJson[lang].addevidence.Chat}: ${msg.chat.title} (${String(msg.chat.id)}) ${langJson[lang].addevidence.Author}: ${author} (${(new Date(msg.reply_to_message.date*1000)).toISOString()}) @@ -132,13 +145,15 @@ const uploadEvidenceJson = async (lang: string, msg: TelegramBot.Message, eviden return evidenceJsonPath; } -const submitEvidence = async (evidencePath: string, questionId: number|string, privateKey: string) => { +const submitEvidence = async (batchedSend: any, evidencePath: string, questionId: number|string) => { - await getRealitioArbitrator(process.env.REALITIO_ARBITRATOR, privateKey) - .submitEvidence( + batchedSend({ + args: [ questionId, - evidencePath - ) + evidencePath], + method: contract.methods.submitEvidence, + to: contract.options.address + }); } /* @@ -147,64 +162,68 @@ const submitEvidence = async (evidencePath: string, questionId: number|string, p const regexp = /\/addevidence/ const regexpFull = /\/addevidence (.+)/ -const callback = async (db: any, lang: string, bot: TelegramBot, msg: TelegramBot.Message) => { - const match = msg.text.match(regexpFull); - +const callback = async (db: any, settings: groupSettings, bot: any, msg: any, batchedSend: any) => { if (!msg.reply_to_message) { - await bot.sendMessage(msg.chat.id, `/addevidence ${langJson[lang].errorReply}`); + msg.chat.is_forum? await bot.sendMessage(msg.chat.id, `/addevidence ${langJson[settings.lang].errorReply}`, {message_thread_id: msg.message_thread_id}) : await bot.sendMessage(msg.chat.id, `/addevidence ${langJson[settings.lang].errorReply}`); return; } + const match = msg.text.match(regexpFull); + + //TODO Evidence IDs and button callback UX if (!match || match.length < 2){ - await bot.sendMessage(msg.chat.id, `/addevidence ${langJson[lang].addEvidence.error1} ${langJson[lang].addEvidence.id}`); - const errorMsg = await errorMessage(db, lang, bot, msg); - await bot.sendMessage(msg.chat.id, errorMsg, {parse_mode: "Markdown", disable_web_page_preview: true}); + msg.chat.is_forum? await bot.sendMessage(msg.chat.id, `/addevidence ${langJson[settings.lang].addevidence.error1} ${langJson[settings.lang].addevidence.id}`, {message_thread_id: msg.message_thread_id}) : await bot.sendMessage(msg.chat.id, `/addevidence ${langJson[settings.lang].addevidence.error1} ${langJson[settings.lang].addevidence.id}`); + //const errorMsg = await errorMessage(db, lang, bot, msg); + //await bot.sendMessage(msg.chat.id, errorMsg, {parse_mode: "Markdown", disable_web_page_preview: true}); return; } - const result = await getActiveEvidenceGroupId(db, 'telegram', String(msg.chat.id), Number(match[1])); - const user = await bot.getChatMember(msg.chat.id, String(msg.from.id)); - const isAdmin = user.status === 'creator' || user.status === 'administrator'; - if (result == null){ - await bot.sendMessage(msg.chat.id, langJson[lang].errorId); - const errorMsg = await errorMessage(db, lang, bot, msg); - await bot.sendMessage(msg.chat.id, errorMsg, {parse_mode: "Markdown", disable_web_page_preview: true}); + if (!await existsQuestionId(match[1])){ + msg.chat.is_forum? await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorId, {message_thread_id: msg.message_thread_id}) : bot.sendMessage(msg.chat.id, langJson[settings.lang].errorId); + await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorId); + //const errorMsg = await errorMessage(db, lang, bot, msg); + //await bot.sendMessage(msg.chat.id, errorMsg, {parse_mode: "Markdown", disable_web_page_preview: true}); return; } - if(!isAdmin){ - const reportAllowance = await getAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id)); - if (reportAllowance === undefined){ - setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), 3, 14, Math.ceil( new Date().getTime() / 1000)); - } else if ((Math.ceil( new Date().getTime() / 1000) < reportAllowance.timestamp_refresh + 5760) && reportAllowance.evidence_allowance == 0 ){ - await bot.sendMessage(msg.chat.id, langJson[lang].errorAllowance); - } else{ - const newReportAllowance = reportAllowance.report_allowance + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800); - const newEvidenceAllowance = reportAllowance.evidence_allowance + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800)*5 - 1; - const newRefreshTimestamp = reportAllowance.timestamp_refresh + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800)*28800; - setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), Math.min(newReportAllowance,3), Math.min(newEvidenceAllowance,15), newRefreshTimestamp); - } + + // TODO Allowance + /* + const reportAllowance = await getAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id)); + if (reportAllowance === undefined){ + setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), 3, 14, Math.ceil( new Date().getTime() / 1000)); + } else if ((Math.ceil( new Date().getTime() / 1000) < reportAllowance.timestamp_refresh + 5760) && reportAllowance.evidence_allowance == 0 ){ + await bot.sendMessage(msg.chat.id, langJson[lang].errorAllowance); + } else{ + const newReportAllowance = reportAllowance.report_allowance + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800); + const newEvidenceAllowance = reportAllowance.evidence_allowance + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800)*5 - 1; + const newRefreshTimestamp = reportAllowance.timestamp_refresh + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800)*28800; + setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), Math.min(newReportAllowance,3), Math.min(newEvidenceAllowance,15), newRefreshTimestamp); } +*/ + if (!botAddress) + botAddress = await (await new Wallet(process.env.PRIVATE_KEY)).address try { - const evidencePath = await processCommand(bot, lang, msg, match[1], await (await new Wallet(process.env.PRIVATE_KEY)).address, process.env.PRIVATE_KEY); + const evidencePath = await processCommand(bot, settings, msg, match[1], botAddress,batchedSend); } catch (e) { console.log(e); - await bot.sendMessage(msg.chat.id, `${langJson[lang].errorTxn}: ${e.message}.`); + await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].errorTxn}: ${e.message}.`); } } - +/* const errorMessage = async (db: any, lang: string, bot: TelegramBot, msg: TelegramBot.Message): Promise => { const reports = await getDisputedReportsInfo(db, 'telegram', String(msg.chat.id)); - var reportMessage: string = `${langJson[lang].addEvidence.msg1}:\n\n`; + var reportMessage: string = `${langJson[lang].addevidence.msg1}:\n\n`; await reports.forEach(async (report) => { const MsgLink = 'https://t.me/c/' + report.group_id.substring(4) + '/' + report.msg_id; const msgTime = new Date(report.timestamp*1000).toISOString(); - reportMessage += ` - ${report.username} ${langJson[lang].addEvidence.msg2} [${msgTime.substring(0,msgTime.length-4)}](${MsgLink}) ([${langJson[lang].socialConsensus.consensus5}](${report.msgBackup})): ${langJson[lang].addEvidence.id} ${report.evidenceIndex}\n`; + reportMessage += ` - ${report.username} ${langJson[lang].addevidence.msg2} [${msgTime.substring(0,msgTime.length-4)}](${MsgLink}) ([${langJson[lang].socialConsensus.consensus5}](${report.msgBackup})): ${langJson[lang].addevidence.id} ${report.evidenceIndex}\n`; }); return reportMessage; } +*/ export {regexp, callback, processCommand, submitEvidence, upload}; \ No newline at end of file diff --git a/lib/telegram/commands/getReports.ts b/lib/telegram/commands/getReports.ts index a373329..408e217 100644 --- a/lib/telegram/commands/getReports.ts +++ b/lib/telegram/commands/getReports.ts @@ -1,5 +1,4 @@ import * as TelegramBot from "node-telegram-bot-api"; -import {getDisputedReportsInfo, getDisputedReportsUserInfo} from "../../db"; const escape = require('markdown-escape') import langJson from "../assets/lang.json"; @@ -9,7 +8,7 @@ import langJson from "../assets/lang.json"; const regexp = /\/getreports/ const callback = async (db: any, lang: string, bot: TelegramBot, msg: TelegramBot.Message) => { - +/* if(msg.reply_to_message){ const reports = await getDisputedReportsUserInfo(db, 'telegram', String(msg.chat.id), String(msg.reply_to_message.from.id)); const fromUsername = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name || `no-username-set`); @@ -23,7 +22,7 @@ const callback = async (db: any, lang: string, bot: TelegramBot, msg: TelegramBo const MsgLink = 'https://t.me/c/' + report.group_id.substring(4) + '/' + report.msg_id; const msgTime = new Date(report.timestamp*1000).toISOString(); const reportState = report.finalized? langJson[lang].getReports.reportFinal : langJson[lang].getReports.reportCurrent; - reportMessage += ` - [${langJson[lang].getReports.report}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITITY_ETH_V30}-${report.question_id}), ${langJson[lang].addEvidence.Evidence} ID ${report.evidenceIndex}, [${langJson[lang].addEvidence.MessageSent} ${msgTime.substring(0,msgTime.length-4)}](${MsgLink}) ([${langJson[lang].socialConsensus.consensus5}](${report.msgBackup})), ${reportState} ${langJson[lang].answer}, ${reportAnswer}\n`; + reportMessage += ` - [${langJson[lang].getReports.report}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), ${langJson[lang].addEvidence.Evidence} ID ${report.evidenceIndex}, [${langJson[lang].addEvidence.MessageSent} ${msgTime.substring(0,msgTime.length-4)}](${MsgLink}) ([${langJson[lang].socialConsensus.consensus5}](${report.msgBackup})), ${reportState} ${langJson[lang].answer}, ${reportAnswer}\n`; }); await bot.sendMessage(msg.chat.id, reportMessage, {parse_mode: "Markdown", disable_web_page_preview: true}); return; @@ -41,12 +40,12 @@ const callback = async (db: any, lang: string, bot: TelegramBot, msg: TelegramBo const reportAnswer = report.active? langJson[lang].getReports.broke : langJson[lang].getReports.nobreak const MsgLink = 'https://t.me/c/' + report.group_id.substring(4) + '/' + report.msg_id; const msgTime = new Date(report.timestamp*1000).toISOString(); - reportMessage += ` - ${report.username} ${langJson[lang].getReports.reportMessage1} [${msgTime.substring(0,msgTime.length-4)}](${MsgLink}) ([${langJson[lang].getReports.reportMessage2}](${report.msgBackup})): [${langJson[lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITITY_ETH_V30}-${report.question_id}), ${langJson[lang].getReports.reportMessage4}, ${reportAnswer}\n`; + reportMessage += ` - ${report.username} ${langJson[lang].getReports.reportMessage1} [${msgTime.substring(0,msgTime.length-4)}](${MsgLink}) ([${langJson[lang].getReports.reportMessage2}](${report.msgBackup})): [${langJson[lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), ${langJson[lang].getReports.reportMessage4}, ${reportAnswer}\n`; }); reportMessage += '\n\n' reportMessage += langJson[lang].getReports.specificUser; await bot.sendMessage(msg.chat.id, reportMessage, {parse_mode: "Markdown", disable_web_page_preview: true}); - + */ } export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/getRules.ts b/lib/telegram/commands/getRules.ts index 732ccb0..9c5dbbb 100644 --- a/lib/telegram/commands/getRules.ts +++ b/lib/telegram/commands/getRules.ts @@ -1,18 +1,19 @@ import * as TelegramBot from "node-telegram-bot-api"; import {getRule} from "../../db"; import langJson from "../assets/lang.json"; +import { groupSettings } from "../../../types"; /* * /getrules */ const regexp = /\/getrules/ -const callback = async (db: any, lang: string, bot: TelegramBot, msg: TelegramBot.Message) => { +const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { const rules = await getRule(db, 'telegram', String(msg.chat.id), Math.floor(Date.now()/1000)); if (rules) - await bot.sendMessage(msg.chat.id, `${langJson[lang].rules}(${rules}).`,{parse_mode: "Markdown"}); + await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].rules}(${rules}).`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}); else - await bot.sendMessage(msg.chat.id, langJson[lang].noRules); + await bot.sendMessage(msg.chat.id, langJson[settings.lang].noRules, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}); } export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/greeting.ts b/lib/telegram/commands/greeting.ts index 24b5fd2..e9416dc 100644 --- a/lib/telegram/commands/greeting.ts +++ b/lib/telegram/commands/greeting.ts @@ -1,33 +1,30 @@ import * as TelegramBot from "node-telegram-bot-api"; -import {getRule, setRules} from "../../db"; import langJson from "../assets/lang.json"; - -/* - * /getrules - */ - +import {groupSettings} from "../../../types"; let greetingMap : Map = new Map(); -const callback = async (db: any, lang: string, bot: TelegramBot, msg: TelegramBot.Message) => { - - var rules = await getRule(db, 'telegram', String(msg.chat.id), Math.floor(Date.now()/1000)); - - if (!rules){ - rules = langJson[lang].defaultRules; - await setRules(db, 'telegram', String(msg.chat.id), rules, Math.floor(Date.now()/1000)); - } - - const previousMsgId = greetingMap?.get(msg.chat.id); +const callback = async (bot: any, settings: groupSettings, msg: any) => { + const previousMsgId = greetingMap.get(msg.chat.id); if (previousMsgId){ - bot.deleteMessage(msg.chat.id, String(previousMsgId[0])); - bot.deleteMessage(msg.chat.id, String(previousMsgId[1])); + try{ + bot.deleteMessage(msg.chat.id, String(previousMsgId[0])); + bot.deleteMessage(msg.chat.id, String(previousMsgId[1])); + } catch (e){ + console.log(e) + } + } + try{ + if(msg.chat.is_forum){ + bot.sendMessage(msg.chat.id, `Welcome [${msg.from.first_name}](tg://user?id=${msg.from.id}) ${langJson[settings.lang].greeting2}(${settings.rules}). ${langJson[settings.lang].greeting3}`, {message_thread_id: settings.thread_id_welcome, parse_mode: "Markdown"}); + } else { + const msg1: TelegramBot.Message = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].greeting1}[Kleros Moderate](https://kleros.io/moderate/).`, {parse_mode: "Markdown"}); + const msg2: TelegramBot.Message = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].greeting2}(${settings.rules}). ${langJson[settings.lang].greeting3}`, {parse_mode: "Markdown"}); + greetingMap.set(msg.chat.id, [msg1.message_id, msg2.message_id]); + } + } catch(e){ + console.log(e) } - - const msg1: TelegramBot.Message = await bot.sendMessage(msg.chat.id, `${langJson[lang].greeting1}[Kleros Moderate](https://kleros.io/moderate/).`, {parse_mode: "Markdown"}); - const msg2: TelegramBot.Message = await bot.sendMessage(msg.chat.id, `${langJson[lang].greeting2}(${rules}). ${langJson[lang].greeting3}`, {parse_mode: "Markdown"}); - - greetingMap.set(msg.chat.id, [msg1.message_id, msg2.message_id]); } export {callback}; \ No newline at end of file diff --git a/lib/telegram/commands/report.ts b/lib/telegram/commands/report.ts index 7e52be2..779de95 100644 --- a/lib/telegram/commands/report.ts +++ b/lib/telegram/commands/report.ts @@ -1,152 +1,167 @@ import * as TelegramBot from "node-telegram-bot-api"; import {Wallet} from "@ethersproject/wallet"; -import {addReportRequest, getReportRequest, addReport, getRecordCount, questionAnswered, setInviteURL, getInviteURL, getQuestionId, getRule, getConcurrentReports, getAllowance, setAllowance} from "../../db"; +import {setInviteURL, getInviteURL, getRule} from "../../db"; +import { getQuestionId } from "../../graph"; +import { groupSettings } from "../../../types"; import {upload} from "./addEvidence" import {reportUser} from "../../bot-core"; import langJson from "../assets/lang.json"; - +const escape = require('markdown-escape'); /* * /report */ const regexp = /\/report\s?(.+)?/ let evidenceIndexMap : Map = new Map(); +let inviteURLMap : Map = new Map(); +var botAddress: string; - -const callback = async (db:any, lang: string, bot: any, msg: TelegramBot.Message, match: string[]) => { +const callback = async (db:any, settings: groupSettings, bot: any, botId: number, msg: TelegramBot.Message, match: string[]) => { if (!msg.reply_to_message) { - await bot.sendMessage(msg.chat.id, `/report ${langJson[lang].errorReply}`); + await bot.sendMessage(msg.chat.id, `/report ${langJson[settings.lang].errorReply}`); return; } - const user = await bot.getChatMember(msg.chat.id, String(msg.from.id)); - const isAdmin = user.status === 'creator' || user.status === 'administrator'; - const reportedChatMember = await bot.getChatMember(msg.chat.id, String(msg.reply_to_message.from.id)); - if (reportedChatMember.status === 'creator' || reportedChatMember.status === 'administrator') { - await bot.sendMessage(msg.chat.id, `${langJson[lang].report.errorAdmin}`); - return; + + if (msg.reply_to_message.from.id === botId){ + await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.errorModBot}`); } + // WHO WATCHES THE WATCHMEN?? + //const reportedChatMember = await bot.getChatMember(msg.chat.id, String(msg.reply_to_message.from.id)); + //if (reportedChatMember.status === 'creator' || reportedChatMember.status === 'administrator') { + // await bot.sendMessage(msg.chat.id, `${langJson[lang].report.errorAdmin}`); + // return; + //} const fromUsername = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name || `no-username-set`); const reportedUserID = String(msg.reply_to_message.from.id); - const reportedQuestionId = await getQuestionId(db, 'telegram', String(msg.chat.id), reportedUserID, String(msg.reply_to_message.message_id)); + + // replace with graph, maybe also hashmap for fast + const reportedQuestionId = await getQuestionId(botAddress, 'Telegram', String(msg.chat.id), reportedUserID, String(msg.reply_to_message.message_id)); if (reportedQuestionId){ - await bot.sendMessage(msg.chat.id, `${langJson[lang].report.reported}(https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITITY_ETH_V30}-${reportedQuestionId})`, {parse_mode: 'Markdown'}); + await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.reported}(https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${reportedQuestionId})`, {parse_mode: 'Markdown'}); return; } - const reportRequest = await getReportRequest(db, 'telegram', String(msg.chat.id), String(msg.reply_to_message.message_id)); + // replace with hashmap ? + // only keep track of last 24 hours + //const reportRequest + //= await getReportRequest(db, 'telegram', String(msg.chat.id), String(msg.reply_to_message.message_id)); +/* if (reportRequest){ const requestMsgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + reportRequest.msgRequestId; await bot.sendMessage(msg.chat.id, `${langJson[lang].report.reported}(${requestMsgLink}).`, {parse_mode: 'Markdown'}); return; - } + }*/ +/* const reports = await getConcurrentReports(db, 'telegram', String(msg.chat.id), reportedUserID, msg.reply_to_message.date); if (reports.length > 0 && match[1] != langJson[lang].socialConsensus.confirm) { var reportInfo = `${langJson[lang].report.info1} *${escape(fromUsername)} (ID :${reportedUserID})* ${langJson[lang].report.info2} \n\n`; (reports).forEach((report) => { const privateMsgLink = 'https://t.me/c/' + report.group_id.substring(4) + '/' + report.msg_id; - reportInfo += ` - [${langJson[lang].addEvidence.Message} ${new Date(report.timestamp*1000).toISOString()}](${privateMsgLink}): [${langJson[lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITITY_ETH_V30}-${report.question_id})\n`; + reportInfo += ` - [${langJson[lang].addEvidence.Message} ${new Date(report.timestamp*1000).toISOString()}](${privateMsgLink}): [${langJson[lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id})\n`; }); reportInfo += `\n${langJson[lang].report.sure} \'/report ${langJson[lang].socialConsensus.confirm}\'` await bot.sendMessage(msg.chat.id, reportInfo, {parse_mode: 'Markdown'}); return; } - +*/ const rules = await getRule(db, 'telegram', String(msg.chat.id), msg.reply_to_message.date); + if (!rules){ - await bot.sendMessage(msg.chat.id, langJson[lang].report.norules); + await bot.sendMessage(msg.chat.id, langJson[settings.lang].report.norules); return; } - const evidencepath = await upload(bot, lang, msg, await (await new Wallet(process.env.PRIVATE_KEY)).address); - const msgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + String(msg.reply_to_message.message_id); - const msgBackup = 'ipfs.kleros.io'+evidencepath; - - if (!isAdmin){ - const reportAllowance = await getAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id)); - if(reportAllowance != undefined && reportAllowance.question_id_last){ - const isQuestionAnswered = await questionAnswered(db, reportAllowance.question_id_last); - const lastReport = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITITY_ETH_V30}-${reportAllowance.question_id_last}`; - if(!isQuestionAnswered && Math.floor(Date.now()/1000) < reportAllowance.timestamp_last_question + 259200){ - await bot.sendMessage(msg.chat.id, `${langJson[lang].report.allowance1}(${lastReport}) ${langJson[lang].report.allowance2}`, {parse_mode: 'Markdown'}); - return; - } - } + if (!botAddress) + botAddress = await (await new Wallet(process.env.PRIVATE_KEY)).address - if ( reportAllowance === undefined ){ - setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), 2, 15, Math.ceil( new Date().getTime() / 1000)); - } else if ((Math.ceil( new Date().getTime() / 1000) < reportAllowance.timestamp_refresh + 28800) && reportAllowance.report_allowance == 0 ){ - await bot.sendMessage(msg.chat.id, langJson[lang].report.noallowance); + const evidencepath = await upload(bot, settings.lang, msg, botAddress); + const msgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + String(msg.reply_to_message.message_id); + const msgBackup = 'https://ipfs.kleros.io'+evidencepath; + // TODO report + /* + const reportAllowance = await getAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id)); + if(reportAllowance != undefined && reportAllowance.question_id_last){ + const isQuestionAnswered = await questionAnswered(db, reportAllowance.question_id_last); + const lastReport = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${reportAllowance.question_id_last}`; + if(!isQuestionAnswered && Math.floor(Date.now()/1000) < reportAllowance.timestamp_last_question + 259200){ + await bot.sendMessage(msg.chat.id, `${langJson[lang].report.allowance1}(${lastReport}) ${langJson[lang].report.allowance2}`, {parse_mode: 'Markdown'}); return; - } else{ - const newReportAllowance = reportAllowance.report_allowance + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800) - 1; - const newEvidenceAllowance = reportAllowance.evidence_allowance + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800)*5; - const newRefreshTimestamp = reportAllowance.timestamp_refresh + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800)*28800; - setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), Math.min(newReportAllowance,3), Math.min(newEvidenceAllowance,15), newRefreshTimestamp); } - const opts = { - parse_mode: 'Markdown', - reply_markup: { - inline_keyboard: [ - [ - { - text: langJson[lang].socialConsensus.confirm + ' (1/3)', - callback_data: String(msg.reply_to_message.message_id)+'|'+String(msg.from.id) - } - ] - ] - } - }; - const reportRequestMsg = await bot.sendMessage(msg.chat.id, `${langJson[lang].socialConsensus.consensus1}\n\n ${langJson[lang].socialConsensus.consensus2} ${escape(fromUsername)} (ID: ${reportedUserID}) ${langJson[lang].socialConsensus.consensus3}(${rules}) ${langJson[lang].socialConsensus.consensus4}(${msgLink}) ([${langJson[lang].socialConsensus.consensus5}](${msgBackup}))?`, opts); - addReportRequest(db, 'telegram', String(msg.chat.id),reportedUserID,fromUsername,String(msg.reply_to_message.message_id),msgBackup, String(reportRequestMsg.message_id)); + }*/ + /* + if ( reportAllowance === undefined ){ + setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), 2, 15, Math.ceil( new Date().getTime() / 1000)); + } else if ((Math.ceil( new Date().getTime() / 1000) < reportAllowance.timestamp_refresh + 28800) && reportAllowance.report_allowance == 0 ){ + await bot.sendMessage(msg.chat.id, langJson[lang].report.noallowance); + return; } else{ - reportMsg(db, lang, bot, msg, fromUsername, reportedUserID, rules, String(msg.reply_to_message.message_id), msgBackup) - } - + const newReportAllowance = reportAllowance.report_allowance + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800) - 1; + const newEvidenceAllowance = reportAllowance.evidence_allowance + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800)*5; + const newRefreshTimestamp = reportAllowance.timestamp_refresh + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800)*28800; + setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), Math.min(newReportAllowance,3), Math.min(newEvidenceAllowance,15), newRefreshTimestamp); + }*/ + const opts = { + parse_mode: 'Markdown', + reply_markup: { + inline_keyboard: [ + [ + { + text: langJson[settings.lang].socialConsensus.confirm + ' (1/3)', + callback_data: String(msg.reply_to_message.from.id)+'|'+String(msg.reply_to_message.message_id)+'|'+String(msg.from.id) + } + ] + ] + } + }; + const reportRequestMsg = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].socialConsensus.consensus1}\n\n ${langJson[settings.lang].socialConsensus.consensus2} [${escape(fromUsername)}](tg://user?id=${reportedUserID}) ${langJson[settings.lang].socialConsensus.consensus3}(${rules}) ${langJson[settings.lang].socialConsensus.consensus4}(${msgLink}) ([${langJson[settings.lang].socialConsensus.consensus5}](${msgBackup}))?`, opts); return; } - -const reportMsg = async (db: any, lang: string, bot: TelegramBot, msg: TelegramBot.Message, fromUsername: string, reportedUserID: string, rules: string, msgId: string, msgBackup: string) => { +const reportMsg = async (settings: groupSettings, db: any, bot: TelegramBot, msg: TelegramBot.Message, fromUsername: string, reportedUserID: string, rules: string, msgId: string, msgBackup: string, reportedBy: string, batchedSend: any) => { try { + var inviteURL = inviteURLMap.get(msg.chat.id) + if (!inviteURL){ + inviteURL = await getInviteURL(db, 'telegram', String(msg.chat.id)); + if (!inviteURL){ + inviteURL = await bot.exportChatInviteLink(msg.chat.id); + await setInviteURL(db, 'telegram', String(msg.chat.id), inviteURL); + } + inviteURLMap.set(msg.chat.id, inviteURL) + } - const inviteURL = await getInviteURL(db, 'telegram', String(msg.chat.id)); - const inviteURLBackup = inviteURL? inviteURL: await bot.exportChatInviteLink(msg.chat.id); - if (!inviteURL) - await setInviteURL(db, 'telegram', String(msg.chat.id), inviteURLBackup); - const msgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + msgId; - let evidenceIndex = evidenceIndexMap.get(msg.chat.id) + 1; - if (!evidenceIndex){ - evidenceIndex = await getRecordCount(db, 'telegram', String(msg.chat.id)); - evidenceIndexMap.set(msg.chat.id, evidenceIndex); - } else { - evidenceIndexMap.set(msg.chat.id, evidenceIndex); - } + var evidenceIndex = evidenceIndexMap.get(msg.chat.id) + 1; + if (!evidenceIndex) + evidenceIndex = 1//await getRecordCount(db, 'telegram', String(msg.chat.id))+1; + evidenceIndexMap.set(msg.chat.id, evidenceIndex); + const {questionId, questionUrl: appealUrl} = await reportUser( - lang, + batchedSend, + settings.lang, false, fromUsername, reportedUserID, 'Telegram', msg.chat.title, - inviteURLBackup, + inviteURL, String(msg.chat.id), rules, msgLink, - msgBackup); + msgBackup, + reportedBy); - await addReport(db, questionId, "telegram", String(msg.chat.id), reportedUserID, fromUsername , msgId, false, msgBackup, evidenceIndex, 0, msg.reply_to_message.date); - await bot.sendMessage(msg.chat.id, `*${escape(fromUsername)} (ID :${reportedUserID}) *'s conduct due to this [message](${msgLink}) ([backup](${msgBackup})) is reported for breaking the [rules](${rules}).\n\nDid *${escape(fromUsername)}* break the rules? The [question](${appealUrl}) can be answered with a minimum bond of 5 DAI.\n\n To save a record, reply to messages you want saved with the command below,\n/addevidence ${evidenceIndex}`, {parse_mode: 'Markdown'}); + await bot.sendMessage(settings.channelID, `*${escape(fromUsername)} (ID :${reportedUserID}) *'s conduct due to this [message](${msgLink}) ([backup](${msgBackup})) is reported for breaking the [rules](${rules}).\n\nDid *${escape(fromUsername)}* break the rules? The [question](${appealUrl}) can be answered with a minimum bond of 5 DAI.\n\n To save a record, reply to messages you want saved with the command below,\n/addevidence ${evidenceIndex}`, {parse_mode: 'Markdown'}); + return questionId; } catch (e) { console.log(e); - await bot.sendMessage(msg.chat.id, `${langJson[lang].errorTxn}. ${e.reason}. `); + await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].errorTxn}. ${e.reason}. `); return; } } diff --git a/lib/telegram/commands/setChannel.ts b/lib/telegram/commands/setChannel.ts new file mode 100644 index 0000000..3ed2d2e --- /dev/null +++ b/lib/telegram/commands/setChannel.ts @@ -0,0 +1,63 @@ +import * as TelegramBot from "node-telegram-bot-api"; +import {groupSettings} from "../../../types"; +import {setChannelID, setInviteURLChannel} from "../../db"; +import {validateUrl} from "./setRules"; +import langJson from "../assets/lang.json"; + +/* + * /setchannel [public channel name] + */ +const regexp = /\/setchannel/ +const regexpFull = /\/setchannel (.+)/ + +const callback = async (db: any, settings: groupSettings, bot: TelegramBot, botId: string, msg: TelegramBot.Message, match: string[], batchedSend: any) => { + try { + const user = await bot.getChatMember(msg.chat.id, String(msg.from.id)); + if (!(user.status === 'creator' || user.status === 'administrator')) { + await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorAdminOnly); + return; + } + const newmatch = msg.text.match(regexpFull); + if (!newmatch || newmatch.length < 2){ + bot.sendMessage(msg.chat.id, `/setchannel ${langJson[settings.lang].addevidence.error1} ${langJson[settings.lang].addevidence.id}`); + return; + } + try{ + const channel = await bot.getChat(newmatch[1]); + if(channel.type !== "channel"){ + await bot.sendMessage(msg.chat.id, '/setchannel must be followed by a valid channel.'); + return; + } + } catch(e){ + await bot.sendMessage(msg.chat.id, `${newmatch[1]} is not a valid channel.`); + return; + } + const channelUser = await bot.getChatMember(newmatch[1], String(msg.from.id)); + if(channelUser.status !== "administrator" && channelUser.status !== "creator"){ + console.log(channelUser) + await bot.sendMessage(msg.chat.id, 'You are not an authorized admin of the channel.'); + return; + } + const channelUserSusie = await bot.getChatMember(newmatch[1], botId); + if (channelUserSusie.status !== "administrator"){ + await bot.sendMessage(msg.chat.id, 'The channel must have Susie as an admin.'); + bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {caption: langJson[settings.lang].errorAdminRights}); + return; + } + if(!channelUserSusie.can_invite_users){ + await bot.sendMessage(msg.chat.id, 'Susie must be able to invite users to the channel.'); + return; + } + console.log('madeit'); + const invite_url_channel = await bot.exportChatInviteLink(newmatch[1]); + console.log('madeit'); + const result = setInviteURLChannel(db, 'telegram', String(msg.chat.id), invite_url_channel); + console.log('madeit'); + await setChannelID(db, 'telegram', String(msg.chat.id), newmatch[1]); + await bot.sendMessage(msg.chat.id, `Moderation announcement [channel](${invite_url_channel}).`, {parse_mode: "Markdown"}); + } catch (error) { + console.log(error); + } +} + +export {regexp, callback, validateUrl}; \ No newline at end of file diff --git a/lib/telegram/commands/setLanguage.ts b/lib/telegram/commands/setLanguage.ts index 211c12d..85e357e 100644 --- a/lib/telegram/commands/setLanguage.ts +++ b/lib/telegram/commands/setLanguage.ts @@ -1,37 +1,64 @@ import * as TelegramBot from "node-telegram-bot-api"; import {setLang, setRules} from "../../db"; import langJson from "../assets/lang.json"; - +import { groupSettings } from "../../../types"; /* * /setlanguage ? */ const regexp = /\/setlanguage/ const regexpFull = /\/setlanguage (.+)/ -const callback = async (db: any, lang: string, bot: TelegramBot, msg: TelegramBot.Message) => { +const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { const user = await bot.getChatMember(msg.chat.id, String(msg.from.id)); - const match = msg.text.match(regexpFull); - - if (!match || match.length < 2){ - await bot.sendMessage(msg.chat.id, langJson[lang].errorMatchLanguage); + if (!(user.status === 'creator' || user.status === 'administrator')) { + msg.chat.is_forum? await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorAdminOnly, {message_thread_id: msg.message_thread_id}): await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorAdminOnly); return; } + const match = msg.text.match(regexpFull); + const langCode = match? match[1].toLowerCase(): ''; - const langCode = match[1].toLowerCase(); - - if (user.status === 'creator' || user.status === 'administrator') { - if (langJson[langCode]) { - await bot.sendMessage(msg.chat.id, langJson[langCode].confirmationLanguage); - setLang(db, 'telegram', String(msg.chat.id),langCode); - await setRules(db, 'telegram', String(msg.chat.id), langJson[lang].defaultRules, Math.floor(Date.now()/1000)); - await bot.sendMessage(msg.chat.id, `${langJson[lang].defaultRulesMsg1}(${langJson[lang].defaultRules}). ${langJson[lang].defaultRulesMsg2}.`, {parse_mode: "Markdown"}); - - } else { - await bot.sendMessage(msg.chat.id, `${langCode} `+ langJson[lang].errorLanguage); - } + if (langJson[langCode]) { + setLanguageConfirm(db, bot, settings, langCode, msg) } else { - await bot.sendMessage(msg.chat.id, langJson[lang].errorAdminOnly); + const errorLanguage = `The language you requested is not yet available. Head to @SusieSupportChannel or linguo for information on how to add more translations!` + await bot.sendMessage(msg.chat.id, errorLanguage, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + const opts = msg.chat.is_forum? { + message_thread_id: msg.message_thread_id, + parse_mode: 'Markdown', + reply_markup: { + inline_keyboard: [ + [ + { + text: 'English', + callback_data: 'en' + } + ] + ] + } + }: { + parse_mode: 'Markdown', + reply_markup: { + inline_keyboard: [ + [ + { + text: 'English', + callback_data: 'en' + } + ] + ] + } + } + await bot.sendMessage(msg.chat.id,'List of available languages',opts) } } -export {regexp, callback}; \ No newline at end of file +const setLanguageConfirm = async (db: any, bot: any, settings: groupSettings, langCode: string, msg: any) => { + setLang(db, 'telegram', String(msg.chat.id),langCode); + setRules(db, 'telegram', String(msg.chat.id), langJson[langCode].defaultRules, Math.floor(Date.now()/1000)); + bot.sendMessage(msg.chat.id, langJson[langCode].confirmationLanguage, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + const msgDefaultRules = await bot.sendMessage(msg.chat.id, `${langJson[langCode].defaultRulesMsg1}(${langJson[langCode].defaultRules}). ${langJson[settings.lang].defaultRulesMsg2}.`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: settings.thread_id_rules}: {}) + const msgRules = await bot.forwardMessage(msg.chat.id, msg.chat.id, msgDefaultRules.message_id, {message_thread_id: settings.thread_id_rules}); + bot.pinChatMessage(msg.chat.id, msgRules.message_id, {message_thread_id: settings.thread_id_rules}) +} + +export {regexp, callback, setLanguageConfirm}; \ No newline at end of file diff --git a/lib/telegram/commands/setRules.ts b/lib/telegram/commands/setRules.ts index c2386f4..7c5f0c7 100644 --- a/lib/telegram/commands/setRules.ts +++ b/lib/telegram/commands/setRules.ts @@ -1,4 +1,5 @@ import * as TelegramBot from "node-telegram-bot-api"; +import { groupSettings } from "../../../types"; import {setRules} from "../../db"; import {ipfsPublish} from "../../ipfs-publish"; import langJson from "../assets/lang.json"; @@ -17,28 +18,35 @@ const validateUrl = (s: string): boolean => { } }; -const callback = async (db: any, lang: string, bot: TelegramBot, msg: TelegramBot.Message, match: string[]) => { - const user = await bot.getChatMember(msg.chat.id, String(msg.from.id)); - - if (user.status === 'creator' || user.status === 'administrator') { - if (msg.reply_to_message) { - const enc = new TextEncoder(); - - const rulesPath = await ipfsPublish('rules.txt', enc.encode(msg.reply_to_message.text)) - - await setRules(db, 'telegram', String(msg.chat.id), 'https://ipfs.kleros.io'+rulesPath, new Date().getTime()/1000); - - await bot.sendMessage(msg.chat.id, langJson[lang].rulesUpdated); - } else { - if (validateUrl(match[1])) { - await setRules(db, 'telegram', String(msg.chat.id), match[1], Math.floor(new Date().getTime()/1000)); - await bot.sendMessage(msg.chat.id, langJson[lang].rulesUpdated); +const callback = async (db: any, settings: groupSettings, bot: any, botId: string, msg: any, match: string[]) => { + try{ + const user = await bot.getChatMember(msg.chat.id, String(msg.from.id)); + const chat = await bot.getChat(msg.chat.id); + if (user.status === 'creator' || user.status === 'administrator') { + if (msg.reply_to_message && !msg.reply_to_message.forum_topic_created) { + const enc = new TextEncoder(); + const rulesPath = await ipfsPublish('rules.txt', enc.encode(msg.reply_to_message.text)) + setRules(db, 'telegram', String(msg.chat.id), 'https://ipfs.kleros.io'+rulesPath, new Date().getTime()/1000); + bot.sendMessage(msg.chat.id, `The community rules are [updated](https://ipfs.kleros.io${rulesPath}).`, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules, parse_mode: 'Markdown'}: {parse_mode: "Markdown"}); + if(msg.chat.is_forum){ + const msgRules = await bot.forwardMessage(msg.chat.id, msg.chat.id, msg.reply_to_message.message_id, {message_thread_id: settings.thread_id_rules}); + bot.pinChatMessage(msg.chat.id, msgRules.message_id, {message_thread_id: settings.thread_id_rules}) + } + } else if (validateUrl(match[1])) { + setRules(db, 'telegram', String(msg.chat.id), match[1], Math.floor(new Date().getTime()/1000)); + if(msg.chat.is_forum){ + const msgRules = await bot.forwardMessage(msg.chat.id, msg.chat.id, msg.message_id, {message_thread_id: settings.thread_id_rules}); + bot.pinChatMessage(msg.chat.id, msgRules.message_id, {message_thread_id: settings.thread_id_rules}) + } + await bot.sendMessage(msg.chat.id, langJson[settings.lang].rulesUpdated, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules}: {}); } else { - await bot.sendMessage(msg.chat.id, langJson[lang].errorRules); + await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorRules, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules}: {}); } + } else { + await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorAdminOnly, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); } - } else { - await bot.sendMessage(msg.chat.id, langJson[lang].errorAdminOnly); + } catch(e){ + console.log(e) } } diff --git a/lib/telegram/commands/socialConsensus.ts b/lib/telegram/commands/socialConsensus.ts index 78f7f55..1875f2e 100644 --- a/lib/telegram/commands/socialConsensus.ts +++ b/lib/telegram/commands/socialConsensus.ts @@ -1,81 +1,61 @@ import * as TelegramBot from "node-telegram-bot-api"; -import {getRule, getAllowance, setAllowance, setAllowanceAsked, getReportRequest, getQuestionId} from "../../db"; +import { getQuestionId } from "../../graph"; import {reportMsg} from "./report"; import langJson from "../assets/lang.json"; +import { groupSettings } from "../../../types"; const escape = require('markdown-escape') /* * /getrules */ -const callback = async (db: any, lang: string, bot: any, callbackQuery: TelegramBot.CallbackQuery) => { +const callback = async (db: any, settings: groupSettings, botaddress: string, bot: TelegramBot, callbackQuery: TelegramBot.CallbackQuery, batchedSend: any) => { const rawCalldata = callbackQuery.data; const calldata = rawCalldata.split('|'); const match = callbackQuery.message.reply_markup.inline_keyboard[0][0].text; - const msg = callbackQuery.message; - const user = await bot.getChatMember(msg.chat.id, String(callbackQuery.from.id)); - const isAdmin = user.status === 'creator' || user.status === 'administrator'; - - if (!isAdmin){ - if (callbackQuery.from.id == Number(calldata[1])) { - return; - } - - if (calldata.length > 2 && callbackQuery.from.id == Number(calldata[2])){ - return; - } - const reportAllowance = await getAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id)); - if ( reportAllowance === undefined ){ - setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), 2, 15, Math.ceil( new Date().getTime() / 1000)); - } else if ((Math.ceil( new Date().getTime() / 1000) < reportAllowance.timestamp_refresh + 28800) && reportAllowance.report_allowance == 0 ){ - return; - } else{ - const newReportAllowance = reportAllowance.report_allowance + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800) - 1; - const newEvidenceAllowance = reportAllowance.evidence_allowance + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800)*5; - const newRefreshTimestamp = reportAllowance.timestamp_refresh + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800)*28800; - setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), Math.min(newReportAllowance,3), Math.min(newEvidenceAllowance,15), newRefreshTimestamp); - } - } - + const msg: any = callbackQuery.message; const newConfirmations = Number(match.substring(9,10)) + 1; - const opts = { - chat_id: msg.chat.id, - message_id: msg.message_id, - parse_mode: 'Markdown', - reply_markup: { + if (callbackQuery.from.id == Number(calldata[2])) + return; + //if (calldata.length > 3 && callbackQuery.from.id == Number(calldata[3])) + // return; + + const markdown = { inline_keyboard: [ [ { - text: langJson[lang].socialConsensus.confirm + '('+newConfirmations+'/3)', + text: langJson[settings.lang].socialConsensus.confirm + '('+newConfirmations+'/3)', callback_data: rawCalldata+'|'+String(callbackQuery.from.id) } ] ] - } - }; - const reportRequest = await getReportRequest(db, 'telegram', String(msg.chat.id),calldata[0]); + }; + const opts = msg.chat.is_forum? { + chat_id: msg.chat.id, + message_id: msg.message_id, + } : { + chat_id: msg.chat.id, + message_id: msg.message_id, + message_thread_id: msg.message_thread_id + } //todo proper rule chronology - const rules = await getRule(db, 'telegram', String(msg.chat.id), Math.floor(Date.now()/1000)); - const msgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + String(reportRequest.msg_id); - - if (newConfirmations > 2){ - const reportedQuestionId = await getQuestionId(db, 'telegram', String(msg.chat.id), reportRequest.user_id, String(reportRequest.msg_id)); + if (newConfirmations > 1){ + const reportedQuestionId = await getQuestionId(botaddress, 'Telegram', String(msg.chat.id), String(calldata[0]), String(calldata[1])); + if (reportedQuestionId){ + return; + } if (reportedQuestionId) - await bot.sendMessage(msg.chat.id, `${langJson[lang].socialConsensus.reported}(https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITITY_ETH_V30}-${reportedQuestionId})`, {parse_mode: 'Markdown'}); + await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].socialConsensus.reported}(https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${reportedQuestionId})`, {parse_mode: 'Markdown'}); else{ - const optsFinal = { - chat_id: msg.chat.id, - message_id: msg.message_id, - }; - bot.editMessageText(langJson[lang].socialConsensus.reportConfirm, optsFinal); - const questionId = await reportMsg(db, bot, msg, reportRequest.username, reportRequest.user_id, rules, reportRequest.msg_id, reportRequest.msgBackup); - setAllowanceAsked(db, questionId, 'telegram', String(msg.chat.id), calldata[1]); - setAllowanceAsked(db, questionId, 'telegram', String(msg.chat.id), calldata[2]); - setAllowanceAsked(db, questionId, 'telegram', String(msg.chat.id), String(callbackQuery.from.id)); + bot.deleteMessage(msg.chat.id, String(msg.message_id)) + const user = (await bot.getChatMember(String(msg.chat.id), String(calldata[0]))).user; + const fromUsername = escape(user.username || user.first_name || `no-username-set`); + await reportMsg(settings, db, bot, msg, fromUsername, String(calldata[0]), msg.entities[0].url, String(calldata[1]), msg.entities[2].url, calldata[2],batchedSend); } - } else - bot.editMessageText(`${langJson[lang].socialConsensus.consensus1}\n\n ${langJson[lang].socialConsensus.consensus2} ${escape(reportRequest.username)} (ID: ${reportRequest.user_id}) ${langJson[lang].socialConsensus.consensus3}(${rules}) due to conduct over this [message]${langJson[lang].socialConsensus.consensus4}(${msgLink}) ([${langJson[lang].socialConsensus.consensus5}](${reportRequest.msgBackup}))?`, opts); + } else{ + bot.editMessageReplyMarkup(markdown, opts) + } } export {callback}; \ No newline at end of file diff --git a/lib/telegram/commands/start.ts b/lib/telegram/commands/start.ts new file mode 100644 index 0000000..b51aa10 --- /dev/null +++ b/lib/telegram/commands/start.ts @@ -0,0 +1,67 @@ +import * as TelegramBot from "node-telegram-bot-api"; +import {setThreadID, getThreadIDNotifications, dbstart, setRules} from "../../db"; +import langJson from "../assets/lang.json"; +import {groupSettings} from "../../../types"; + +/* + * /start + */ +const regexp = /\/start/ + +const callback = async (db: any, settings: groupSettings, bot: any, botID: string, msg: any) => { + // admin check + try{ + console.log(msg) + const requestUser = await bot.getChatMember(msg.chat.id, msg.from.id) + if (requestUser.status !== "administrator" && requestUser.status !== "creator"){ + bot.sendMessage(settings.channelID, "Please ask an admin to start Susie's community moderation."); + return; + } + const botUser = await bot.getChatMember(msg.chat.id, botID) + if(botUser.status !== "administrator" || !botUser.can_restrict_members){ + bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', msg.chat.is_forum? {message_thread_id: msg.message_thread_id, caption: "Please give Susie full admin rights.\n\nThen try to /start community moderation again."} : {caption: "Please give Susie full admin rights.\n\nThen try to /start community moderation again."}); + return; + } + if (msg.chat.is_forum){ + if(!botUser.can_manage_topics){ + bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {message_thread_id: msg.message_thread_id, caption: "Must have can manage topics"}); + return; + } + const thread_ids = getThreadIDNotifications(db, 'telegram', String(msg.chat.id)); + if (thread_ids){ + bot.sendMessage(msg.chat.id, "Already started."); + } + await topicMode(db,bot,settings,String(msg.chat.id)); + } + dbstart(db, 'telegram', String(msg.chat.id)) + setRules(db, 'telegram', String(msg.chat.id), langJson[settings.lang].defaultRules, Math.floor(Date.now()/1000)); + bot.sendMessage(msg.chat.id, "I am now moderating this community.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + return; + } catch (e){ + try{ + if (msg.chat.is_forum){ + bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {message_thread_id: msg.message_thread_id, caption: "Must have can manage topics"}); + } else{ + bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {caption: langJson[settings.lang].errorAdminRights+"Topics must be enabled"}); + } + } catch (e){ + console.log(e) + } + } +} + +const topicMode = async (db:any, bot: any, settings: groupSettings, chat_id: string): Promise<[string,string]> => { + // tg bugging, won't display icon_color if set + const topicRules = await bot.createForumTopic(chat_id, 'Rules', {icon_custom_emoji_id: '4929691942553387009'}); + const topicModeration = await bot.createForumTopic(chat_id, 'Moderation', {icon_custom_emoji_id: '4929336692923432961'}); + + bot.sendMessage(settings.channelID, `Please refer to the moderation topic for notifications, and the rules topic for rules. `); + bot.sendMessage(chat_id, `${langJson[settings.lang].defaultRulesMsg1alt}. ${langJson[settings.lang].defaultRulesMsg2}.`, {parse_mode: "Markdown", message_thread_id: topicRules.message_thread_id}); + //bot.sendMessage(chat_id, `${langJson[settings.lang].greeting2}(${settings.rules}). ${langJson[settings.lang].greeting3}`, {parse_mode: "Markdown", message_thread_id: topicRules.message_thread_id}); + bot.sendMessage(chat_id, `${langJson[settings.lang].greeting1}[Kleros Moderate](https://kleros.io/moderate/).`, {parse_mode: "Markdown", message_thread_id: topicModeration.message_thread_id}); + bot.closeForumTopic(chat_id, topicRules.message_thread_id) + setThreadID(db,'telegram',chat_id,String(topicRules.message_thread_id), String(topicModeration.message_thread_id)) + return [topicRules.message_thread_id, topicModeration.message_thread_id] +} + +export {regexp, callback, topicMode}; \ No newline at end of file diff --git a/lib/telegram/commands/toggleWelcome.ts b/lib/telegram/commands/toggleWelcome.ts new file mode 100644 index 0000000..8463b21 --- /dev/null +++ b/lib/telegram/commands/toggleWelcome.ts @@ -0,0 +1,31 @@ +import * as TelegramBot from "node-telegram-bot-api"; +import {setGreetingMode, setThreadIDWelcome} from "../../db"; +import langJson from "../assets/lang.json"; +import {groupSettings} from "../../../types"; + +/* + * /welcome + */ +const regexp = /\/welcome/ + +const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { + try{ + const user = await bot.getChatMember(msg.chat.id, String(msg.from.id)); + if (!(user.status === 'creator' || user.status === 'administrator')) { + await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorAdminOnly, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + return; + } + if (msg.chat.is_forum){ + const topicWelcome = await bot.createForumTopic(msg.chat.id, 'Welcome', {icon_custom_emoji_id: '4929292553544531969'}); + const msg1: TelegramBot.Message = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].greeting1}[Kleros Moderate](https://kleros.io/moderate/).`, {parse_mode: "Markdown", message_thread_id: topicWelcome.message_thread_id}); + bot.pinChatMessage(msg.chat.id, msg1.message_id, {message_thread_id: topicWelcome.message_thread_id}) + setThreadIDWelcome(db, 'telegram', String(msg.chat.id), String(topicWelcome.message_thread_id)) + } + setGreetingMode(db, 'telegram', String(msg.chat.id),settings.greeting_mode? 0: 1) + await bot.sendMessage(msg.chat.id, settings.greeting_mode? "Welcome messages are on." : "Welcome messages are off.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + } catch(e){ + console.log(e) + } +} + +export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/welcome.ts b/lib/telegram/commands/welcome.ts index b831341..92a2eea 100644 --- a/lib/telegram/commands/welcome.ts +++ b/lib/telegram/commands/welcome.ts @@ -1,19 +1,19 @@ import * as TelegramBot from "node-telegram-bot-api"; -import {setRules, getRule} from "../../db"; import langJson from "../assets/lang.json"; +import { groupSettings } from "./types"; /* * Welcome Message */ -const callback = async (db: any, lang: string, bot: TelegramBot, myChatMember: TelegramBot.ChatMemberUpdated) => { +const callback = async (settings: groupSettings, bot: any, msg: any) => { try { - const rules = await getRule(db, 'telegram', String(myChatMember.chat.id), Math.floor(Date.now()/1000)); - - if (!rules){ - await bot.sendMessage(myChatMember.chat.id, `${langJson[lang].defaultRulesMsg1}(${langJson[lang].defaultRules}). ${langJson[lang].defaultRulesMsg2}.`, {parse_mode: "Markdown"}); - await setRules(db, 'telegram', String(myChatMember.chat.id), langJson[lang].defaultRules, Math.floor(Date.now()/1000)); - } + if (msg.old_chat_member.status !== "left") + return; + const message = `${langJson[settings.lang].welcome}[Kleros Moderate](https://kleros.io/moderate/) bot. \n\n/start to begin community sourced moderation.`; + bot.sendMessage(msg.chat.id, `${langJson[settings.lang].welcome}[Kleros Moderate](https://kleros.io/moderate/) bot. \n\n/start to begin community sourced moderation.`, msg.chat.is_forum? {parse_mode: "Markdown"} : {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}); + //const options = msg.chat.is_forum? {message_thread_id: msg.message_thread_id, caption: "To get started, give Susie admin rights."} : {caption: "To get started, give Susie admin rights."} + //bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', options); } catch (error) { console.log(error); } diff --git a/lib/telegram/index.ts b/lib/telegram/index.ts index 236a4fa..3255ae0 100644 --- a/lib/telegram/index.ts +++ b/lib/telegram/index.ts @@ -5,52 +5,93 @@ import * as setRulesCommand from "../../lib/telegram/commands/setRules"; import * as getRules from "../../lib/telegram/commands/getRules"; import * as report from "../../lib/telegram/commands/report"; import * as welcome from "../../lib/telegram/commands/welcome"; +import * as toggleWelcome from "../../lib/telegram/commands/toggleWelcome"; import * as greeting from "../../lib/telegram/commands/greeting"; import * as socialConsensus from "../../lib/telegram/commands/socialConsensus"; import * as addEvidence from "../../lib/telegram/commands/addEvidence"; +import * as start from "../../lib/telegram/commands/start"; import * as setLanguage from "../../lib/telegram/commands/setLanguage"; +import * as setChannel from "../../lib/telegram/commands/setChannel"; import * as getReports from "../../lib/telegram/commands/getReports"; import langJson from "./assets/lang.json"; -import {openDb, getLang, setLang, getRule, setRules} from "../db"; +import {groupSettings} from "../../types"; +import {openDb, getGroupSettings, eraseThreadID, dbstart, dbstarted} from "../db"; +import {Wallet} from "@ethersproject/wallet"; +const Web3 = require('web3') +const _batchedSend = require('web3-batched-send') +const web3 = new Web3(process.env.WEB3_PROVIDER_URL) +const batchedSend = _batchedSend( + web3, + process.env.TRANSACTION_BATCHER_CONTRACT_ADDRESS, + process.env.PRIVATE_KEY, + 20000 // The debounce timeout period in milliseconds in which transactions are batched. + ) +var botAddress: string; const ModeratorBot = require('node-telegram-bot-api'); -const bot: TelegramBot = new ModeratorBot(process.env.BOT_TOKEN, {polling: true}); +const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: true, testEnvironment: false}); +//bot. +var botId: number; const db = openDb(); -const whitelist = ['-1001711792724', '-1001612151117', '-1001151472172', '-1001585259197']; -let warnMsg : Map = new Map(); -let lang : Map = new Map(); +const started : Map = new Map(); +const settings : Map = new Map(); +// Throttling +const msgCounters : Map = new Map(); +const lastMsgEpochs : Map = new Map(); -bot.on("my_chat_member", async function(myChatMember: TelegramBot.ChatMemberUpdated) { +bot.on("my_chat_member", async function(myChatMember: any) { try{ - if (!await validate(myChatMember.chat.id)) - return; - const language = lang?.get(myChatMember.chat.id); - await welcome.callback(db, language, bot, myChatMember); - } catch(error){ - console.log(error); - console.log("Welcome error."); + console.log(myChatMember) + if(myChatMember.chat.is_forum){ + return; + } + const settings = validate(myChatMember.chat); + + if(myChatMember.chat.type === "channel"){ + try{ + bot.sendMessage(myChatMember.chat.id, "The channel id is " + myChatMember.chat.id); + } catch(e) { + console.log(e) + } + return; + } + await welcome.callback(settings, bot, myChatMember); + } catch(e){ + console.log("Welcome error." + e); } }); -bot.on("new_chat_members", async function (msg: any) { - try{ - if (!await validate(msg.chat.id)) - return; - const language = lang?.get(msg.chat.id); - await greeting.callback(db, language, bot, msg); - } catch(error){ - console.log(error); - console.log("New chat member error."); +bot.on("new_chat_members", async function (chatMemberUpdated: any) { + console.log('new chat member') + const settings = validate(chatMemberUpdated.chat); + if(!started.has(chatMemberUpdated.chat.id)) + return; + if (chatMemberUpdated.chat.type === "channel"){ + return; } + + if (settings.greeting_mode) + await greeting.callback(bot, settings, chatMemberUpdated); }); // Handle callback queries bot.on('callback_query', async function onCallbackQuery(callbackQuery: TelegramBot.CallbackQuery) { try{ - if (!await validate(callbackQuery.message.chat.id)) + if(!botAddress) + botAddress = (await new Wallet(process.env.PRIVATE_KEY)).address; + if(!started.has(callbackQuery.message.chat.id)) return; - const language = lang?.get(callbackQuery.message.chat.id); - await socialConsensus.callback(db, language, bot, callbackQuery); + const settings = validate(callbackQuery.message.chat); + + if (callbackQuery.data.length < 3){ + const user = await bot.getChatMember(callbackQuery.message.chat.id, String(callbackQuery.from.id)) + if (user.status !== "creator" && user.status !== "administrator") + return; + bot.deleteMessage(callbackQuery.message.chat.id, String(callbackQuery.message.message_id)) + setLanguage.setLanguageConfirm(db, bot, settings, callbackQuery.data, callbackQuery.message); + } + else + await socialConsensus.callback(db, settings, botAddress, bot, callbackQuery, batchedSend); } catch(error){ console.log(error); console.log("Social Consensus Error"); @@ -62,6 +103,9 @@ const commands: {regexp: RegExp, callback: any}[] = [ setRulesCommand, getRules, report, + toggleWelcome, + start, + setChannel, addEvidence, getReports, setLanguage, @@ -70,69 +114,92 @@ const commands: {regexp: RegExp, callback: any}[] = [ commands.forEach((command) => { bot.onText( command.regexp, - async (msg: TelegramBot.Message, match: string[]) => { - try{ - if (!await validate(msg.chat.id)) - return; - const language = lang?.get(msg.chat.id); - command.callback(db, language, bot, msg, match); - if(command == setLanguage){ - var currentLang = getLang(db, 'telegram', String(msg.chat.id)); - if (currentLang !== language){ - lang.set(msg.chat.id, language); + async (msg: any, match: string[]) => { + const groupSettings = validate(msg.chat); + + if (command === start){ + if (started.has(msg.chat.id)){ + try{ + bot.sendMessage(msg.chat.id, "Susie is already moderating this community.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id} : {}) + return + } catch(e){ + console.log(e) } } - - } catch (err){ - console.log(`${command.regexp} command error.`); - console.log(err); + } else if(!started.has(msg.chat.id)){ + return; } + + if (!botId) + botId = (await bot.getMe()).id; + + command.callback(db, groupSettings, bot, botId, msg, match,batchedSend); + if (command === setLanguage || command === setRulesCommand || command === setChannel || command === toggleWelcome || command === start) + settings.delete(msg.chat.id) } ) }) +const throttling = (chat: TelegramBot.Chat): boolean => { + const lastEpoch = lastMsgEpochs.get(chat.id) ?? 0; + const currentEpoch = Math.floor(Date.now()/1000) % 60; + if (currentEpoch > lastEpoch){ + lastMsgEpochs.set(chat.id, currentEpoch); + msgCounters.set(chat.id,1); + } + const msgCounter = msgCounters.get(chat.id); + if (msgCounter > 20) + return false; + msgCounters.set(chat.id,msgCounter+1); + return true; -const validate = async (chatId: number): Promise => { - var language = lang?.get(chatId); - if (!language){ - var currentLang = getLang(db, 'telegram', String(chatId)); - if (!langJson[currentLang]) { - setLang(db, 'telegram', String(chatId),'en'); - currentLang = 'en'; - } - if (currentLang !== language){ - language = currentLang; - lang.set(chatId, language); +} + +const validate = (chat: any): groupSettings=> { + var groupSettings : groupSettings = settings.get(chat.id) + if (!groupSettings){ + groupSettings = getGroupSettings(db, 'telegram', String(chat.id)) + console.log ('groupSettings fetched from db'); + console.log(groupSettings) + if(groupSettings){ + settings.set(chat.id, groupSettings) + started.set(chat.id, true) } } + /* + if (groupSettings && !chat.is_forum && groupSettings.thread_id_notifications){ // turn topics off + eraseThreadID(db, 'telegram', String(chat.id)) + groupSettings.thread_id_notifications = '' + groupSettings.thread_id_rules = '' + groupSettings.thread_id_welcome = '' + settings.set(chat.id, groupSettings) + }*/ + const fullSettings = { + lang: groupSettings?.lang ?? 'en', + rules: groupSettings?.rules ?? langJson['en'].defaultRules, + channelID: groupSettings?.channelID ?? String(chat.id), + greeting_mode: groupSettings?.greeting_mode ?? false, + thread_id_rules: groupSettings?.thread_id_rules ?? '', + thread_id_welcome: groupSettings?.thread_id_welcome ?? '', + thread_id_notifications: groupSettings?.thread_id_notifications ?? '' + } + console.log(fullSettings); + return fullSettings +} - const botUser = await bot.getChatMember(chatId, String((await bot.getMe()).id)); - if (botUser.can_send_messages == false){ - return false; - } else if (botUser.status != "administrator" || botUser.can_restrict_members != true || botUser.can_invite_users != true){ - const previousMsgId = warnMsg?.get(chatId); - if (previousMsgId){ - bot.deleteMessage(chatId, String(previousMsgId[0])); - bot.deleteMessage(chatId, String(previousMsgId[1])); +const checkMigration = async (groupSettings: groupSettings, chat: any): Promise => { + if (chat.is_forum && !groupSettings.thread_id_notifications){ // turn topics on + try{ + const threads = await start.topicMode(db, bot, groupSettings, String(chat.id)); + groupSettings.thread_id_rules = threads[0] + groupSettings.thread_id_notifications = threads[1] + groupSettings.channelID = String(chat.id) + settings.set(chat.id, groupSettings) + } catch(e){ + console.log(e) } - const msg1 = await bot.sendVideo(chatId, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4'); - const msg2 = await bot.sendMessage(chatId, langJson[language].errorAdminRights); - warnMsg.set(chatId, [msg1.message_id, msg2.message_id]); - - return false; - } else - return true; + } + return groupSettings } -const whitelisted = async (chatId: number): Promise => { - const botUser = await bot.getChatMember(chatId, String((await bot.getMe()).id)); - if (botUser.can_send_messages == false){ - return false; - } else if (!whitelist.includes(String(chatId))){ - await bot.sendMessage(chatId, `The hosted Kleros Moderate service is in beta. This chat id ${chatId} is not whitelisted. Submit an [interest form](https://forms.gle/3Yteu5YFTZoWGhXv7) to get whitelisted, or self-host the [bot](https://github.com/kleros/kleros-moderate).`, {parse_mode: 'Markdown'}); - return false; - } else - return true; - } - console.log('Telegram bot ready...'); \ No newline at end of file diff --git a/types.d.ts b/types.d.ts index 05cddbd..cd29b82 100644 --- a/types.d.ts +++ b/types.d.ts @@ -1,3 +1,12 @@ import * as TelegramBot from "node-telegram-bot-api"; -type CommandCallback = (bot: TelegramBot, msg: TelegramBot.Message, match: string[]) => void; \ No newline at end of file +type CommandCallback = (bot: TelegramBot, msg: TelegramBot.Message, match: string[]) => void; +interface groupSettings { + lang: string; + rules: string; + channelID: string; + thread_id_rules: string; + thread_id_notifications: string; + thread_id_welcome: string; + greeting_mode: boolean; + } \ No newline at end of file From e0744036b1ef2db421521c034122e4879eb3597c Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Tue, 22 Nov 2022 22:56:16 -0800 Subject: [PATCH 004/111] feat(tg): federation and caching --- lib/bot-core.ts | 10 +- lib/create-db.ts | 103 +++++++--- lib/db.ts | 209 ++++++++++++++++++-- lib/graph.ts | 29 ++- lib/telegram/commands/addEvidence.ts | 62 +++--- lib/telegram/commands/getAccount.ts | 9 +- lib/telegram/commands/getReports.ts | 53 +++--- lib/telegram/commands/getRules.ts | 6 +- lib/telegram/commands/joinfed.ts | 20 ++ lib/telegram/commands/leavefed.ts | 20 ++ lib/telegram/commands/report.ts | 232 ++++++++++++----------- lib/telegram/commands/setChannel.ts | 7 +- lib/telegram/commands/setLanguage.ts | 9 +- lib/telegram/commands/setRules.ts | 36 ++-- lib/telegram/commands/socialConsensus.ts | 53 +++--- lib/telegram/commands/start.ts | 13 +- lib/telegram/commands/toggleWelcome.ts | 7 +- lib/telegram/index.ts | 195 +++++++++++-------- 18 files changed, 691 insertions(+), 382 deletions(-) create mode 100644 lib/telegram/commands/joinfed.ts create mode 100644 lib/telegram/commands/leavefed.ts diff --git a/lib/bot-core.ts b/lib/bot-core.ts index 4c1c787..6bd387d 100644 --- a/lib/bot-core.ts +++ b/lib/bot-core.ts @@ -32,10 +32,6 @@ export const reportUser = async (batchedSend:any, lang: string, hasBanningPermis minBond ); - if(hasBanningPermission){ - //await answerQuestion(questionId, privateKey); - } - return { questionId: questionId, questionUrl: `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${questionId}` @@ -45,13 +41,11 @@ export const reportUser = async (batchedSend:any, lang: string, hasBanningPermis async function askQuestionWithMinBond(batchedSend: any, lang: string, fromUsername: string, UserID: string, platform: string, group: string, inviteURL: string, groupID: string, rulesUrl: string|BigNumber, message: string, messageBackup: string, reportedBy: string, minBond: number|BigNumber): Promise { // A question is automatically created in Realitio with an answer in favor of banning the user. - // Bond of the answer: 1 xDAI (initially the answer can be omitted). - const realityETHV30 = getRealityETHV30(process.env.REALITY_ETH_V30, process.env.PRIVATE_KEY); + //const realityETHV30 = getRealityETHV30(process.env.REALITY_ETH_V30, process.env.PRIVATE_KEY); const delim = '\u241f'; - const category = 'misc'; const openingTs = Math.floor(new Date().getTime()/1000); - const question = fromUsername+delim+UserID+delim+platform+delim+group+delim+inviteURL+delim+groupID+delim+rulesUrl+delim+message+delim+messageBackup+delim+category+delim+lang+delim+reportedBy; + const question = fromUsername+delim+UserID+delim+platform+delim+group+delim+inviteURL+delim+groupID+delim+rulesUrl+delim+message+delim+messageBackup+delim+reportedBy; const arbitrator = process.env.REALITIO_ARBITRATOR; const templateId = process.env.TEMPLATE_ID; const timeout = 86400; diff --git a/lib/create-db.ts b/lib/create-db.ts index 5c1b586..af034e6 100644 --- a/lib/create-db.ts +++ b/lib/create-db.ts @@ -12,21 +12,41 @@ const Database = require('better-sqlite3'); * `address` is the address of the bot assigned to this group. */ await db.exec( - `CREATE TABLE groups ( - platform TEXT, - group_id TEXT, - channel_id TEXT, - thread_id_rules TEXT, - thread_id_notifications TEXT, - thread_id_welcome TEXT, - invite_url TEXT, - invite_url_channel TEXT, - greeting_mode INTEGER, - lang TEXT, - rules TEXT - PRIMARY KEY (platform, group_id))` - ); + `CREATE TABLE groups ( + platform TEXT, + group_id TEXT, + channel_id TEXT, + thread_id_rules TEXT, + thread_id_notifications TEXT, + thread_id_welcome TEXT, + invite_url TEXT, + invite_url_channel TEXT, + federation_owner_user_id TEXT, + greeting_mode INTEGER, + lang TEXT, + rules TEXT, + PRIMARY KEY (platform, group_id))` + ); + /** + * `question_id` is the id of the question in reality.eth + * `platform` can be `telegram`, `reddit`, etc. + * `group_id` is the id of the group on the platform (eg. group on telegram, subreddit on reddit, etc.). + * `user_id` is the id of the banned user in `platform`. + * `chat_id` is the id of the banned user in `platform`. + * `active` indicates whether the user is currently banned. + * `finalized` indicates if the question has finalized. + */ + await db.exec( + `CREATE TABLE allowance ( + platform TEXT, + group_id TEXT, + user_id TEXT, + report_allowance INTEGER, + evidence_allowance INTEGER, + timestamp_refresh INTEGER, + PRIMARY KEY (platform, group_id, user_id))` + ); /** * `platform` can be `telegram`, `reddit`, etc. @@ -34,13 +54,52 @@ const Database = require('better-sqlite3'); * `rules` the group rules. eg ipfs cid string. * `timestamp` the timestamp when the rules were set. */ - await db.exec( - `CREATE TABLE rules ( - platform TEXT, - group_id TEXT, - rules TEXT, - timestamp INTEGER, - PRIMARY KEY (platform, group_id, timestamp))` - ); + await db.exec( + `CREATE TABLE rules ( + platform TEXT, + group_id TEXT, + rules TEXT, + timestamp INTEGER, + PRIMARY KEY (platform, group_id, timestamp))` + ); + + /** + * `question_id` is the id of the question in reality.eth + * `platform` can be `telegram`, `reddit`, etc. + * `group_id` is the id of the group on the platform (eg. group on telegram, subreddit on reddit, etc.). + * `user_id` is the id of the banned user in `platform`. + * `chat_id` is the id of the banned user in `platform`. + * `active` indicates whether the user is currently banned. + * `finalized` indicates if the question has finalized. + */ + await db.exec( + `CREATE TABLE reports ( + question_id TEXT PRIMARY KEY, + platform TEXT, + group_id TEXT, + user_id TEXT, + msg_id TEXT, + timestamp INTEGER, + evidenceIndex INTEGER + )` + ); + + /** + * `question_id` is the id of the question in reality.eth + * `platform` can be `telegram`, `reddit`, etc. + * `group_id` is the id of the group on the platform (eg. group on telegram, subreddit on reddit, etc.). + * `user_id` is the id of the banned user in `platform`. + * `chat_id` is the id of the banned user in `platform`. + * `active` indicates whether the user is currently banned. + * `finalized` indicates if the question has finalized. + */ + await db.exec( + `CREATE TABLE federations ( + platform TEXT, + owner_user_id TEXT, + group_id TEXT[], + PRIMARY KEY (platform, owner_user_id))` + ); + db.close(); })(); \ No newline at end of file diff --git a/lib/db.ts b/lib/db.ts index 0ed78ce..37ac008 100644 --- a/lib/db.ts +++ b/lib/db.ts @@ -1,5 +1,5 @@ const Database = require('better-sqlite3'); -import { groupSettings } from "../types"; +import { groupSettingsUnderspecified } from "../types"; export function openDb() { const db = new Database('database.db'); @@ -21,6 +21,34 @@ const setLang = (db: any, platform: string, groupId: string, lang: string) => { } } +const joinFederation = (db: any, platform: string, groupId: string, owner_user_id: string) => { + try{ + const stmt = db.prepare( + `INSERT INTO groups (platform, group_id, owner_user_id) + VALUES (?, ?, ?) + ON CONFLICT(platform, group_id) DO UPDATE SET + owner_user_id=?;`); + const info = stmt.run(platform, groupId, owner_user_id, owner_user_id); + } catch(err) { + console.log("db error: joinFederation"); + console.log(err); + } +} + +const leaveFederation = (db: any, platform: string, groupId: string, owner_user_id: string) => { + try{ + const stmt = db.prepare( + `INSERT INTO groups (platform, group_id, owner_user_id) + VALUES (?, ?, ?) + ON CONFLICT(platform, group_id) DO UPDATE SET + owner_user_id=?;`); + const info = stmt.run(platform, groupId, owner_user_id, owner_user_id); + } catch(err) { + console.log("db error: leaveFederation"); + console.log(err); + } +} + const setInviteURL = (db: any, platform: string, groupId: string, inviteUrl: string) => { try{ const stmt = db.prepare( @@ -64,26 +92,23 @@ const setChannelID = (db: any, platform: string, groupId: string, channel_id: st } } -const dbstart = (db: any, platform: string, groupId: string) => { +const getDisputedReportsInfo = (db:any, platform: string, groupId: string) => { try{ - const stmt = db.prepare( - `INSERT INTO groups (platform, group_id) - VALUES (?, ?);`); - const info = stmt.run(platform, groupId); - } catch(err) { - console.log("db error: set dbstart"); + const stmt = db.prepare('SELECT * FROM reports WHERE finalized = 0 AND group_id = ? AND platform = ? AND bond_paid > 0'); + return stmt.all(groupId, platform); + } catch(err){ + console.log("db error: getDisputedReports"); console.log(err); } } -const dbstarted = (db: any, platform: string, groupId: string) => { +const getFederationGroups = (db: any, platform: string, owner_user_id: string) => { try{ const stmt = db.prepare( - `INSERT INTO groups (platform, group_id) - VALUES (?, ?);`); - const info = stmt.run(platform, groupId); + `SELECT group_id FROM groups WHERE platform=? AND owner_user_id=?;`); + const info = stmt.run(platform, platform, owner_user_id); } catch(err) { - console.log("db error: set dbstarted"); + console.log("db error: setLang"); console.log(err); } } @@ -199,10 +224,21 @@ const getChannelID = (db: any, platform: string, groupId: string): string => { } } -const getGroupSettings = (db: any, platform: string, groupId: string): groupSettings => { + + +const getGroupSettings = (db: any, platform: string, groupId: string): groupSettingsUnderspecified => { try{ const stmt = db.prepare('SELECT * FROM groups WHERE platform = ? AND group_id = ?'); - return stmt.get(platform, groupId); + const result = stmt.get(platform, groupId); + return { + lang: result?.lang, + rules: undefined, + channelID: result?.channelID, + thread_id_rules: result?.thread_id_rules, + thread_id_notifications: result?.thread_id_notifications, + thread_id_welcome: result?.thread_id_welcome, + greeting_mode: result?.greeting_mode, + } } catch(err){ console.log("db error: getGroupSettings"); console.log(err); @@ -219,6 +255,89 @@ const getThreadIDRules = (db: any, platform: string, groupId: string) => { } } +const getConcurrentReports = (db: any, platform: string, groupId: string, userId: string, timestamp: number) => { + try{ + const stmt = db.prepare('SELECT question_id, msg_id, group_id, timestamp FROM reports WHERE timestamp BETWEEN ? AND ? AND user_id = ? AND group_id = ? AND platform = ?'); + return stmt.all(timestamp - 3600, timestamp + 3600, userId, groupId, platform); + } catch(err){ + console.log("db error: getConcurrentReports"); + console.log(err); + } +} + +const getDisputedReportsUserInfo = (db:any, platform: string, groupId: string, userId: string) => { + try{ + const stmt = db.prepare('SELECT * FROM reports WHERE user_id = ? AND group_id = ? AND platform = ?'); + return stmt.all(userId, groupId, platform); + } catch(err){ + console.log("db error: getDisputedReportsUserInfo"); + console.log(err); + } +} + +const getQuestionId = (db: any, platform: string, groupId: string, userId: string, msgId: string) => { + try{ + const stmt = db.prepare(`SELECT question_id FROM reports WHERE platform = ? AND group_id = ? AND user_id = ? AND msg_id = ?`); + return stmt.get(platform, groupId, userId, msgId)?.question_id || ''; + } catch{ + console.log("db error: getQuestionId"); + } +} + +const getRecordCount = (db: any, platform: string, groupId: string) => { + try{ + const stmt = db.prepare( + `SELECT COUNT(*) as total FROM reports + WHERE platform = ? AND group_id = ?` + ); + return stmt.get(platform, groupId)?.total || 0; + } catch(err) { + console.log("db error: getRecordCount"); + console.log(err); + } +} + +const getAllowance = (db: any, platform: string, groupId: string, userId: string): {report_allowance: number, evidence_allowance: number, timestamp_refresh: number, question_id_last: string, timestamp_last_question: number} | undefined => { + try{ + const stmt = db.prepare('SELECT report_allowance, evidence_allowance, timestamp_refresh, question_id_last, timestamp_last_question FROM allowance WHERE user_id = ? AND group_id = ? AND platform = ?'); + return stmt.all(userId, groupId, platform); + } catch{ + console.log("db error: getAllowance"); + } +} + +const getActiveEvidenceGroupId = (db: any, platform: string, groupId: string, evidenceIndex: number) => { + try{ + const stmt = db.prepare( `SELECT question_id FROM reports WHERE platform = ? AND group_id = ? AND evidenceIndex = ? AND finalized = 0`); + return stmt.get(platform, groupId, evidenceIndex); + } catch(err) { + console.log("db error: getActiveEvidenceGroupId"); + console.log(err); + } +} + +const setAllowance = async( + db: any, + platform: string, + groupId: string, + userId: string, + reportAllowance: number, + evidenceAllowance: number, + timeRefresh: number + ) => { + try{ + const stmt = db.prepare( + `INSERT INTO allowance (platform, group_id, user_id, report_allowance, evidence_allowance, timestamp_refresh) + VALUES ($platform, $group_id, $user_id, $report_allowance, $evidence_allowance, $timestamp_refresh) + ON CONFLICT(platform, group_id, user_id) DO UPDATE SET + report_allowance=$report_allowance, evidence_allowance = $evidence_allowance, timestamp_refresh = $timestamp_refresh;` + ); + const info = stmt.run(platform, groupId, userId, reportAllowance, evidenceAllowance, timeRefresh); + } catch { + console.log("db error: setAllowance"); + } +} + const getThreadIDWelcome = (db: any, platform: string, groupId: string) => { try{ const stmt = db.prepare('SELECT thread_id_welcome FROM groups WHERE platform = ? AND group_id = ?'); @@ -274,6 +393,52 @@ const getRule = (db:any, platform: string, groupId: string, timestamp: number): } } +const addReport = ( + db: any, + questionId: string, + platform: string, + groupId: string, + userId: string, + username: string, + msgId: string, + msgTimestamp: number, + evidenceIndex: number + ) => { + try{ + const stmt = db.prepare( + `INSERT INTO reports ( + question_id, + platform, + group_id, + user_id, + username, + msg_id, + timestamp, + evidenceIndex) + VALUES ( + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?);`); + const info = stmt.run( + questionId, + platform, + groupId, + userId, + username, + msgId, + msgTimestamp, + evidenceIndex); + } catch(e) { + console.log("db error: addReport."+e); + } + +} + export { getInviteURL, setInviteURL, @@ -282,13 +447,23 @@ export { getThreadIDWelcome, getGroupSettings, setThreadIDWelcome, + setAllowance, + getAllowance, + addReport, + getQuestionId, + getConcurrentReports, + getActiveEvidenceGroupId, setChannelID, + getDisputedReportsUserInfo, getChannelID, - dbstart, - dbstarted, + getDisputedReportsInfo, + leaveFederation, + joinFederation, + getFederationGroups, getGreetingMode, eraseThreadID, setGreetingMode, + getRecordCount, setLang, getLang, setRules, diff --git a/lib/graph.ts b/lib/graph.ts index ad0d439..5b36477 100644 --- a/lib/graph.ts +++ b/lib/graph.ts @@ -2,7 +2,7 @@ import request from "graphql-request"; const getQuestionId = async (botAddress: string, platform: string, groupId: string, userId: string, msgId: string): Promise => { const query = `{ - moderationInfos(where: {message: "https://t.me/c/${groupId.substring(4)}/${msgId}",user_: {id:"${botAddress}${platform}${userId}", group: "${botAddress}Telegram${groupId}"}}) { + moderationInfos(where: {message: "https://t.me/c/${groupId.substring(4)}/${msgId}",UserHistory_: {id:"${botAddress}${platform}${userId}${groupId}"}) { id } }`; @@ -11,8 +11,27 @@ const getQuestionId = async (botAddress: string, platform: string, groupId: stri 'https://api.thegraph.com/subgraphs/name/shotaronowhere/kleros-moderate-goerli', query ); - console.log(result) - return (result)?.data?.moderationInfos[0]?.id; + return (result)?.moderationInfos[0]?.id; + } catch(e){ + console.log(e) + return undefined + } +} + +const getAllowance = async (botAddress: string, platform: string, groupId: string, userId: string): Promise<[number, number, number]|undefined> => { + const query = `{ + userHistories(where: {id:"${botAddress}${platform}${userId}${groupId}"}) { + countReportsMade + countReportsMadeAndResponded + timestampLastUpdated + } + }`; + try{ + const result = await request( + 'https://api.thegraph.com/subgraphs/name/shotaronowhere/kleros-moderate-goerli', + query + ); + return result?.userHistories.length>0? result?.userHistories[0] : undefined; } catch(e){ console.log(e) return undefined @@ -29,11 +48,11 @@ const existsQuestionId = async (question_id: string): Promise= 1; } catch(e){ console.log(e) return undefined } } -export{getQuestionId, existsQuestionId} \ No newline at end of file +export{getQuestionId, existsQuestionId, getAllowance} \ No newline at end of file diff --git a/lib/telegram/commands/addEvidence.ts b/lib/telegram/commands/addEvidence.ts index 1b20d15..6080354 100644 --- a/lib/telegram/commands/addEvidence.ts +++ b/lib/telegram/commands/addEvidence.ts @@ -1,15 +1,13 @@ import * as TelegramBot from "node-telegram-bot-api"; import {Wallet} from "@ethersproject/wallet"; import {ipfsPublish, ipfsPublishBuffer} from "../../ipfs-publish"; -import { existsQuestionId } from "../../graph"; +import { setAllowance, getAllowance, getActiveEvidenceGroupId } from "../../db"; import fetch from 'node-fetch'; import { groupSettings } from "../../../types"; import langJson from "../assets/lang.json"; -import { newSettings } from "../../ddb/ddb"; const _contract = require('../../abi/Realitio_v2_1_ArbitratorWithAppeals.json') const Web3 = require('web3') const web3 = new Web3(process.env.WEB3_PROVIDER_URL) - const contract = new web3.eth.Contract( _contract, process.env.REALITIO_ARBITRATOR @@ -17,24 +15,22 @@ const contract = new web3.eth.Contract( var botAddress: string; -const processCommand = async (bot: TelegramBot, settings: groupSettings, msg: TelegramBot.Message, questionId: number|string, address: string, batchedSend: any, ): Promise => { - const evidencePath = await upload(bot, settings.lang, msg, address); - const evidenceJsonPath = await uploadEvidenceJson(settings.lang, msg, evidencePath, address); - await bot.sendMessage(settings.channelID, `${langJson[settings.lang].addevidence.submitted}(https://ipfs.kleros.io${evidencePath}).`, {parse_mode: "Markdown"}); - //await bot.sendMessage(channelId, `${langJson[lang].addevidence.submitted}(https://ipfs.kleros.io${evidencePath}).`, {parse_mode: "Markdown"}); - - await submitEvidence(batchedSend, evidenceJsonPath, questionId); +const processCommand = async (bot: TelegramBot, settings: groupSettings, msg: TelegramBot.Message, questionId: number|string, batchedSend: any ): Promise => { + const evidencePath = await upload(bot, settings.lang, msg); + const evidenceJsonPath = await uploadEvidenceJson(settings.lang, msg, evidencePath); + submitEvidence(batchedSend, evidenceJsonPath, questionId); + bot.sendMessage(settings.channelID, `${langJson[settings.lang].addevidence.submitted}(https://ipfs.kleros.io${evidencePath}).`, {parse_mode: "Markdown"}); return evidenceJsonPath; } -const upload = async (bot: TelegramBot, lang: string, msg: TelegramBot.Message, address: string): Promise => { +const upload = async (bot: TelegramBot, lang: string, msg: TelegramBot.Message): Promise => { if (msg.reply_to_message.text){ - return await uploadTextEvidence(lang, msg, address); + return await uploadTextEvidence(lang, msg); } else if (msg.reply_to_message.location){ - return await uploadLocationEvidence(lang, msg, address); + return await uploadLocationEvidence(lang, msg); } else if (msg.reply_to_message.poll){ - return await uploadPollEvidence(lang, msg, address); + return await uploadPollEvidence(lang, msg); } else { var file: TelegramBot.File; if (msg.reply_to_message.sticker){ @@ -67,7 +63,7 @@ const uploadFileEvidence = async (filePath: string, fileName: string): Promise => { +const uploadLocationEvidence = async (lang: string, msg: TelegramBot.Message): Promise => { const enc = new TextEncoder(); const author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' ID:'+msg.reply_to_message.from.id ; const fileName = `${langJson[lang]["addevidence"].location}.txt`; @@ -82,7 +78,7 @@ ${langJson[lang].addevidence.Message} (${langJson[lang].addevidence.location}): return evidencePath; } -const uploadPollEvidence = async (lang: string, msg: TelegramBot.Message, address: string): Promise => { +const uploadPollEvidence = async (lang: string, msg: TelegramBot.Message): Promise => { const enc = new TextEncoder(); const author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' ID:'+msg.reply_to_message.from.id ; const fileName = `${langJson[lang].addevidence.Poll}.txt`; @@ -101,7 +97,7 @@ ${langJson[lang].addevidence.Message} (${langJson[lang].addevidence.Poll}): \n return evidencePath; } -const uploadTextEvidence = async (lang: string, msg: TelegramBot.Message, address: string): Promise => { +const uploadTextEvidence = async (lang: string, msg: TelegramBot.Message): Promise => { const enc = new TextEncoder(); const author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' ID:'+msg.reply_to_message.from.id ; const fileName = `${langJson[lang].addevidence.Message}.txt`; @@ -116,11 +112,13 @@ ${langJson[lang].addevidence.Message}: ${msg.reply_to_message.text}`; return evidencePath; } -const uploadEvidenceJson = async (lang: string, msg: TelegramBot.Message, evidenceItem: string, address: string): Promise => { +const uploadEvidenceJson = async (lang: string, msg: TelegramBot.Message, evidenceItem: string): Promise => { const _name = `Kleros Moderator Bot: ${langJson[lang].addevidence.Chat} ${langJson[lang].addevidence.History}`; const author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' ID:'+msg.reply_to_message.from.id ; const enc = new TextEncoder(); - const _description = `${langJson[lang].addevidence.Desc1} ${address}. + if (!botAddress) + botAddress = await (await new Wallet(process.env.PRIVATE_KEY)).address + const _description = `${langJson[lang].addevidence.Desc1} ${botAddress}. ${langJson[lang].addevidence.Desc2}, @@ -162,9 +160,9 @@ const submitEvidence = async (batchedSend: any, evidencePath: string, questionId const regexp = /\/addevidence/ const regexpFull = /\/addevidence (.+)/ -const callback = async (db: any, settings: groupSettings, bot: any, msg: any, batchedSend: any) => { +const callback = async (db: any, settings: groupSettings, bot: any, botID: number, msg: any, matchh: string[], batchedSend: any) => { if (!msg.reply_to_message) { - msg.chat.is_forum? await bot.sendMessage(msg.chat.id, `/addevidence ${langJson[settings.lang].errorReply}`, {message_thread_id: msg.message_thread_id}) : await bot.sendMessage(msg.chat.id, `/addevidence ${langJson[settings.lang].errorReply}`); + bot.sendMessage(msg.chat.id, `/addevidence ${langJson[settings.lang].errorReply}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) return; } @@ -172,39 +170,33 @@ const callback = async (db: any, settings: groupSettings, bot: any, msg: any, ba //TODO Evidence IDs and button callback UX if (!match || match.length < 2){ - msg.chat.is_forum? await bot.sendMessage(msg.chat.id, `/addevidence ${langJson[settings.lang].addevidence.error1} ${langJson[settings.lang].addevidence.id}`, {message_thread_id: msg.message_thread_id}) : await bot.sendMessage(msg.chat.id, `/addevidence ${langJson[settings.lang].addevidence.error1} ${langJson[settings.lang].addevidence.id}`); + bot.sendMessage(msg.chat.id, `/addevidence ${langJson[settings.lang].addevidence.error1} ${langJson[settings.lang].addevidence.id}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) //const errorMsg = await errorMessage(db, lang, bot, msg); //await bot.sendMessage(msg.chat.id, errorMsg, {parse_mode: "Markdown", disable_web_page_preview: true}); return; } - - if (!await existsQuestionId(match[1])){ - msg.chat.is_forum? await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorId, {message_thread_id: msg.message_thread_id}) : bot.sendMessage(msg.chat.id, langJson[settings.lang].errorId); - await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorId); + const result = getActiveEvidenceGroupId(db, 'telegram', String(msg.chat.id), Number(match[1])); + if (!result){ + bot.sendMessage(msg.chat.id, langJson[settings.lang].errorId, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) //const errorMsg = await errorMessage(db, lang, bot, msg); //await bot.sendMessage(msg.chat.id, errorMsg, {parse_mode: "Markdown", disable_web_page_preview: true}); return; } - // TODO Allowance - /* - const reportAllowance = await getAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id)); - if (reportAllowance === undefined){ + const reportAllowance = getAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id)); + if (!reportAllowance){ setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), 3, 14, Math.ceil( new Date().getTime() / 1000)); } else if ((Math.ceil( new Date().getTime() / 1000) < reportAllowance.timestamp_refresh + 5760) && reportAllowance.evidence_allowance == 0 ){ - await bot.sendMessage(msg.chat.id, langJson[lang].errorAllowance); + await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorAllowance); } else{ const newReportAllowance = reportAllowance.report_allowance + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800); const newEvidenceAllowance = reportAllowance.evidence_allowance + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800)*5 - 1; const newRefreshTimestamp = reportAllowance.timestamp_refresh + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800)*28800; setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), Math.min(newReportAllowance,3), Math.min(newEvidenceAllowance,15), newRefreshTimestamp); } -*/ - if (!botAddress) - botAddress = await (await new Wallet(process.env.PRIVATE_KEY)).address try { - const evidencePath = await processCommand(bot, settings, msg, match[1], botAddress,batchedSend); + const evidencePath = await processCommand(bot, settings, msg, match[1],batchedSend); } catch (e) { console.log(e); diff --git a/lib/telegram/commands/getAccount.ts b/lib/telegram/commands/getAccount.ts index 96c0730..c4f4434 100644 --- a/lib/telegram/commands/getAccount.ts +++ b/lib/telegram/commands/getAccount.ts @@ -6,10 +6,13 @@ import langJson from "../assets/lang.json"; * /getaccount */ const regexp = /\/getaccount/ +var address: string; -const callback = async (db: any, lang: string, bot: TelegramBot, msg: TelegramBot.Message) => { - const add = await (await new Wallet(process.env.PRIVATE_KEY)).address; - await bot.sendMessage(msg.chat.id, `${langJson[lang].getAccount}: ${add}`); +const callback = async (db: any, lang: string, bot: any, msg: any) => { + if (!address) + address = (await new Wallet(process.env.PRIVATE_KEY)).address; + + await bot.sendMessage(msg.chat.id, `${langJson[lang].getAccount}: ${address}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}); } export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/getReports.ts b/lib/telegram/commands/getReports.ts index 408e217..c36fa1c 100644 --- a/lib/telegram/commands/getReports.ts +++ b/lib/telegram/commands/getReports.ts @@ -1,39 +1,44 @@ import * as TelegramBot from "node-telegram-bot-api"; const escape = require('markdown-escape') import langJson from "../assets/lang.json"; - +import {getDisputedReportsUserInfo } from "../../db"; /* * /getaccount */ const regexp = /\/getreports/ -const callback = async (db: any, lang: string, bot: TelegramBot, msg: TelegramBot.Message) => { -/* - if(msg.reply_to_message){ - const reports = await getDisputedReportsUserInfo(db, 'telegram', String(msg.chat.id), String(msg.reply_to_message.from.id)); - const fromUsername = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name || `no-username-set`); - if (reports.length == 0){ - await bot.sendMessage(msg.chat.id, `${langJson[lang].getReports.noReports} *${escape(fromUsername)}*.`, {parse_mode: "Markdown"}); +const callback = async (db: any, lang: string, bot: any, msg: any) => { + try{ + if(msg.reply_to_message){ + const reports = await getDisputedReportsUserInfo(db, 'telegram', String(msg.chat.id), String(msg.reply_to_message.from.id)); + const fromUsername = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name || `no-username-set`); + if (reports.length == 0){ + bot.sendMessage(msg.chat.id, `${langJson[lang].getReports.noReports} *${escape(fromUsername)}*.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}:{parse_mode: "Markdown"}); + return; + } + var reportMessage: string = `${langJson[lang].getReports.ReportsFor} ${escape(fromUsername)}:\n\n`; + await reports.forEach(async (report) => { + const reportAnswer = report.active? langJson[lang].getReports.broke : langJson[lang].getReports.nobreak; + const MsgLink = 'https://t.me/c/' + report.group_id.substring(4) + '/' + report.msg_id; + const msgTime = new Date(report.timestamp*1000).toISOString(); + const reportState = report.finalized? langJson[lang].getReports.reportFinal : langJson[lang].getReports.reportCurrent; + reportMessage += ` - [${langJson[lang].getReports.report}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), ${langJson[lang].addEvidence.Evidence} ID ${report.evidenceIndex}, [${langJson[lang].addEvidence.MessageSent} ${msgTime.substring(0,msgTime.length-4)}](${MsgLink}) ([${langJson[lang].socialConsensus.consensus5}](${report.msgBackup})), ${reportState} ${langJson[lang].answer}, ${reportAnswer}\n`; + }); + bot.sendMessage(msg.chat.id, reportMessage , msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown", disable_web_page_preview: true}:{parse_mode: "Markdown", disable_web_page_preview: true}); return; + } else { + bot.sendMessage(msg.chat.id, "Please reply to a user to find their history", msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) } - var reportMessage: string = `${langJson[lang].getReports.ReportsFor} ${escape(fromUsername)}:\n\n`; - await reports.forEach(async (report) => { - const reportAnswer = report.active? langJson[lang].getReports.broke : langJson[lang].getReports.nobreak; - const MsgLink = 'https://t.me/c/' + report.group_id.substring(4) + '/' + report.msg_id; - const msgTime = new Date(report.timestamp*1000).toISOString(); - const reportState = report.finalized? langJson[lang].getReports.reportFinal : langJson[lang].getReports.reportCurrent; - reportMessage += ` - [${langJson[lang].getReports.report}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), ${langJson[lang].addEvidence.Evidence} ID ${report.evidenceIndex}, [${langJson[lang].addEvidence.MessageSent} ${msgTime.substring(0,msgTime.length-4)}](${MsgLink}) ([${langJson[lang].socialConsensus.consensus5}](${report.msgBackup})), ${reportState} ${langJson[lang].answer}, ${reportAnswer}\n`; - }); - await bot.sendMessage(msg.chat.id, reportMessage, {parse_mode: "Markdown", disable_web_page_preview: true}); - return; + } catch(e){ + console.log(e) } - - const reports = await getDisputedReportsInfo(db, 'telegram', String(msg.chat.id)); +/* + const reports = getDisputedReportsInfo(db, 'telegram', String(msg.chat.id)); if (reports.length == 0){ - await bot.sendMessage(msg.chat.id, langJson[lang].getReports.noActiveReports + '\n\n' + langJson[lang].getReports.specificUser); + bot.sendMessage(msg.chat.id, langJson[lang].getReports.noActiveReports + '\n\n' + langJson[lang].getReports.specificUser, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}:{parse_mode: "Markdown"}); return; - } - + }*/ +/* var reportMessage: string = langJson[lang].getReports.reportMessage + ':\n\n'; await reports.forEach(async (report) => { @@ -44,7 +49,7 @@ const callback = async (db: any, lang: string, bot: TelegramBot, msg: TelegramBo }); reportMessage += '\n\n' reportMessage += langJson[lang].getReports.specificUser; - await bot.sendMessage(msg.chat.id, reportMessage, {parse_mode: "Markdown", disable_web_page_preview: true}); + bot.sendMessage(msg.chat.id, reportMessage, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown", disable_web_page_preview: true}:{parse_mode: "Markdown", disable_web_page_preview: true}); */ } diff --git a/lib/telegram/commands/getRules.ts b/lib/telegram/commands/getRules.ts index 9c5dbbb..e019bff 100644 --- a/lib/telegram/commands/getRules.ts +++ b/lib/telegram/commands/getRules.ts @@ -9,11 +9,7 @@ import { groupSettings } from "../../../types"; const regexp = /\/getrules/ const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { - const rules = await getRule(db, 'telegram', String(msg.chat.id), Math.floor(Date.now()/1000)); - if (rules) - await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].rules}(${rules}).`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}); - else - await bot.sendMessage(msg.chat.id, langJson[settings.lang].noRules, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}); + bot.sendMessage(msg.chat.id, `${langJson[settings.lang].rules}(${settings.rules}).`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}); } export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/joinfed.ts b/lib/telegram/commands/joinfed.ts new file mode 100644 index 0000000..9494e96 --- /dev/null +++ b/lib/telegram/commands/joinfed.ts @@ -0,0 +1,20 @@ +import * as TelegramBot from "node-telegram-bot-api"; +import { groupSettings } from "../../../types"; +import {joinFederation} from "../../db"; +import langJson from "../assets/lang.json"; + +/* + * /joinfed + */ +const regexp = /\/joinfed/ + +const callback = async (db: any, settings: groupSettings, bot: any, botId: string, msg: any, match: string[]) => { + try{ + joinFederation(db, 'telegram', String(msg.chat.id), String(msg.from.id)) + bot.sendMessage(msg.chat.id, 'Your group has joined the federation.', msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) + } catch(e){ + console.log(e) + } +} + +export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/leavefed.ts b/lib/telegram/commands/leavefed.ts new file mode 100644 index 0000000..03e3c13 --- /dev/null +++ b/lib/telegram/commands/leavefed.ts @@ -0,0 +1,20 @@ +import * as TelegramBot from "node-telegram-bot-api"; +import { groupSettings } from "../../../types"; +import {leaveFederation} from "../../db"; +import langJson from "../assets/lang.json"; + +/* + * /joinfed + */ +const regexp = /\/leavefed/ + +const callback = async (db: any, settings: groupSettings, bot: any, botId: string, msg: any, match: string[]) => { + try{ + leaveFederation(db, 'telegram', String(msg.chat.id), String(msg.from.id)) + bot.sendMessage(msg.chat.id, 'Your group has left the federation.', msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) + } catch(e){ + console.log(e) + } +} + +export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/report.ts b/lib/telegram/commands/report.ts index 779de95..b1ec01c 100644 --- a/lib/telegram/commands/report.ts +++ b/lib/telegram/commands/report.ts @@ -1,145 +1,150 @@ import * as TelegramBot from "node-telegram-bot-api"; -import {Wallet} from "@ethersproject/wallet"; -import {setInviteURL, getInviteURL, getRule} from "../../db"; -import { getQuestionId } from "../../graph"; +import {setInviteURL, getInviteURL, getRule,getAllowance, setAllowance, addReport, getConcurrentReports, getRecordCount, getQuestionId} from "../../db"; import { groupSettings } from "../../../types"; import {upload} from "./addEvidence" import {reportUser} from "../../bot-core"; import langJson from "../assets/lang.json"; -const escape = require('markdown-escape'); + /* * /report */ const regexp = /\/report\s?(.+)?/ let evidenceIndexMap : Map = new Map(); -let inviteURLMap : Map = new Map(); -var botAddress: string; +// cacheIndex => groupID,reported message id => [pending report message id] +const NodeCache = require( "node-cache" ); +const myCache = new NodeCache( { stdTTL: 900, checkperiod: 1200 } ); + +const callback = async (db:any, settings: groupSettings, bot: any, botId: number, msg: any, match: string[]) => { + try{ + if (!msg.reply_to_message) { + bot.sendMessage(msg.chat.id, `/report ${langJson[settings.lang].errorReply}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + return; + } -const callback = async (db:any, settings: groupSettings, bot: any, botId: number, msg: TelegramBot.Message, match: string[]) => { + // WHO WATCHES THE WATCHMEN?? + // can't ban bots + if (msg.reply_to_message.from.is_bot){ + if(msg.reply_to_message.from.username === "GroupAnonymousBot") + bot.sendMessage(msg.chat.id, `User is anonymous. Ask admins to disable anonymouse admins to moderate admin behavior.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + else + bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.errorModBot}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + return + } - if (!msg.reply_to_message) { - await bot.sendMessage(msg.chat.id, `/report ${langJson[settings.lang].errorReply}`); - return; - } + const fromUsername = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name || `no-username-set`); + const reportedUserID = String(msg.reply_to_message.from.id); + const currentTimeMs = Date.now()/1000; - if (msg.reply_to_message.from.id === botId){ - await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.errorModBot}`); - } + const cachedReportRequestMessage = myCache.get([msg.chat.id, msg.reply_to_message.message_id].toString()) + if (cachedReportRequestMessage){ // message already reported + const msgLinkReport = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + cachedReportRequestMessage; + bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.reported}(${msgLinkReport})`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); + return; + } + const reportedQuestionId = getQuestionId(db, 'telegram', String(msg.chat.id), reportedUserID, String(msg.reply_to_message.message_id)); - // WHO WATCHES THE WATCHMEN?? - //const reportedChatMember = await bot.getChatMember(msg.chat.id, String(msg.reply_to_message.from.id)); - //if (reportedChatMember.status === 'creator' || reportedChatMember.status === 'administrator') { - // await bot.sendMessage(msg.chat.id, `${langJson[lang].report.errorAdmin}`); - // return; - //} - const fromUsername = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name || `no-username-set`); - const reportedUserID = String(msg.reply_to_message.from.id); + if (reportedQuestionId){ + bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.reported}(https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${reportedQuestionId})`, {parse_mode: 'Markdown'}); + return; + } - // replace with graph, maybe also hashmap for fast - const reportedQuestionId = await getQuestionId(botAddress, 'Telegram', String(msg.chat.id), reportedUserID, String(msg.reply_to_message.message_id)); + if (match[1] != langJson[settings.lang].socialConsensus.confirm) { + const reports = getConcurrentReports(db, 'telegram', String(msg.chat.id), reportedUserID, msg.reply_to_message.date); + if(reports.length > 0){ + var reportInfo = `${langJson[settings.lang].report.info1} *${escape(fromUsername)} (ID :${reportedUserID})* ${langJson[settings.lang].report.info2} \n\n`; + (reports).forEach((report) => { + const privateMsgLink = 'https://t.me/c/' + report.group_id.substring(4) + '/' + report.msg_id; + reportInfo += ` - [${langJson[settings.lang].addEvidence.Message} ${new Date(report.timestamp*1000).toISOString()}](${privateMsgLink}): [${langJson[settings.lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id})\n`; + }); + reportInfo += `\n${langJson[settings.lang].report.sure} \'/report ${langJson[settings.lang].socialConsensus.confirm}\'` + bot.sendMessage(msg.chat.id, reportInfo, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); + return; + } + } - if (reportedQuestionId){ - await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.reported}(https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${reportedQuestionId})`, {parse_mode: 'Markdown'}); - return; - } - // replace with hashmap ? - // only keep track of last 24 hours - //const reportRequest - //= await getReportRequest(db, 'telegram', String(msg.chat.id), String(msg.reply_to_message.message_id)); -/* - if (reportRequest){ - const requestMsgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + reportRequest.msgRequestId; - await bot.sendMessage(msg.chat.id, `${langJson[lang].report.reported}(${requestMsgLink}).`, {parse_mode: 'Markdown'}); - return; - }*/ -/* - const reports = await getConcurrentReports(db, 'telegram', String(msg.chat.id), reportedUserID, msg.reply_to_message.date); - - if (reports.length > 0 && match[1] != langJson[lang].socialConsensus.confirm) { - var reportInfo = `${langJson[lang].report.info1} *${escape(fromUsername)} (ID :${reportedUserID})* ${langJson[lang].report.info2} \n\n`; - (reports).forEach((report) => { - const privateMsgLink = 'https://t.me/c/' + report.group_id.substring(4) + '/' + report.msg_id; - reportInfo += ` - [${langJson[lang].addEvidence.Message} ${new Date(report.timestamp*1000).toISOString()}](${privateMsgLink}): [${langJson[lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id})\n`; - }); - reportInfo += `\n${langJson[lang].report.sure} \'/report ${langJson[lang].socialConsensus.confirm}\'` - await bot.sendMessage(msg.chat.id, reportInfo, {parse_mode: 'Markdown'}); - return; - } -*/ + const rules = getRule(db, 'telegram', String(msg.chat.id), msg.reply_to_message.date); - const rules = await getRule(db, 'telegram', String(msg.chat.id), msg.reply_to_message.date); + if (!rules){ + bot.sendMessage(msg.chat.id, langJson[settings.lang].report.norules, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + return; + } + - if (!rules){ - await bot.sendMessage(msg.chat.id, langJson[settings.lang].report.norules); - return; - } - - if (!botAddress) - botAddress = await (await new Wallet(process.env.PRIVATE_KEY)).address - - const evidencepath = await upload(bot, settings.lang, msg, botAddress); - const msgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + String(msg.reply_to_message.message_id); - const msgBackup = 'https://ipfs.kleros.io'+evidencepath; - // TODO report - /* - const reportAllowance = await getAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id)); - if(reportAllowance != undefined && reportAllowance.question_id_last){ - const isQuestionAnswered = await questionAnswered(db, reportAllowance.question_id_last); - const lastReport = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${reportAllowance.question_id_last}`; - if(!isQuestionAnswered && Math.floor(Date.now()/1000) < reportAllowance.timestamp_last_question + 259200){ - await bot.sendMessage(msg.chat.id, `${langJson[lang].report.allowance1}(${lastReport}) ${langJson[lang].report.allowance2}`, {parse_mode: 'Markdown'}); + const evidencepath = await upload(bot, settings.lang, msg); + const msgBackup = 'https://ipfs.kleros.io'+evidencepath; + // TODO report + + const reportAllowance = getAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id)); + if (!reportAllowance ){ + setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), 2, 15, currentTimeMs); + } else if (currentTimeMs < reportAllowance.timestamp_refresh + 28800 && reportAllowance.report_allowance == 0 ){ + bot.sendMessage(msg.chat.id, langJson[settings.lang].report.noallowance, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); return; + } else{ + const newReportAllowance = reportAllowance.report_allowance + Math.floor((currentTimeMs - reportAllowance.timestamp_refresh)/28800) - 1; + const newEvidenceAllowance = reportAllowance.evidence_allowance + Math.floor((currentTimeMs - reportAllowance.timestamp_refresh)/28800)*5; + const newRefreshTimestamp = reportAllowance.timestamp_refresh + Math.floor((currentTimeMs - reportAllowance.timestamp_refresh)/28800)*28800; + setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), Math.min(newReportAllowance,3), Math.min(newEvidenceAllowance,15), newRefreshTimestamp); } - }*/ - /* - if ( reportAllowance === undefined ){ - setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), 2, 15, Math.ceil( new Date().getTime() / 1000)); - } else if ((Math.ceil( new Date().getTime() / 1000) < reportAllowance.timestamp_refresh + 28800) && reportAllowance.report_allowance == 0 ){ - await bot.sendMessage(msg.chat.id, langJson[lang].report.noallowance); + const opts = { + parse_mode: 'Markdown', + reply_to_message_id: msg.reply_to_message.message_id, + reply_markup: { + inline_keyboard: [ + [ + { + text: langJson[settings.lang].socialConsensus.confirm + ' (1/3)', + callback_data: '2|'+String(msg.reply_to_message.from.id)+'|'+String(msg.reply_to_message.message_id)+'|'+String(msg.from.id) + } + ] + ] + } + }; + const optsThread = { + parse_mode: 'Markdown', + reply_to_message_id: msg.reply_to_message.message_id, + message_thread_id: msg.message_thread_id, + reply_markup: { + inline_keyboard: [ + [ + { + text: langJson[settings.lang].socialConsensus.confirm + ' (1/3)', + callback_data: "2|"+String(msg.reply_to_message.from.id)+'|'+String(msg.reply_to_message.message_id)+'|'+String(msg.from.id) + } + ] + ] + } + }; + const msgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + msg.reply_to_message.message_id; + const reportRequestMsg: TelegramBot.Message = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].socialConsensus.consensus2} [${fromUsername}](tg://user?id=${reportedUserID}) ${langJson[settings.lang].socialConsensus.consensus3}(${rules}) ${langJson[settings.lang].socialConsensus.consensus4}(${msgLink}) ([${langJson[settings.lang].socialConsensus.consensus5}](${msgBackup}))?`, msg.chat.is_forum? optsThread: opts); + myCache.set([msg.chat.id, msg.reply_to_message.message_id].toString(),reportRequestMsg.message_id) ; return; - } else{ - const newReportAllowance = reportAllowance.report_allowance + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800) - 1; - const newEvidenceAllowance = reportAllowance.evidence_allowance + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800)*5; - const newRefreshTimestamp = reportAllowance.timestamp_refresh + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800)*28800; - setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), Math.min(newReportAllowance,3), Math.min(newEvidenceAllowance,15), newRefreshTimestamp); - }*/ - const opts = { - parse_mode: 'Markdown', - reply_markup: { - inline_keyboard: [ - [ - { - text: langJson[settings.lang].socialConsensus.confirm + ' (1/3)', - callback_data: String(msg.reply_to_message.from.id)+'|'+String(msg.reply_to_message.message_id)+'|'+String(msg.from.id) - } - ] - ] - } - }; - const reportRequestMsg = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].socialConsensus.consensus1}\n\n ${langJson[settings.lang].socialConsensus.consensus2} [${escape(fromUsername)}](tg://user?id=${reportedUserID}) ${langJson[settings.lang].socialConsensus.consensus3}(${rules}) ${langJson[settings.lang].socialConsensus.consensus4}(${msgLink}) ([${langJson[settings.lang].socialConsensus.consensus5}](${msgBackup}))?`, opts); - return; + } catch(e){ + console.log(e) + } } -const reportMsg = async (settings: groupSettings, db: any, bot: TelegramBot, msg: TelegramBot.Message, fromUsername: string, reportedUserID: string, rules: string, msgId: string, msgBackup: string, reportedBy: string, batchedSend: any) => { +const reportMsg = async (settings: groupSettings, db: any, bot: any, msg: any, fromUsername: string, reportedUserID: string, rules: string, msgId: string, msgBackup: string, reportedBy: string, batchedSend: any) => { try { - var inviteURL = inviteURLMap.get(msg.chat.id) + var inviteURL = myCache.get(msg.chat.id) if (!inviteURL){ - inviteURL = await getInviteURL(db, 'telegram', String(msg.chat.id)); + inviteURL = getInviteURL(db, 'telegram', String(msg.chat.id)); if (!inviteURL){ inviteURL = await bot.exportChatInviteLink(msg.chat.id); - await setInviteURL(db, 'telegram', String(msg.chat.id), inviteURL); + setInviteURL(db, 'telegram', String(msg.chat.id), inviteURL); } - inviteURLMap.set(msg.chat.id, inviteURL) + myCache.set(msg.chat.id, inviteURL) } const msgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + msgId; - var evidenceIndex = evidenceIndexMap.get(msg.chat.id) + 1; - if (!evidenceIndex) - evidenceIndex = 1//await getRecordCount(db, 'telegram', String(msg.chat.id))+1; + var evidenceIndex = myCache.get("evidence"+msg.chat.id) + 1; + if (!evidenceIndex){ + evidenceIndex = getRecordCount(db, 'telegram', String(msg.chat.id))+1; + } evidenceIndexMap.set(msg.chat.id, evidenceIndex); - + const {questionId, questionUrl: appealUrl} = await reportUser( batchedSend, settings.lang, @@ -154,14 +159,17 @@ const reportMsg = async (settings: groupSettings, db: any, bot: TelegramBot, msg msgLink, msgBackup, reportedBy); - - await bot.sendMessage(settings.channelID, `*${escape(fromUsername)} (ID :${reportedUserID}) *'s conduct due to this [message](${msgLink}) ([backup](${msgBackup})) is reported for breaking the [rules](${rules}).\n\nDid *${escape(fromUsername)}* break the rules? The [question](${appealUrl}) can be answered with a minimum bond of 5 DAI.\n\n To save a record, reply to messages you want saved with the command below,\n/addevidence ${evidenceIndex}`, {parse_mode: 'Markdown'}); + addReport(db, questionId, "telegram", String(msg.chat.id), reportedUserID, fromUsername , msgId, msg.reply_to_message.date,evidenceIndex); + bot.sendMessage(settings.channelID, `[${fromUsername}](tg://user?id=${reportedUserID})'s conduct due to this [message](${msgLink}) ([backup](${msgBackup})) is reported for breaking the [rules](${rules}).\n\nDid *${fromUsername}* break the rules? The [question](${appealUrl}) can be answered with a minimum bond of 5 DAI.\n\nTo save a record, reply to messages you want saved with the command below,\n/addevidence ${evidenceIndex}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); return questionId; } catch (e) { console.log(e); - - await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].errorTxn}. ${e.reason}. `); + try{ + bot.sendMessage(msg.chat.id, `${langJson[settings.lang].errorTxn}. ${e.reason}. `,msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + } catch(e){ + console.log(e) + } return; } } diff --git a/lib/telegram/commands/setChannel.ts b/lib/telegram/commands/setChannel.ts index 3ed2d2e..6f4d5c2 100644 --- a/lib/telegram/commands/setChannel.ts +++ b/lib/telegram/commands/setChannel.ts @@ -12,14 +12,9 @@ const regexpFull = /\/setchannel (.+)/ const callback = async (db: any, settings: groupSettings, bot: TelegramBot, botId: string, msg: TelegramBot.Message, match: string[], batchedSend: any) => { try { - const user = await bot.getChatMember(msg.chat.id, String(msg.from.id)); - if (!(user.status === 'creator' || user.status === 'administrator')) { - await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorAdminOnly); - return; - } const newmatch = msg.text.match(regexpFull); if (!newmatch || newmatch.length < 2){ - bot.sendMessage(msg.chat.id, `/setchannel ${langJson[settings.lang].addevidence.error1} ${langJson[settings.lang].addevidence.id}`); + bot.sendMessage(msg.chat.id, `/setchannel must be followed by a channel id`); return; } try{ diff --git a/lib/telegram/commands/setLanguage.ts b/lib/telegram/commands/setLanguage.ts index 85e357e..0df5b15 100644 --- a/lib/telegram/commands/setLanguage.ts +++ b/lib/telegram/commands/setLanguage.ts @@ -9,11 +9,6 @@ const regexp = /\/setlanguage/ const regexpFull = /\/setlanguage (.+)/ const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { - const user = await bot.getChatMember(msg.chat.id, String(msg.from.id)); - if (!(user.status === 'creator' || user.status === 'administrator')) { - msg.chat.is_forum? await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorAdminOnly, {message_thread_id: msg.message_thread_id}): await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorAdminOnly); - return; - } const match = msg.text.match(regexpFull); const langCode = match? match[1].toLowerCase(): ''; @@ -30,7 +25,7 @@ const callback = async (db: any, settings: groupSettings, bot: any, botId: numbe [ { text: 'English', - callback_data: 'en' + callback_data: `0|${msg.from.id}`+'|'+`en` } ] ] @@ -42,7 +37,7 @@ const callback = async (db: any, settings: groupSettings, bot: any, botId: numbe [ { text: 'English', - callback_data: 'en' + callback_data: `0|${msg.from.id}`+'|'+`en` } ] ] diff --git a/lib/telegram/commands/setRules.ts b/lib/telegram/commands/setRules.ts index 7c5f0c7..5daaf38 100644 --- a/lib/telegram/commands/setRules.ts +++ b/lib/telegram/commands/setRules.ts @@ -20,30 +20,24 @@ const validateUrl = (s: string): boolean => { const callback = async (db: any, settings: groupSettings, bot: any, botId: string, msg: any, match: string[]) => { try{ - const user = await bot.getChatMember(msg.chat.id, String(msg.from.id)); - const chat = await bot.getChat(msg.chat.id); - if (user.status === 'creator' || user.status === 'administrator') { - if (msg.reply_to_message && !msg.reply_to_message.forum_topic_created) { - const enc = new TextEncoder(); - const rulesPath = await ipfsPublish('rules.txt', enc.encode(msg.reply_to_message.text)) - setRules(db, 'telegram', String(msg.chat.id), 'https://ipfs.kleros.io'+rulesPath, new Date().getTime()/1000); - bot.sendMessage(msg.chat.id, `The community rules are [updated](https://ipfs.kleros.io${rulesPath}).`, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules, parse_mode: 'Markdown'}: {parse_mode: "Markdown"}); - if(msg.chat.is_forum){ - const msgRules = await bot.forwardMessage(msg.chat.id, msg.chat.id, msg.reply_to_message.message_id, {message_thread_id: settings.thread_id_rules}); + if (msg.reply_to_message && !msg.reply_to_message.forum_topic_created) { + const enc = new TextEncoder(); + const rulesPath = await ipfsPublish('rules.txt', enc.encode(msg.reply_to_message.text)) + setRules(db, 'telegram', String(msg.chat.id), 'https://ipfs.kleros.io'+rulesPath, new Date().getTime()/1000); + bot.sendMessage(msg.chat.id, `The community rules are [updated](https://ipfs.kleros.io${rulesPath}).`, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules, parse_mode: 'Markdown'}: {parse_mode: "Markdown"}); + if(msg.chat.is_forum){ + const msgRules = await bot.forwardMessage(msg.chat.id, msg.chat.id, msg.reply_to_message.message_id, {message_thread_id: settings.thread_id_rules}); + bot.pinChatMessage(msg.chat.id, msgRules.message_id, {message_thread_id: settings.thread_id_rules}) + } + } else if (validateUrl(match[1])) { + setRules(db, 'telegram', String(msg.chat.id), match[1], Math.floor(new Date().getTime()/1000)); + if(msg.chat.is_forum){ + const msgRules = await bot.forwardMessage(msg.chat.id, msg.chat.id, msg.message_id, {message_thread_id: settings.thread_id_rules}); bot.pinChatMessage(msg.chat.id, msgRules.message_id, {message_thread_id: settings.thread_id_rules}) - } - } else if (validateUrl(match[1])) { - setRules(db, 'telegram', String(msg.chat.id), match[1], Math.floor(new Date().getTime()/1000)); - if(msg.chat.is_forum){ - const msgRules = await bot.forwardMessage(msg.chat.id, msg.chat.id, msg.message_id, {message_thread_id: settings.thread_id_rules}); - bot.pinChatMessage(msg.chat.id, msgRules.message_id, {message_thread_id: settings.thread_id_rules}) - } - await bot.sendMessage(msg.chat.id, langJson[settings.lang].rulesUpdated, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules}: {}); - } else { - await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorRules, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules}: {}); } + await bot.sendMessage(msg.chat.id, langJson[settings.lang].rulesUpdated, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules}: {}); } else { - await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorAdminOnly, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorRules, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules}: {}); } } catch(e){ console.log(e) diff --git a/lib/telegram/commands/socialConsensus.ts b/lib/telegram/commands/socialConsensus.ts index 1875f2e..d0849eb 100644 --- a/lib/telegram/commands/socialConsensus.ts +++ b/lib/telegram/commands/socialConsensus.ts @@ -4,21 +4,26 @@ import {reportMsg} from "./report"; import langJson from "../assets/lang.json"; import { groupSettings } from "../../../types"; const escape = require('markdown-escape') +import {Wallet} from "@ethersproject/wallet"; +var botAddress: string; /* * /getrules */ -const callback = async (db: any, settings: groupSettings, botaddress: string, bot: TelegramBot, callbackQuery: TelegramBot.CallbackQuery, batchedSend: any) => { +const callback = async (db: any, settings: groupSettings, bot: TelegramBot, callbackQuery: TelegramBot.CallbackQuery, batchedSend: any) => { + if(!botAddress) + botAddress = await (await new Wallet(process.env.PRIVATE_KEY)).address.toLowerCase(); + const rawCalldata = callbackQuery.data; const calldata = rawCalldata.split('|'); const match = callbackQuery.message.reply_markup.inline_keyboard[0][0].text; const msg: any = callbackQuery.message; const newConfirmations = Number(match.substring(9,10)) + 1; - if (callbackQuery.from.id == Number(calldata[2])) + if (callbackQuery.from.id == Number(calldata[3])) return; - //if (calldata.length > 3 && callbackQuery.from.id == Number(calldata[3])) + //if (calldata.length > 4 && callbackQuery.from.id == Number(calldata[4])) // return; const markdown = { @@ -31,28 +36,30 @@ const callback = async (db: any, settings: groupSettings, botaddress: string, bo ] ] }; - const opts = msg.chat.is_forum? { - chat_id: msg.chat.id, - message_id: msg.message_id, - } : { - chat_id: msg.chat.id, - message_id: msg.message_id, - message_thread_id: msg.message_thread_id - } - //todo proper rule chronology - if (newConfirmations > 1){ - const reportedQuestionId = await getQuestionId(botaddress, 'Telegram', String(msg.chat.id), String(calldata[0]), String(calldata[1])); - if (reportedQuestionId){ - return; + const opts = msg.chat.is_forum? { + chat_id: msg.chat.id, + message_id: msg.message_id, + } : { + chat_id: msg.chat.id, + message_id: msg.message_id, + message_thread_id: msg.message_thread_id } - if (reportedQuestionId) - await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].socialConsensus.reported}(https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${reportedQuestionId})`, {parse_mode: 'Markdown'}); - else{ - bot.deleteMessage(msg.chat.id, String(msg.message_id)) - const user = (await bot.getChatMember(String(msg.chat.id), String(calldata[0]))).user; - const fromUsername = escape(user.username || user.first_name || `no-username-set`); - await reportMsg(settings, db, bot, msg, fromUsername, String(calldata[0]), msg.entities[0].url, String(calldata[1]), msg.entities[2].url, calldata[2],batchedSend); + const optsFinal = msg.chat.is_forum? { + chat_id: msg.chat.id, + message_id: msg.message_id, + text: "User Reported." + } : { + chat_id: msg.chat.id, + message_id: msg.message_id, + message_thread_id: msg.message_thread_id, + text: "User Reported." } + if (newConfirmations > 1){ + bot.editMessageReplyMarkup({ inline_keyboard: []}, optsFinal) + bot.editMessageText("User Reported.") + const user = (await bot.getChatMember(String(msg.chat.id), String(calldata[1]))).user; + const fromUsername = user.username || user.first_name || `no-username-set`; + await reportMsg(settings, db, bot, msg, fromUsername, String(calldata[1]), msg.entities[1].url, String(calldata[2]), msg.entities[3].url, calldata[3],batchedSend); } else{ bot.editMessageReplyMarkup(markdown, opts) } diff --git a/lib/telegram/commands/start.ts b/lib/telegram/commands/start.ts index b51aa10..6561c82 100644 --- a/lib/telegram/commands/start.ts +++ b/lib/telegram/commands/start.ts @@ -1,5 +1,5 @@ import * as TelegramBot from "node-telegram-bot-api"; -import {setThreadID, getThreadIDNotifications, dbstart, setRules} from "../../db"; +import {setThreadID, getThreadIDNotifications, setRules} from "../../db"; import langJson from "../assets/lang.json"; import {groupSettings} from "../../../types"; @@ -11,12 +11,6 @@ const regexp = /\/start/ const callback = async (db: any, settings: groupSettings, bot: any, botID: string, msg: any) => { // admin check try{ - console.log(msg) - const requestUser = await bot.getChatMember(msg.chat.id, msg.from.id) - if (requestUser.status !== "administrator" && requestUser.status !== "creator"){ - bot.sendMessage(settings.channelID, "Please ask an admin to start Susie's community moderation."); - return; - } const botUser = await bot.getChatMember(msg.chat.id, botID) if(botUser.status !== "administrator" || !botUser.can_restrict_members){ bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', msg.chat.is_forum? {message_thread_id: msg.message_thread_id, caption: "Please give Susie full admin rights.\n\nThen try to /start community moderation again."} : {caption: "Please give Susie full admin rights.\n\nThen try to /start community moderation again."}); @@ -29,13 +23,12 @@ const callback = async (db: any, settings: groupSettings, bot: any, botID: strin } const thread_ids = getThreadIDNotifications(db, 'telegram', String(msg.chat.id)); if (thread_ids){ - bot.sendMessage(msg.chat.id, "Already started."); + bot.sendMessage(msg.chat.id, "Already started.", {message_thread_id: msg.message_thread_id}); } await topicMode(db,bot,settings,String(msg.chat.id)); } - dbstart(db, 'telegram', String(msg.chat.id)) setRules(db, 'telegram', String(msg.chat.id), langJson[settings.lang].defaultRules, Math.floor(Date.now()/1000)); - bot.sendMessage(msg.chat.id, "I am now moderating this community.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + bot.sendMessage(msg.chat.id, `Hi! I'm a Kleros Moderator. I help communities crowdsource moderation. If you need help, just DM me : )\n\n${langJson[settings.lang].defaultRulesMsg1}(${langJson[settings.lang].defaultRules}).`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}: {parse_mode: "Markdown"}) return; } catch (e){ try{ diff --git a/lib/telegram/commands/toggleWelcome.ts b/lib/telegram/commands/toggleWelcome.ts index 8463b21..2d41eed 100644 --- a/lib/telegram/commands/toggleWelcome.ts +++ b/lib/telegram/commands/toggleWelcome.ts @@ -10,11 +10,6 @@ const regexp = /\/welcome/ const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { try{ - const user = await bot.getChatMember(msg.chat.id, String(msg.from.id)); - if (!(user.status === 'creator' || user.status === 'administrator')) { - await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorAdminOnly, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); - return; - } if (msg.chat.is_forum){ const topicWelcome = await bot.createForumTopic(msg.chat.id, 'Welcome', {icon_custom_emoji_id: '4929292553544531969'}); const msg1: TelegramBot.Message = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].greeting1}[Kleros Moderate](https://kleros.io/moderate/).`, {parse_mode: "Markdown", message_thread_id: topicWelcome.message_thread_id}); @@ -22,7 +17,7 @@ const callback = async (db: any, settings: groupSettings, bot: any, botId: numbe setThreadIDWelcome(db, 'telegram', String(msg.chat.id), String(topicWelcome.message_thread_id)) } setGreetingMode(db, 'telegram', String(msg.chat.id),settings.greeting_mode? 0: 1) - await bot.sendMessage(msg.chat.id, settings.greeting_mode? "Welcome messages are on." : "Welcome messages are off.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + bot.sendMessage(msg.chat.id, settings.greeting_mode? "Welcome messages are off." : "Welcome messages are on.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); } catch(e){ console.log(e) } diff --git a/lib/telegram/index.ts b/lib/telegram/index.ts index 3255ae0..12b22cc 100644 --- a/lib/telegram/index.ts +++ b/lib/telegram/index.ts @@ -9,14 +9,15 @@ import * as toggleWelcome from "../../lib/telegram/commands/toggleWelcome"; import * as greeting from "../../lib/telegram/commands/greeting"; import * as socialConsensus from "../../lib/telegram/commands/socialConsensus"; import * as addEvidence from "../../lib/telegram/commands/addEvidence"; +import * as leaveFed from "../../lib/telegram/commands/leavefed"; +import * as joinFed from "../../lib/telegram/commands/joinfed"; import * as start from "../../lib/telegram/commands/start"; import * as setLanguage from "../../lib/telegram/commands/setLanguage"; import * as setChannel from "../../lib/telegram/commands/setChannel"; import * as getReports from "../../lib/telegram/commands/getReports"; import langJson from "./assets/lang.json"; -import {groupSettings} from "../../types"; -import {openDb, getGroupSettings, eraseThreadID, dbstart, dbstarted} from "../db"; -import {Wallet} from "@ethersproject/wallet"; +import {groupSettings, groupSettingsUnderspecified} from "../../types"; +import {openDb, getGroupSettings, getRule, eraseThreadID} from "../db"; const Web3 = require('web3') const _batchedSend = require('web3-batched-send') @@ -27,74 +28,83 @@ const batchedSend = _batchedSend( process.env.PRIVATE_KEY, 20000 // The debounce timeout period in milliseconds in which transactions are batched. ) -var botAddress: string; + const defaultSettings: groupSettings = { + lang: 'en', + rules: langJson['en'].defaultRules, + channelID: '', + greeting_mode: false, + thread_id_rules: '', + thread_id_welcome: '', + thread_id_notifications: '' +} const ModeratorBot = require('node-telegram-bot-api'); const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: true, testEnvironment: false}); //bot. var botId: number; const db = openDb(); -const started : Map = new Map(); -const settings : Map = new Map(); +const NodeCache = require( "node-cache" ); +const myCache = new NodeCache( { stdTTL: 900, checkperiod: 1200 } ); // Throttling -const msgCounters : Map = new Map(); -const lastMsgEpochs : Map = new Map(); bot.on("my_chat_member", async function(myChatMember: any) { try{ - console.log(myChatMember) - if(myChatMember.chat.is_forum){ - return; - } + if(throttled(myChatMember.from.id) || myChatMember.chat.is_forum) + return const settings = validate(myChatMember.chat); if(myChatMember.chat.type === "channel"){ try{ - bot.sendMessage(myChatMember.chat.id, "The channel id is " + myChatMember.chat.id); + bot.sendMessage(myChatMember.chat.id, `The channel id is ${myChatMember.chat.id}`, {parse_mode: "HTML"}); } catch(e) { console.log(e) } return; - } - await welcome.callback(settings, bot, myChatMember); + } else if (myChatMember.chat.type === "supergroup") + welcome.callback(settings, bot, myChatMember); + else if (myChatMember.chat.type === "private") + return + else + try{ + bot.sendVideo(myChatMember.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {caption: "Group is not a supergroup. Please promote me to an admin."}); + } catch(e){ + console.log(e) + } } catch(e){ console.log("Welcome error." + e); } }); -bot.on("new_chat_members", async function (chatMemberUpdated: any) { - console.log('new chat member') - const settings = validate(chatMemberUpdated.chat); - if(!started.has(chatMemberUpdated.chat.id)) +bot.on("new_chat_members", async function (chatMemberUpdated: TelegramBot.ChatMemberUpdated) { + if(!hasStarted(chatMemberUpdated.chat.id)||throttled(chatMemberUpdated.from.id) ) return; - if (chatMemberUpdated.chat.type === "channel"){ + const settings = validate(chatMemberUpdated.chat); + if (chatMemberUpdated.chat.type !== "supergroup") return; - } - if (settings.greeting_mode) await greeting.callback(bot, settings, chatMemberUpdated); }); // Handle callback queries bot.on('callback_query', async function onCallbackQuery(callbackQuery: TelegramBot.CallbackQuery) { + if(!hasStarted(callbackQuery.message.chat.id)||throttled(callbackQuery.from.id)) + return; + const settings = validate(callbackQuery.message.chat); + const rawCalldata = callbackQuery.data; + const calldata = rawCalldata.split('|'); try{ - if(!botAddress) - botAddress = (await new Wallet(process.env.PRIVATE_KEY)).address; - if(!started.has(callbackQuery.message.chat.id)) - return; - const settings = validate(callbackQuery.message.chat); - - if (callbackQuery.data.length < 3){ - const user = await bot.getChatMember(callbackQuery.message.chat.id, String(callbackQuery.from.id)) - if (user.status !== "creator" && user.status !== "administrator") + if (Number(calldata[0]) === 0){ // set language + if (callbackQuery.from.id !== Number(calldata[1])) return; bot.deleteMessage(callbackQuery.message.chat.id, String(callbackQuery.message.message_id)) setLanguage.setLanguageConfirm(db, bot, settings, callbackQuery.data, callbackQuery.message); - } - else - await socialConsensus.callback(db, settings, botAddress, bot, callbackQuery, batchedSend); - } catch(error){ - console.log(error); - console.log("Social Consensus Error"); + } else if (Number(calldata[0]) === 1){ // add evidence + if (callbackQuery.from.id !== Number(calldata[1])) + return; + // handle addevidence callback + } else + await socialConsensus.callback(db, settings, bot, callbackQuery, batchedSend); + } catch(e){ + console.log("Callback Query Error" + e); } }); @@ -105,20 +115,25 @@ const commands: {regexp: RegExp, callback: any}[] = [ report, toggleWelcome, start, + leaveFed, + joinFed, setChannel, addEvidence, getReports, setLanguage, ]; +const adminOnlyCommands = [joinFed, leaveFed, setLanguage, setChannel, toggleWelcome, start, setRulesCommand ] + commands.forEach((command) => { bot.onText( command.regexp, async (msg: any, match: string[]) => { + if(throttled(msg.from.id) || msg.chat.type !== "supergroup") + return const groupSettings = validate(msg.chat); - if (command === start){ - if (started.has(msg.chat.id)){ + if (hasStarted(msg.chat.id)){ try{ bot.sendMessage(msg.chat.id, "Susie is already moderating this community.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id} : {}) return @@ -126,80 +141,104 @@ commands.forEach((command) => { console.log(e) } } - } else if(!started.has(msg.chat.id)){ + } else if(!hasStarted(msg.chat.id)){ return; } - if (!botId) - botId = (await bot.getMe()).id; + try{ + if (!botId) + botId = (await bot.getMe()).id; + } catch(e){ + console.log(e) + } + + if (adminOnlyCommands.indexOf(command)!==-1){ + var status = myCache.get("status"+msg.chat.id+msg.from.id) + if (!status){ + try{ + status = (await bot.getChatMember(msg.chat.id, String(msg.from.id))).status; + myCache.set("status"+msg.chat.id+msg.from.id,status) + } catch(e){ + console.log(e) + return; + } + } + if (!(status === 'creator' || status === 'administrator')) { + bot.sendMessage(msg.chat.id, langJson[groupSettings.lang].errorAdminOnly, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + return; + } + } + // todo success bool return val, to not always delete settings command.callback(db, groupSettings, bot, botId, msg, match,batchedSend); if (command === setLanguage || command === setRulesCommand || command === setChannel || command === toggleWelcome || command === start) - settings.delete(msg.chat.id) + myCache.del(msg.chat.id) } ) }) -const throttling = (chat: TelegramBot.Chat): boolean => { - const lastEpoch = lastMsgEpochs.get(chat.id) ?? 0; - const currentEpoch = Math.floor(Date.now()/1000) % 60; - if (currentEpoch > lastEpoch){ - lastMsgEpochs.set(chat.id, currentEpoch); - msgCounters.set(chat.id,1); + +const throttled = (userId: number): boolean => { + const count = myCache.get(userId) ?? 1 + if (count >100) + return true + myCache.set(userId.toString(), count + 1) + return false; +} + +const hasStarted = (chatid: number): boolean=> { + const cachedStarted = myCache.get("started"+chatid); + if (typeof cachedStarted !== 'undefined') + return cachedStarted; + const rules = getRule(db, 'telegram', String(chatid), Math.floor(Date.now()/1000)) + if (rules){ + myCache.set("started"+chatid, true) + return true; } - const msgCounter = msgCounters.get(chat.id); - if (msgCounter > 20) + else { + myCache.set("started"+chatid, false) return false; - msgCounters.set(chat.id,msgCounter+1); - return true; - + } } const validate = (chat: any): groupSettings=> { - var groupSettings : groupSettings = settings.get(chat.id) + if (!hasStarted(chat.id)){ + return defaultSettings; + } + var groupSettings : groupSettingsUnderspecified = myCache.get(chat.id) if (!groupSettings){ + const rules = getRule(db, 'telegram', String(chat.id), Math.floor(Date.now()/1000)) groupSettings = getGroupSettings(db, 'telegram', String(chat.id)) - console.log ('groupSettings fetched from db'); - console.log(groupSettings) - if(groupSettings){ - settings.set(chat.id, groupSettings) - started.set(chat.id, true) - } + groupSettings.rules = rules + myCache.set(chat.id, groupSettings) } - /* - if (groupSettings && !chat.is_forum && groupSettings.thread_id_notifications){ // turn topics off - eraseThreadID(db, 'telegram', String(chat.id)) - groupSettings.thread_id_notifications = '' - groupSettings.thread_id_rules = '' - groupSettings.thread_id_welcome = '' - settings.set(chat.id, groupSettings) - }*/ const fullSettings = { - lang: groupSettings?.lang ?? 'en', - rules: groupSettings?.rules ?? langJson['en'].defaultRules, + lang: groupSettings?.lang ?? defaultSettings.lang, + rules: groupSettings?.rules ?? defaultSettings.rules, channelID: groupSettings?.channelID ?? String(chat.id), - greeting_mode: groupSettings?.greeting_mode ?? false, - thread_id_rules: groupSettings?.thread_id_rules ?? '', - thread_id_welcome: groupSettings?.thread_id_welcome ?? '', - thread_id_notifications: groupSettings?.thread_id_notifications ?? '' + greeting_mode: groupSettings?.greeting_mode ?? defaultSettings.greeting_mode, + thread_id_rules: groupSettings?.thread_id_rules ?? defaultSettings.thread_id_rules, + thread_id_welcome: groupSettings?.thread_id_welcome ?? defaultSettings.thread_id_rules, + thread_id_notifications: groupSettings?.thread_id_notifications ?? defaultSettings.thread_id_notifications } console.log(fullSettings); return fullSettings } - +/* const checkMigration = async (groupSettings: groupSettings, chat: any): Promise => { + await bot.sendMessage(chat.id, "Started topic mode", {messsage_thread_id: groupSettings.thread_id_notifications}) if (chat.is_forum && !groupSettings.thread_id_notifications){ // turn topics on try{ const threads = await start.topicMode(db, bot, groupSettings, String(chat.id)); groupSettings.thread_id_rules = threads[0] groupSettings.thread_id_notifications = threads[1] groupSettings.channelID = String(chat.id) - settings.set(chat.id, groupSettings) + myCache.set(chat.id, groupSettings) } catch(e){ console.log(e) } } return groupSettings -} +}*/ console.log('Telegram bot ready...'); \ No newline at end of file From 71b3e4c974724099672960db998613ed0812dbf5 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Tue, 22 Nov 2022 22:56:36 -0800 Subject: [PATCH 005/111] feat(subgraph): refactor --- subgraph/schema.graphql | 19 ++---- .../Realitio_v2_1_ArbitratorWithAppeals.ts | 15 +++-- subgraph/src/reality-ethv-30.ts | 58 ++++++++++--------- 3 files changed, 46 insertions(+), 46 deletions(-) diff --git a/subgraph/schema.graphql b/subgraph/schema.graphql index d09e02e..16b7bce 100644 --- a/subgraph/schema.graphql +++ b/subgraph/schema.graphql @@ -20,7 +20,7 @@ type ModerationInfo @entity(immutable: true){ askedBy: Bytes! deadline: BigInt timeout: BigInt! - user: User! + UserHistory: UserHistory! dispute: ModerationDispute @derivedFrom(field: "moderationInfo") reality: RealityCheck } @@ -38,6 +38,7 @@ type RealityCheck @entity{ type UserHistory @entity{ id: ID! user: User! + group: Group! timestampLastUpdated: BigInt! timestampParole: BigInt! countBrokeRulesOptimisticAndArbitrated: Int! @@ -45,15 +46,14 @@ type UserHistory @entity{ countReportsMade: Int! countReportsMadeAndResponded: Int! timestampLastReport: BigInt! + moderation: [ModerationInfo!]! @derivedFrom(field: "UserHistory") } type User @entity(immutable: true){ id: ID! username: String userID: String! - group: Group! - history: UserHistory @derivedFrom(field: "user") - moderation: [ModerationInfo!]! @derivedFrom(field: "user") + history: [UserHistory!]! @derivedFrom(field: "user") } type Janny @entity{ @@ -73,14 +73,5 @@ type Group @entity(immutable: true){ platform: String! groupID: String! botAddress: Bytes! - users: [User!]! @derivedFrom(field: "group") -} - -type Group @entity(immutable: true){ - id: ID! - name: String - platform: String! - groupID: String! - botAddress: Bytes! - users: [User!]! @derivedFrom(field: "group") + UserHistory: [UserHistory!]! @derivedFrom(field: "group") } \ No newline at end of file diff --git a/subgraph/src/Realitio_v2_1_ArbitratorWithAppeals.ts b/subgraph/src/Realitio_v2_1_ArbitratorWithAppeals.ts index 9b1faf1..115bdbd 100644 --- a/subgraph/src/Realitio_v2_1_ArbitratorWithAppeals.ts +++ b/subgraph/src/Realitio_v2_1_ArbitratorWithAppeals.ts @@ -1,7 +1,8 @@ import { DisputeIDToQuestionID as DisputeIDToQuestionIDEvent, RulingFunded as RulingFundedEvent, - Ruling as RulingEvent + Ruling as RulingEvent, + Evidence as EvidenceEvent } from "../generated/Realitio_v2_1_ArbitratorWithAppeals/Realitio_v2_1_ArbitratorWithAppeals" import { ModerationDispute, ModerationInfo, UserHistory, @@ -16,7 +17,13 @@ import { moderationDispute.timestampLastUpdated = event.block.timestamp moderationDispute.save(); } - +/* + export function handleEvidenceEvent( + event: EvidenceEvent + ): void { + event.params._event.logIndex + } +*/ export function handleRuling(event: RulingEvent): void { const moderationDispute = ModerationDispute.load(event.params._disputeID.toHexString()); if (!moderationDispute){ @@ -31,9 +38,9 @@ import { log.error("ModerationInfo not found {}.", [moderationDispute.moderationInfo]); return; } - const userHistory = UserHistory.load(modinfo.user) + const userHistory = UserHistory.load(modinfo.UserHistory) if (!userHistory){ - log.error("UserHistory not found {}.", [modinfo.user]); + log.error("UserHistory not found {}.", [modinfo.UserHistory]); return; } diff --git a/subgraph/src/reality-ethv-30.ts b/subgraph/src/reality-ethv-30.ts index e60c621..3200b9d 100644 --- a/subgraph/src/reality-ethv-30.ts +++ b/subgraph/src/reality-ethv-30.ts @@ -13,9 +13,9 @@ export function handleLogNotifyOfArbitrationRequest(event: LogNotifyOfArbitratio log.error('moderation info not found. {}',[event.params.question_id.toHexString()]) return } - let userHistory = UserHistory.load(moderationInfo.user) + let userHistory = UserHistory.load(moderationInfo.UserHistory) if (!userHistory){ - log.error('user history not found. {}',[moderationInfo.user]) + log.error('user history not found. {}',[moderationInfo.UserHistory]) return } if(RealityETHV30.bind(event.address).getBestAnswer(event.params.question_id) === new Bytes(1)){ @@ -42,19 +42,11 @@ export function handleLogNewAnswer(event: LogNewAnswer): void { if (!realityCheck) realityCheck = new RealityCheck(event.params.question_id.toHexString()) - let userHistory = UserHistory.load(moderationInfo.user) + let userHistory = UserHistory.load(moderationInfo.UserHistory) if (!userHistory){ - userHistory = new UserHistory(moderationInfo.user) - userHistory.countBrokeRulesArbitrated = 0 - userHistory.countBrokeRulesOptimisticAndArbitrated = 0 - userHistory.countReportsMade = 0 - userHistory.countReportsMadeAndResponded = 0 - userHistory.timestampLastReport = BigInt.fromU32(0) - userHistory.timestampLastUpdated = BigInt.fromU32(0) - userHistory.timestampParole = BigInt.fromU32(0) - userHistory.user = moderationInfo.user + log.error('user missing {}',[moderationInfo.UserHistory]); + return; } - const reportedByUserHistory = UserHistory.load(moderationInfo.reportedBy) if (!reportedByUserHistory){ log.error('reportedByUserHistory missing {}',[moderationInfo.reportedBy]); @@ -63,16 +55,11 @@ export function handleLogNewAnswer(event: LogNewAnswer): void { reportedByUserHistory.countReportsMadeAndResponded++ reportedByUserHistory.save() - const user = User.load(moderationInfo.user) - if (!user){ - log.error('user missing {}',[moderationInfo.user]); - return; - } - var janny = Janny.load(user.group) + var janny = Janny.load(userHistory.group) if(!janny){ - janny = new Janny(user.group) - janny.group = user.group + janny = new Janny(userHistory.group) + janny.group = userHistory.group } let sheriffOld = janny.sheriff @@ -154,7 +141,7 @@ export function handleLogNewQuestion(event: LogNewQuestion): void { //if (event.params.template_id.toU32() === 60){ //XDAI const questionString = event.params.question; const params = questionString.split('\u241f'); - if (params.length < 10) + if (params.length < 8) return; let group = Group.load(event.transaction.from.toHexString() + params[2] + params[5]); @@ -169,11 +156,10 @@ export function handleLogNewQuestion(event: LogNewQuestion): void { } let user = User.load(event.transaction.from.toHexString() + params[2] + params[1]); - if (user === null) { + if (!user) { user = new User(event.transaction.from.toHexString() + params[2] + params[1]); user.userID = params[1]; user.username = params[0]; - user.group = event.transaction.from.toHexString() + params[2] + params[5]; user.save(); } @@ -182,7 +168,6 @@ export function handleLogNewQuestion(event: LogNewQuestion): void { moderationInfo.reportedBy = event.transaction.from.toHexString()+params[2] + params[9] if (!User.load(moderationInfo.reportedBy)){ const userReportedBy = new User(moderationInfo.reportedBy) - userReportedBy.group = user.group userReportedBy.userID = params[9] userReportedBy.save() } @@ -193,14 +178,31 @@ export function handleLogNewQuestion(event: LogNewQuestion): void { moderationInfo.message = params[7]; moderationInfo.reality = event.params.question_id.toHexString() moderationInfo.messageBackup = params[8]; - moderationInfo.user = event.transaction.from.toHexString() + params[2] + params[1]; + + var reportedUser = UserHistory.load(event.transaction.from.toHexString() + params[2] + params[1]+params[5]) + if (!reportedUser){ + reportedUser = new UserHistory(event.transaction.from.toHexString() + params[2] + params[1]+params[5]) + reportedUser.countBrokeRulesArbitrated = 0 + reportedUser.countBrokeRulesOptimisticAndArbitrated = 0 + reportedUser.countReportsMade = 0 + reportedUser.countReportsMadeAndResponded = 0 + reportedUser.timestampLastReport = BigInt.fromU32(0) + reportedUser.timestampLastUpdated = BigInt.fromU32(0) + reportedUser.timestampParole = BigInt.fromU32(0) + reportedUser.user = event.transaction.from.toHexString() + params[2] + params[1] + reportedUser.group = group.id + reportedUser.save() + } + moderationInfo.UserHistory = reportedUser.id; + moderationInfo.save(); - var reportedByUserHistory = UserHistory.load(moderationInfo.reportedBy) + var reportedByUserHistory = UserHistory.load(moderationInfo.reportedBy+params[5]) if (!reportedByUserHistory){ - reportedByUserHistory = new UserHistory(moderationInfo.reportedBy) + reportedByUserHistory = new UserHistory(moderationInfo.reportedBy+params[5]) reportedByUserHistory.user = moderationInfo.reportedBy + reportedByUserHistory.group = group.id reportedByUserHistory.countReportsMade = 0 reportedByUserHistory.countBrokeRulesOptimisticAndArbitrated = 0 reportedByUserHistory.countBrokeRulesArbitrated = 0 From eb46bba91040a002ac065c2d64d7a8c8e9ff0f07 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Mon, 28 Nov 2022 22:52:15 -0800 Subject: [PATCH 006/111] feat: big update --- lib/db.ts | 21 +- lib/graph.ts | 20 +- lib/telegram/assets/lang.json | 17 +- lib/telegram/commands/addEvidence.ts | 6 +- lib/telegram/commands/getChannel.ts | 16 ++ lib/telegram/commands/help.ts | 291 +++++++++++++++++++++++ lib/telegram/commands/setChannel.ts | 22 +- lib/telegram/commands/setLanguage.ts | 19 +- lib/telegram/commands/socialConsensus.ts | 26 +- lib/telegram/commands/start.ts | 28 ++- lib/telegram/commands/welcome.ts | 1 - lib/telegram/index.ts | 69 +++--- package.json | 2 + 13 files changed, 457 insertions(+), 81 deletions(-) create mode 100644 lib/telegram/commands/getChannel.ts create mode 100644 lib/telegram/commands/help.ts diff --git a/lib/db.ts b/lib/db.ts index 37ac008..e12da37 100644 --- a/lib/db.ts +++ b/lib/db.ts @@ -233,7 +233,7 @@ const getGroupSettings = (db: any, platform: string, groupId: string): groupSett return { lang: result?.lang, rules: undefined, - channelID: result?.channelID, + channelID: result?.channel_id, thread_id_rules: result?.thread_id_rules, thread_id_notifications: result?.thread_id_notifications, thread_id_welcome: result?.thread_id_welcome, @@ -299,10 +299,10 @@ const getRecordCount = (db: any, platform: string, groupId: string) => { const getAllowance = (db: any, platform: string, groupId: string, userId: string): {report_allowance: number, evidence_allowance: number, timestamp_refresh: number, question_id_last: string, timestamp_last_question: number} | undefined => { try{ - const stmt = db.prepare('SELECT report_allowance, evidence_allowance, timestamp_refresh, question_id_last, timestamp_last_question FROM allowance WHERE user_id = ? AND group_id = ? AND platform = ?'); + const stmt = db.prepare('SELECT report_allowance, evidence_allowance, timestamp_refresh FROM allowance WHERE user_id = ? AND group_id = ? AND platform = ?'); return stmt.all(userId, groupId, platform); - } catch{ - console.log("db error: getAllowance"); + } catch(e){ + console.log("db error: getAllowance "+e); } } @@ -328,13 +328,13 @@ const setAllowance = async( try{ const stmt = db.prepare( `INSERT INTO allowance (platform, group_id, user_id, report_allowance, evidence_allowance, timestamp_refresh) - VALUES ($platform, $group_id, $user_id, $report_allowance, $evidence_allowance, $timestamp_refresh) + VALUES (?, ?, ?, ?, ?, ?) ON CONFLICT(platform, group_id, user_id) DO UPDATE SET - report_allowance=$report_allowance, evidence_allowance = $evidence_allowance, timestamp_refresh = $timestamp_refresh;` + report_allowance=?, evidence_allowance = ?, timestamp_refresh = ?;` ); - const info = stmt.run(platform, groupId, userId, reportAllowance, evidenceAllowance, timeRefresh); - } catch { - console.log("db error: setAllowance"); + const info = stmt.run(platform, groupId, userId, reportAllowance, evidenceAllowance, timeRefresh,reportAllowance, evidenceAllowance, timeRefresh); + } catch(e) { + console.log("db error: setAllowance"+e); } } @@ -411,7 +411,6 @@ const addReport = ( platform, group_id, user_id, - username, msg_id, timestamp, evidenceIndex) @@ -471,4 +470,4 @@ export { getThreadIDNotifications, getThreadIDRules, getRule -} +} \ No newline at end of file diff --git a/lib/graph.ts b/lib/graph.ts index 5b36477..e99b25b 100644 --- a/lib/graph.ts +++ b/lib/graph.ts @@ -55,4 +55,22 @@ const existsQuestionId = async (question_id: string): Promise => { + const query = `{ + moderationInfos(where: {deadline_gt: ${Math.floor(Date.now()/1000)}, askedBy: "${botaddress}"}) { + id + } + }`; + console.log(query); + try{ + return (await request( + 'https://api.thegraph.com/subgraphs/name/shotaronowhere/kleros-moderate-goerli', + query + )); + } catch(e){ + console.log(e) + return undefined + } +} + +export{getQuestionId, existsQuestionId, getAllowance, getQuestionsNotFinalized} \ No newline at end of file diff --git a/lib/telegram/assets/lang.json b/lib/telegram/assets/lang.json index f76fdf2..16f9632 100644 --- a/lib/telegram/assets/lang.json +++ b/lib/telegram/assets/lang.json @@ -26,6 +26,7 @@ }, "report" : { "errorAdmin": "An admin can't be reported.", + "errorModBot": "Bots can't be reported.", "reported": "The message is already [reported]", "requested": "This message report is already [requested]", "info1": "Are you sure the user", @@ -36,7 +37,7 @@ "allowance2": "was unanswered. Report permissions are limited for 3 days until the previous report is answered.", "noallowance": "You have exhausted your daily report allowance." }, - "socialCensensus" : { + "socialConsensus" : { "confirm": "confirm", "reported": "The message is already [reported]", "reportConfirm": "Report confirmed.", @@ -46,7 +47,7 @@ "consensus4": "due to conduct over this [message]", "consensus5": "backup" }, - "addEvidence" : { + "addevidence" : { "submitted": "Evidence [submitted]", "error1": "must be followed by a", "id": "Evidence Group ID", @@ -74,12 +75,14 @@ "errorRules" : "Invalid url passed to /setrules", "rulesUpdated" : "Rules updated.", "answer": "answer", + "welcome": "Hi, I'm Susie, a ", "greeting1": "Welcome, this group is moderated with ", "greeting2": "Please make sure to follow the [community rules]", - "greeting3": "Users who break the rules can be reported by replying to a message with the command '/report'.", + "greeting3": "Users who break the rules can be reported by replying to a message with the command /report.", "defaultRules": "https://ipfs.kleros.io/ipfs/QmYYcNfEYLtxPM8fof4wf9Tqj7gBGMDMmNnBqZKR1zSczX/Kleros%20Moderate%20Community%20Guidelines%20v1.pdf", - "defaultRulesMsg1": "The Kleros Moderate Community Guidelines apply as the default [rules].", - "defaultRulesMsg2": "Crafting precise policies can be challenging, if you are certain in setting a new policy, you can set new rules with /setrules [url] or /setrules [reply to message]." + "defaultRulesMsg1": "The Kleros Moderate Community Guidelines apply as the default [rules]", + "defaultRulesMsg1alt": "The Kleros Moderate Community Guidelines apply as the default rules", + "defaultRulesMsg2": "Crafting precise policies can be challenging, if you are certain in setting a new policy, you can set new rules with /setrules \\[url] or /setrules \\[reply to message]" }, "es":{ "errorMatchLanguage": "/setlanguage must be followed by a supported language code ('en', 'es')", @@ -128,7 +131,7 @@ "consensus4": "due to conduct over this [message]", "consensus5": "backup" }, - "addEvidence" : { + "addevidence" : { "submitted": "Evidence [submitted]", "error1": "must be followed by a", "id": "Evidence Group ID", @@ -158,7 +161,7 @@ "answer": "answer", "greeting1": "Welcome, this group is moderated with ", "greeting2": "Please make sure to follow the [community rules]", - "greeting3": "Users who break the rules can be reported by replying to a message with the command '/report'.", + "greeting3": "Users who break the rules can be reported by replying to a message with the command /report.", "defaultRules": "https://ipfs.kleros.io/ipfs/QmYYcNfEYLtxPM8fof4wf9Tqj7gBGMDMmNnBqZKR1zSczX/Kleros%20Moderate%20Community%20Guidelines%20v1.pdf", "defaultRulesMsg1": "The Kleros Moderate Community Guidelines apply as the default [rules].", "defaultRulesMsg2": "Crafting precise policies can be challenging, if you are certain in setting a new policy, you can set new rules with /setrules [url] or /setrules [reply to message]." diff --git a/lib/telegram/commands/addEvidence.ts b/lib/telegram/commands/addEvidence.ts index 6080354..4a26a6a 100644 --- a/lib/telegram/commands/addEvidence.ts +++ b/lib/telegram/commands/addEvidence.ts @@ -3,6 +3,7 @@ import {Wallet} from "@ethersproject/wallet"; import {ipfsPublish, ipfsPublishBuffer} from "../../ipfs-publish"; import { setAllowance, getAllowance, getActiveEvidenceGroupId } from "../../db"; import fetch from 'node-fetch'; +import { getQuestionsNotFinalized } from "../../graph"; import { groupSettings } from "../../../types"; import langJson from "../assets/lang.json"; const _contract = require('../../abi/Realitio_v2_1_ArbitratorWithAppeals.json') @@ -165,11 +166,14 @@ const callback = async (db: any, settings: groupSettings, bot: any, botID: numbe bot.sendMessage(msg.chat.id, `/addevidence ${langJson[settings.lang].errorReply}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) return; } - + if (!botAddress) + botAddress = await (await new Wallet(process.env.PRIVATE_KEY)).address.toLowerCase(); const match = msg.text.match(regexpFull); //TODO Evidence IDs and button callback UX if (!match || match.length < 2){ + const questions = await getQuestionsNotFinalized(botAddress) + bot.sendMessage(msg.chat.id, `Did you mean `+ JSON.stringify(questions)); bot.sendMessage(msg.chat.id, `/addevidence ${langJson[settings.lang].addevidence.error1} ${langJson[settings.lang].addevidence.id}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) //const errorMsg = await errorMessage(db, lang, bot, msg); //await bot.sendMessage(msg.chat.id, errorMsg, {parse_mode: "Markdown", disable_web_page_preview: true}); diff --git a/lib/telegram/commands/getChannel.ts b/lib/telegram/commands/getChannel.ts new file mode 100644 index 0000000..82d0f6e --- /dev/null +++ b/lib/telegram/commands/getChannel.ts @@ -0,0 +1,16 @@ +import * as TelegramBot from "node-telegram-bot-api"; +import {getRule, getInviteURLChannel} from "../../db"; +import langJson from "../assets/lang.json"; +import { groupSettings } from "../../../types"; + +/* + * /getrules + */ +const regexp = /\/getchannel/ + +const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { + const channel_invite = getInviteURLChannel(db, 'telegram', msg.chat.id); + bot.sendMessage(msg.chat.id, `I notify this [channel](${channel_invite}) about moderation activity.`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}); +} + +export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/help.ts b/lib/telegram/commands/help.ts new file mode 100644 index 0000000..44673da --- /dev/null +++ b/lib/telegram/commands/help.ts @@ -0,0 +1,291 @@ +import * as TelegramBot from "node-telegram-bot-api"; +import langJson from "../assets/lang.json"; +import { groupSettings } from "../../../types"; + +/* + * /getrules + */ +const regexp = /\/help/ + +const callback = (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { + if (msg.chat.type !== "private"){ + const opts = msg.chat.is_forum? { + message_thread_id: msg.message_thread_id, + parse_mode: 'Markdown', + reply_markup: { + inline_keyboard: [ + [ + { + text: 'Get Help (DM)', + url: `tg://user?id=${botId}&start=help` + } + ] + ] + } + }: { + parse_mode: 'Markdown', + reply_markup: { + inline_keyboard: [ + [ + { + text: 'Get Help (DM)', + url: `https://t.me/KlerosModeratorBot?start=help` + //url: `tg://user?id=${botId}&start=help` + } + ] + ] + } + } + bot.sendMessage(msg.chat.id, `DM me for help : )`, opts); + return; + } + bot.sendMessage(msg.chat.id, message,opts); +} + +const respond = (settings: groupSettings, bot: any, helpType: string, callbackQuery: TelegramBot.CallbackQuery) => { + const optsResponse = { + chat_id: callbackQuery.message.chat.id, + message_id: callbackQuery.message.message_id, + parse_mode: 'Markdown', + disable_web_page_preview: true + }; + try{ + if (helpType !== 'back'){ + bot.editMessageReplyMarkup({ inline_keyboard: [[ + { + text: 'back', + callback_data: `3|back` + } + ]]}, optsResponse) + } else { + bot.editMessageReplyMarkup({ + inline_keyboard: [ + [ + { + text: '👋 Greeting', + callback_data: `3|greeting` + }, { + text: '🗣️ Language', + callback_data: `3|language` + }, { + text: 'ℹ️ Topics', + callback_data: `3|topics` + } + ], + [ + { + text: '🔍 Evidence', + callback_data: `3|addevidence` + }, { + text: '🚨 Report', + callback_data: `3|report` + }, { + text: '⚖️ Rules', + callback_data: `3|rules` + } + ], + [ + { + text: '🔔 Notifications', + callback_data: `3|notifications` + }, { + text: '🌐 Federation', + callback_data: `3|federation` + }, { + text: '⬨ Web 2.5', + callback_data: `3|web2.5` + } + ] + ]}, optsResponse) + bot.editMessageText(message,optsResponse) + } + switch(helpType){ + case 'greeting': { + bot.editMessageText(`👋 *Greeting* 👋 + +Welcome your members with a greeting informing them of the group rules + +*Admin commands:* +- /welcome : Toggles on/off welcomes messages. +- /captcha : Toggles on/off rules captcha. + +When a new person joins, or after 5 minutes, the previous welcome messages will get deleted, but the captchas will remain for up to 5 minutes. + `,optsResponse) + break; + } + case 'language': { + bot.editMessageText(`🗣️ *Languages* 🗣️ + +Susie's replies can be changed to one of the languages below. + +- EN (English) +- ES (Español) *soon* + +*Admin commands*: +- /setlang : Set your preferred language. + +Content moderation requires a nuanced understanding of context and language. Setting a language not only changes Susie's responses, but also specifies language skilled jurors. + +Please make sure to set the appropriate language for your community for effective moderation.` + ,optsResponse) + break; + } + case 'topics': { + bot.editMessageText(`ℹ️ *Topics* ℹ️ + +Topics allow large (>200 member) groups to focus discussion in dedicated **topic** chats. Susie supports topics. When changing a group to topic mode, you will need to /start Susie again. + +*Admin commands*: +- /start: Start topic mode.` + ,optsResponse) + break; + } + case 'addevidence': { + bot.editMessageText(`🔍 *Evidence* 🔍 + +To prevent important messages from deletion, pre-emptively, messages can be saved as evidence. + +*User commands*: +- /addevidence : Reply to a message to add it as evidence` + ,optsResponse) + break; + } + case 'report': { + bot.editMessageText(`🚨 *Report* 🚨 + +As groups grow, so do their moderation problems. We're all busy people who don't have time to monitor groups 24/7. Often users dispute moderation actions by admins and have no recourse. Who moderates the moderator? + +Presenting Kleros Moderate, a crowd-sourced content moderation tool using Reality.eth and Kleros. + +When users are reported, a question is created on Reality.Eth asking 'did the user break the rules?'. The question can be answered yes/no with a bond (5 DAI). Successful reports result in penalties (1 day ban, 1 week ban, 1 year ban). + +Answers to reports can be disputed, creating a case in the Kleros court. Refer to the [docs](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator) to learn more. + +*User commands*: +- /report : Reply to a message to report it +- /getreports: Returns active reports +- /getreports : Returns active reports` + ,optsResponse) + break; + } + case 'rules': { + bot.editMessageText(`⚖️ *Rules* ⚖️ + +The [Kleros Moderate Community Guidelines](https://ipfs.kleros.io/ipfs/QmYYcNfEYLtxPM8fof4wf9Tqj7gBGMDMmNnBqZKR1zSczX/Kleros%20Moderate%20Community%20Guidelines%20v1.pdf) apply as the default rules. Crafting precise policies can be challenging, if you are certain in setting a new policy, you can set new rules with /setrules + +*User commands*: +- /getrules: Returns current rules +*Admin commands*: +- /setrules : Sets the rules to the the url +- /setrules : Sets the rules to a replied message` + ,optsResponse) + break; + } + case 'notifications': { + bot.editMessageText(`🔔 *Notifications* 🔔 + +Susie sends notifications about moderation actions and report updates. These notifications are restricted to a separate chat in topic mode. In regular Telegram groups, notifications can be sent to a notification channel to avoid cluttering the main chat. + +How to enable notification channels: + +1. Make a channel +2. Add Susie +3. Susie will send a channel ID +4. Use that channel ID to set notifications with /setchannel in the original group + +*User commands*: +- /getchannel: Returns current notification channel +*Admin commands*: +- /setchannel : Sets the rules to the the url` + ,optsResponse) + break; + } + case 'federation': { + bot.editMessageText(`🌐 *Federations* + +Moderating a single group is hard, but managing multiple is even harder? Do you have to ban spammers manually, in all your groups? + +No more! With federations, Susie can enforce a ban on a user in all federate groups. + +*User commands*: +- /getfed: Returns current federation +*Admin commands*: +- /newfed: Creates a federation +- /joinfed: Joins the current group to a Federation` + ,optsResponse) + break; + } + case 'web2.5': { + bot.editMessageText(`⬨ *Web 2.5* ⬨ + +Susie uses web3 (Reality.eth and Kleros) with *skin in the game* mechanics to moderate a web2 platform (Telegram). Susie's inner workings are [opensource](https://github.com/kleros/kleros-moderate). Feel free to make an issue, feature request, bug report, comments, suggests, PRs, forks, etc : ) + +This instance of Susie is hosted as a service. You can self-host the bot, a raspberry pi or an old laptop are sufficient to keep your own instance of Susie online. To learn more about self-hosting, see this [guide](https://github.com/kleros/kleros-moderate/self-hosting.md).` + ,optsResponse) + break; + } + default: { + break; + } + } + } catch(e){ + console.log('help response error '+e); + } +} + +const message = `*Help*\n\nHi! My name is Susie. I'm a [Kleros Moderate](https://kleros.io/moderate) bot, here to help you manage your groups! + +I have lots of handy features, such as crowd-sourced user reporting. + +Helpful commands: + - /start: Starts me. You've probably already used this. + - /help: Sends this message and I'll tell you more about myself. + +Select a feature to learn more. My [documentation](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator) is also helpful, or ask a question in @SusieSupport.`; + +const opts = { + parse_mode: 'Markdown', + disable_web_page_preview: true, + reply_markup: { + inline_keyboard: [ + [ + { + text: '👋 Greeting', + callback_data: `3|greeting` + }, { + text: '🗣️ Language', + callback_data: `3|language` + }, { + text: 'ℹ️ Topics', + callback_data: `3|topics` + } + ], + [ + { + text: '🔍 Evidence', + callback_data: `3|addevidence` + }, { + text: '🚨 Report', + callback_data: `3|report` + }, { + text: '⚖️ Rules', + callback_data: `3|rules` + } + ], + [ + { + text: '🔔 Notifications', + callback_data: `3|notifications` + }, { + text: '🌐 Federation', + callback_data: `3|federation` + }, { + text: '⬨ Web 2.5', + callback_data: `3|web2.5` + } + ] + ] + } +} + +export {regexp, callback, respond}; \ No newline at end of file diff --git a/lib/telegram/commands/setChannel.ts b/lib/telegram/commands/setChannel.ts index 6f4d5c2..d299e36 100644 --- a/lib/telegram/commands/setChannel.ts +++ b/lib/telegram/commands/setChannel.ts @@ -24,35 +24,35 @@ const callback = async (db: any, settings: groupSettings, bot: TelegramBot, botI return; } } catch(e){ - await bot.sendMessage(msg.chat.id, `${newmatch[1]} is not a valid channel.`); + try{ + bot.sendMessage(msg.chat.id, `${newmatch[1]} is not a valid channel.`); + } catch(e){ + console.log(e) + } return; } const channelUser = await bot.getChatMember(newmatch[1], String(msg.from.id)); if(channelUser.status !== "administrator" && channelUser.status !== "creator"){ - console.log(channelUser) await bot.sendMessage(msg.chat.id, 'You are not an authorized admin of the channel.'); return; } const channelUserSusie = await bot.getChatMember(newmatch[1], botId); if (channelUserSusie.status !== "administrator"){ - await bot.sendMessage(msg.chat.id, 'The channel must have Susie as an admin.'); bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {caption: langJson[settings.lang].errorAdminRights}); return; } if(!channelUserSusie.can_invite_users){ - await bot.sendMessage(msg.chat.id, 'Susie must be able to invite users to the channel.'); + bot.sendMessage(msg.chat.id, 'Susie must be able to invite users to the channel.'); return; } - console.log('madeit'); const invite_url_channel = await bot.exportChatInviteLink(newmatch[1]); - console.log('madeit'); - const result = setInviteURLChannel(db, 'telegram', String(msg.chat.id), invite_url_channel); - console.log('madeit'); - await setChannelID(db, 'telegram', String(msg.chat.id), newmatch[1]); - await bot.sendMessage(msg.chat.id, `Moderation announcement [channel](${invite_url_channel}).`, {parse_mode: "Markdown"}); + setInviteURLChannel(db, 'telegram', String(msg.chat.id), invite_url_channel); + setChannelID(db, 'telegram', String(msg.chat.id), newmatch[1]); + bot.sendMessage(msg.chat.id, `Moderation announcement [channel](${invite_url_channel}).`, {parse_mode: "Markdown"}); + bot.sendMessage(newmatch[1], `This channel will now relay moderation notifications for ${msg.chat.title}`, {parse_mode: "Markdown"}); } catch (error) { console.log(error); } } -export {regexp, callback, validateUrl}; \ No newline at end of file +export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/setLanguage.ts b/lib/telegram/commands/setLanguage.ts index 0df5b15..3efc654 100644 --- a/lib/telegram/commands/setLanguage.ts +++ b/lib/telegram/commands/setLanguage.ts @@ -15,7 +15,7 @@ const callback = async (db: any, settings: groupSettings, bot: any, botId: numbe if (langJson[langCode]) { setLanguageConfirm(db, bot, settings, langCode, msg) } else { - const errorLanguage = `The language you requested is not yet available. Head to @SusieSupportChannel or linguo for information on how to add more translations!` + const errorLanguage = `The language you requested is not yet available. Head to @KlerosModerateNews or @linguoKleros for information on how to add more translations!` await bot.sendMessage(msg.chat.id, errorLanguage, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) const opts = msg.chat.is_forum? { message_thread_id: msg.message_thread_id, @@ -48,12 +48,17 @@ const callback = async (db: any, settings: groupSettings, bot: any, botId: numbe } const setLanguageConfirm = async (db: any, bot: any, settings: groupSettings, langCode: string, msg: any) => { - setLang(db, 'telegram', String(msg.chat.id),langCode); - setRules(db, 'telegram', String(msg.chat.id), langJson[langCode].defaultRules, Math.floor(Date.now()/1000)); - bot.sendMessage(msg.chat.id, langJson[langCode].confirmationLanguage, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); - const msgDefaultRules = await bot.sendMessage(msg.chat.id, `${langJson[langCode].defaultRulesMsg1}(${langJson[langCode].defaultRules}). ${langJson[settings.lang].defaultRulesMsg2}.`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: settings.thread_id_rules}: {}) - const msgRules = await bot.forwardMessage(msg.chat.id, msg.chat.id, msgDefaultRules.message_id, {message_thread_id: settings.thread_id_rules}); - bot.pinChatMessage(msg.chat.id, msgRules.message_id, {message_thread_id: settings.thread_id_rules}) + try{ + bot.deleteMessage(msg.chat.id, String(msg.message_id)) + setLang(db, 'telegram', String(msg.chat.id),langCode); + setRules(db, 'telegram', String(msg.chat.id), langJson[langCode].defaultRules, Math.floor(Date.now()/1000)); + bot.sendMessage(msg.chat.id, langJson[langCode].confirmationLanguage, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + const msgDefaultRules = await bot.sendMessage(msg.chat.id, `${langJson[langCode].defaultRulesMsg1}(${langJson[langCode].defaultRules}). ${langJson[langCode].defaultRulesMsg2}.`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: settings.thread_id_rules}: {}) + const msgRules = await bot.forwardMessage(msg.chat.id, msg.chat.id, msgDefaultRules.message_id, {message_thread_id: settings.thread_id_rules}); + bot.pinChatMessage(msg.chat.id, msgRules.message_id, {message_thread_id: settings.thread_id_rules}) + } catch(e){ + console.log('setLanguageConfirm error '+e); + } } export {regexp, callback, setLanguageConfirm}; \ No newline at end of file diff --git a/lib/telegram/commands/socialConsensus.ts b/lib/telegram/commands/socialConsensus.ts index d0849eb..3ac1a6a 100644 --- a/lib/telegram/commands/socialConsensus.ts +++ b/lib/telegram/commands/socialConsensus.ts @@ -46,22 +46,24 @@ const callback = async (db: any, settings: groupSettings, bot: TelegramBot, call } const optsFinal = msg.chat.is_forum? { chat_id: msg.chat.id, - message_id: msg.message_id, - text: "User Reported." + message_id: msg.message_id } : { chat_id: msg.chat.id, message_id: msg.message_id, - message_thread_id: msg.message_thread_id, - text: "User Reported." + message_thread_id: msg.message_thread_id } - if (newConfirmations > 1){ - bot.editMessageReplyMarkup({ inline_keyboard: []}, optsFinal) - bot.editMessageText("User Reported.") - const user = (await bot.getChatMember(String(msg.chat.id), String(calldata[1]))).user; - const fromUsername = user.username || user.first_name || `no-username-set`; - await reportMsg(settings, db, bot, msg, fromUsername, String(calldata[1]), msg.entities[1].url, String(calldata[2]), msg.entities[3].url, calldata[3],batchedSend); - } else{ - bot.editMessageReplyMarkup(markdown, opts) + try{ + if (newConfirmations > 1){ + bot.editMessageReplyMarkup({ inline_keyboard: []}, optsFinal) + bot.editMessageText("User Reported.",optsFinal) + const user = (await bot.getChatMember(String(msg.chat.id), String(calldata[1]))).user; + const fromUsername = user.username || user.first_name || `no-username-set`; + await reportMsg(settings, db, bot, msg, fromUsername, String(calldata[1]), msg.entities[1].url, String(calldata[2]), msg.entities[3].url, calldata[3],batchedSend); + } else{ + bot.editMessageReplyMarkup(markdown, opts) + } + } catch(e){ + console.log('social consensus error'+e); } } diff --git a/lib/telegram/commands/start.ts b/lib/telegram/commands/start.ts index 6561c82..e581264 100644 --- a/lib/telegram/commands/start.ts +++ b/lib/telegram/commands/start.ts @@ -11,6 +11,28 @@ const regexp = /\/start/ const callback = async (db: any, settings: groupSettings, bot: any, botID: string, msg: any) => { // admin check try{ + if (msg.chat.type === "private"){ + const opts = { + parse_mode: 'Markdown', + reply_markup: { + inline_keyboard: [ + [ + { + text: 'Add me to your group!', + url: `https://t.me/KlerosModeratorBot?startgroup=botstart` + } + ] + ] + } + } + bot.sendMessage(msg.chat.id, `Hi! My name is Susie. + +I am a [Kleros Moderate](https://kleros.io/moderate) community manager at your service. Hit /help to find out more about how to use me to my full potential. + +Join my news channel @KlerosModerateNews to get information on all the latest updates.`, opts) + return; + } + const botUser = await bot.getChatMember(msg.chat.id, botID) if(botUser.status !== "administrator" || !botUser.can_restrict_members){ bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', msg.chat.is_forum? {message_thread_id: msg.message_thread_id, caption: "Please give Susie full admin rights.\n\nThen try to /start community moderation again."} : {caption: "Please give Susie full admin rights.\n\nThen try to /start community moderation again."}); @@ -28,7 +50,11 @@ const callback = async (db: any, settings: groupSettings, bot: any, botID: strin await topicMode(db,bot,settings,String(msg.chat.id)); } setRules(db, 'telegram', String(msg.chat.id), langJson[settings.lang].defaultRules, Math.floor(Date.now()/1000)); - bot.sendMessage(msg.chat.id, `Hi! I'm a Kleros Moderator. I help communities crowdsource moderation. If you need help, just DM me : )\n\n${langJson[settings.lang].defaultRulesMsg1}(${langJson[settings.lang].defaultRules}).`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}: {parse_mode: "Markdown"}) + bot.sendMessage(msg.chat.id, `Hi! My community moderation tools are at your service. + +[DM](https://t.me/KlerosModeratorBot?start=help) me to find out more about how to use me to my full potential : ) + +${langJson[settings.lang].defaultRulesMsg1}(${langJson[settings.lang].defaultRules}).`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}: {parse_mode: "Markdown"}) return; } catch (e){ try{ diff --git a/lib/telegram/commands/welcome.ts b/lib/telegram/commands/welcome.ts index 92a2eea..34b696a 100644 --- a/lib/telegram/commands/welcome.ts +++ b/lib/telegram/commands/welcome.ts @@ -10,7 +10,6 @@ const callback = async (settings: groupSettings, bot: any, msg: any) => { try { if (msg.old_chat_member.status !== "left") return; - const message = `${langJson[settings.lang].welcome}[Kleros Moderate](https://kleros.io/moderate/) bot. \n\n/start to begin community sourced moderation.`; bot.sendMessage(msg.chat.id, `${langJson[settings.lang].welcome}[Kleros Moderate](https://kleros.io/moderate/) bot. \n\n/start to begin community sourced moderation.`, msg.chat.is_forum? {parse_mode: "Markdown"} : {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}); //const options = msg.chat.is_forum? {message_thread_id: msg.message_thread_id, caption: "To get started, give Susie admin rights."} : {caption: "To get started, give Susie admin rights."} //bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', options); diff --git a/lib/telegram/index.ts b/lib/telegram/index.ts index 12b22cc..00f8cf2 100644 --- a/lib/telegram/index.ts +++ b/lib/telegram/index.ts @@ -7,6 +7,7 @@ import * as report from "../../lib/telegram/commands/report"; import * as welcome from "../../lib/telegram/commands/welcome"; import * as toggleWelcome from "../../lib/telegram/commands/toggleWelcome"; import * as greeting from "../../lib/telegram/commands/greeting"; +import * as help from "../../lib/telegram/commands/help"; import * as socialConsensus from "../../lib/telegram/commands/socialConsensus"; import * as addEvidence from "../../lib/telegram/commands/addEvidence"; import * as leaveFed from "../../lib/telegram/commands/leavefed"; @@ -53,10 +54,12 @@ bot.on("my_chat_member", async function(myChatMember: any) { const settings = validate(myChatMember.chat); if(myChatMember.chat.type === "channel"){ - try{ - bot.sendMessage(myChatMember.chat.id, `The channel id is ${myChatMember.chat.id}`, {parse_mode: "HTML"}); - } catch(e) { - console.log(e) + if( myChatMember.new_chat_member.status === "administrator"){ + try{ + bot.sendMessage(myChatMember.chat.id, `The channel id is ${myChatMember.chat.id}`, {parse_mode: "HTML"}); + } catch(e) { + console.log('channel id msg error'+e); + } } return; } else if (myChatMember.chat.type === "supergroup") @@ -75,36 +78,33 @@ bot.on("my_chat_member", async function(myChatMember: any) { }); bot.on("new_chat_members", async function (chatMemberUpdated: TelegramBot.ChatMemberUpdated) { - if(!hasStarted(chatMemberUpdated.chat.id)||throttled(chatMemberUpdated.from.id) ) + if(!hasStarted(chatMemberUpdated.chat.id)||throttled(chatMemberUpdated.from.id)||chatMemberUpdated.chat.type !== "supergroup") return; const settings = validate(chatMemberUpdated.chat); - if (chatMemberUpdated.chat.type !== "supergroup") - return; if (settings.greeting_mode) - await greeting.callback(bot, settings, chatMemberUpdated); + greeting.callback(bot, settings, chatMemberUpdated); }); // Handle callback queries bot.on('callback_query', async function onCallbackQuery(callbackQuery: TelegramBot.CallbackQuery) { - if(!hasStarted(callbackQuery.message.chat.id)||throttled(callbackQuery.from.id)) + const calldata = callbackQuery.data.split('|'); + if (calldata.length < 2) + return + if((!hasStarted(callbackQuery.message.chat.id) && callbackQuery.message.chat.type == "supergroup")||throttled(callbackQuery.from.id)) return; const settings = validate(callbackQuery.message.chat); - const rawCalldata = callbackQuery.data; - const calldata = rawCalldata.split('|'); - try{ - if (Number(calldata[0]) === 0){ // set language - if (callbackQuery.from.id !== Number(calldata[1])) - return; - bot.deleteMessage(callbackQuery.message.chat.id, String(callbackQuery.message.message_id)) - setLanguage.setLanguageConfirm(db, bot, settings, callbackQuery.data, callbackQuery.message); - } else if (Number(calldata[0]) === 1){ // add evidence - if (callbackQuery.from.id !== Number(calldata[1])) - return; - // handle addevidence callback - } else - await socialConsensus.callback(db, settings, bot, callbackQuery, batchedSend); - } catch(e){ - console.log("Callback Query Error" + e); + if (Number(calldata[0]) === 0){ // set language + if (callbackQuery.from.id !== Number(calldata[1])) + return; + setLanguage.setLanguageConfirm(db, bot, settings, calldata[2], callbackQuery.message); + } else if (Number(calldata[0]) === 1){ // add evidence + if (callbackQuery.from.id !== Number(calldata[1])) + return; + // handle addevidence callback + } else if (Number(calldata[0]) === 2){ // report confirmations + socialConsensus.callback(db, settings, bot, callbackQuery, batchedSend); + } else if (Number(calldata[0]) === 3){ // report confirmations + help.respond(settings, bot, calldata[1], callbackQuery); } }); @@ -115,6 +115,7 @@ const commands: {regexp: RegExp, callback: any}[] = [ report, toggleWelcome, start, + help, leaveFed, joinFed, setChannel, @@ -129,10 +130,18 @@ commands.forEach((command) => { bot.onText( command.regexp, async (msg: any, match: string[]) => { - if(throttled(msg.from.id) || msg.chat.type !== "supergroup") + if(throttled(msg.from.id)) return const groupSettings = validate(msg.chat); - if (command === start){ + if(msg.chat.type === "private"){ + if (msg.text === '/start help'){ + help.callback(db, groupSettings, bot, botId, msg); + return + } else if (msg.text != '/start' && msg.text != '/help') + return + } else if(msg.chat.type !== "supergroup") + return + if (command === start || command === help){ if (hasStarted(msg.chat.id)){ try{ bot.sendMessage(msg.chat.id, "Susie is already moderating this community.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id} : {}) @@ -152,7 +161,7 @@ commands.forEach((command) => { console.log(e) } - if (adminOnlyCommands.indexOf(command)!==-1){ + if (msg.chat.type !== "private" && adminOnlyCommands.indexOf(command)!==-1){ var status = myCache.get("status"+msg.chat.id+msg.from.id) if (!status){ try{ @@ -171,8 +180,10 @@ commands.forEach((command) => { // todo success bool return val, to not always delete settings command.callback(db, groupSettings, bot, botId, msg, match,batchedSend); - if (command === setLanguage || command === setRulesCommand || command === setChannel || command === toggleWelcome || command === start) + if (command === setLanguage || command === setRulesCommand || command === setChannel || command === toggleWelcome) myCache.del(msg.chat.id) + if (command === start) + myCache.del("started"+msg.chat.id) } ) }) diff --git a/package.json b/package.json index 0ce3ee4..e0fec60 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,13 @@ "@graphprotocol/graph-ts": "^0.27.0", "@types/node-telegram-bot-api": "^0.57.1", "better-sqlite3": "^7.6.2", + "cache-manager": "^5.1.3", "dotenv": "^10.0.0", "ethers": "^5.5.2", "graphql": "^16.2.0", "graphql-request": "^3.7.0", "markdown-escape": "^1.1.0", + "node-cache": "^5.1.2", "node-fetch": "2", "node-telegram-bot-api": "^0.60.0", "pm2": "^5.2.0", From 4d86998009e0a3486db938275d9a1990205ddff0 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Mon, 5 Dec 2022 00:14:45 -0700 Subject: [PATCH 007/111] feat: big update --- lib/assets/contracts/Realitio_v2_0.json | 1 + .../Realitio_v2_0_ArbitratorWithAppeals.json | 20938 ++++++ lib/assets/contracts/Realitio_v2_1.json | 59728 ++++++++++++++++ .../Realitio_v2_1_ArbitratorWithAppeals.json | 16090 +++++ lib/create-db.ts | 48 +- lib/cron.ts | 295 +- lib/db.ts | 132 +- lib/realitioReporting.ts | 72 + lib/telegram/commands/addEvidence.ts | 118 +- lib/telegram/commands/getAccount.ts | 14 +- lib/telegram/commands/getChannel.ts | 7 +- lib/telegram/commands/getReports.ts | 65 +- lib/telegram/commands/getRules.ts | 4 +- lib/telegram/commands/greeting.ts | 21 +- lib/telegram/commands/help.ts | 139 +- lib/telegram/commands/report.ts | 30 +- lib/telegram/commands/setChannel.ts | 2 +- lib/telegram/commands/setInviteUrl.ts | 30 - lib/telegram/commands/socialConsensus.ts | 4 +- lib/telegram/commands/start.ts | 8 +- lib/telegram/index.ts | 58 +- lib/utils/ipfs-publish-estuary.ts | 32 + lib/utils/ipfs-publish.ts | 31 + subgraph/schema.graphql | 8 +- subgraph/src/KlerosLiquid.ts | 4 +- .../Realitio_v2_1_ArbitratorWithAppeals.ts | 20 +- subgraph/src/reality-ethv-30.ts | 150 +- types.d.ts | 10 + 28 files changed, 97675 insertions(+), 384 deletions(-) create mode 100644 lib/assets/contracts/Realitio_v2_0.json create mode 100644 lib/assets/contracts/Realitio_v2_0_ArbitratorWithAppeals.json create mode 100644 lib/assets/contracts/Realitio_v2_1.json create mode 100644 lib/assets/contracts/Realitio_v2_1_ArbitratorWithAppeals.json create mode 100644 lib/realitioReporting.ts delete mode 100644 lib/telegram/commands/setInviteUrl.ts create mode 100644 lib/utils/ipfs-publish-estuary.ts create mode 100644 lib/utils/ipfs-publish.ts diff --git a/lib/assets/contracts/Realitio_v2_0.json b/lib/assets/contracts/Realitio_v2_0.json new file mode 100644 index 0000000..c14279f --- /dev/null +++ b/lib/assets/contracts/Realitio_v2_0.json @@ -0,0 +1 @@ +{"abi":[{"constant":false,"inputs":[{"name":"question_id","type":"bytes32"},{"name":"history_hashes","type":"bytes32[]"},{"name":"addrs","type":"address[]"},{"name":"bonds","type":"uint256[]"},{"name":"answers","type":"bytes32[]"}],"name":"claimWinnings","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"question_id","type":"bytes32"},{"name":"content_hash","type":"bytes32"},{"name":"arbitrator","type":"address"},{"name":"min_timeout","type":"uint32"},{"name":"min_bond","type":"uint256"}],"name":"getFinalAnswerIfMatches","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"question_id","type":"bytes32"}],"name":"getBounty","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"question_id","type":"bytes32"}],"name":"getArbitrator","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"question_id","type":"bytes32"}],"name":"getBond","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"question_ids","type":"bytes32[]"},{"name":"lengths","type":"uint256[]"},{"name":"hist_hashes","type":"bytes32[]"},{"name":"addrs","type":"address[]"},{"name":"bonds","type":"uint256[]"},{"name":"answers","type":"bytes32[]"}],"name":"claimMultipleAndWithdrawBalance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"question_id","type":"bytes32"},{"name":"answer","type":"bytes32"},{"name":"nonce","type":"uint256"},{"name":"bond","type":"uint256"}],"name":"submitAnswerReveal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"fee","type":"uint256"}],"name":"setQuestionFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"template_hashes","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"question_id","type":"bytes32"}],"name":"getContentHash","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"question_claims","outputs":[{"name":"payee","type":"address"},{"name":"last_bond","type":"uint256"},{"name":"queued_funds","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"question_id","type":"bytes32"}],"name":"fundAnswerBounty","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"arbitrator_question_fees","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"template_id","type":"uint256"},{"name":"question","type":"string"},{"name":"arbitrator","type":"address"},{"name":"timeout","type":"uint32"},{"name":"opening_ts","type":"uint32"},{"name":"nonce","type":"uint256"}],"name":"askQuestion","outputs":[{"name":"","type":"bytes32"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"question_id","type":"bytes32"},{"name":"answer","type":"bytes32"},{"name":"max_previous","type":"uint256"}],"name":"submitAnswer","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"question_id","type":"bytes32"}],"name":"isFinalized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"question_id","type":"bytes32"}],"name":"getHistoryHash","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"commitments","outputs":[{"name":"reveal_ts","type":"uint32"},{"name":"is_revealed","type":"bool"},{"name":"revealed_answer","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"content","type":"string"}],"name":"createTemplate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"question_id","type":"bytes32"}],"name":"getBestAnswer","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"question_id","type":"bytes32"}],"name":"isPendingArbitration","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"questions","outputs":[{"name":"content_hash","type":"bytes32"},{"name":"arbitrator","type":"address"},{"name":"opening_ts","type":"uint32"},{"name":"timeout","type":"uint32"},{"name":"finalize_ts","type":"uint32"},{"name":"is_pending_arbitration","type":"bool"},{"name":"bounty","type":"uint256"},{"name":"best_answer","type":"bytes32"},{"name":"history_hash","type":"bytes32"},{"name":"bond","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"question_id","type":"bytes32"}],"name":"getOpeningTS","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"question_id","type":"bytes32"}],"name":"getTimeout","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"content","type":"string"},{"name":"question","type":"string"},{"name":"arbitrator","type":"address"},{"name":"timeout","type":"uint32"},{"name":"opening_ts","type":"uint32"},{"name":"nonce","type":"uint256"}],"name":"createTemplateAndAskQuestion","outputs":[{"name":"","type":"bytes32"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"question_id","type":"bytes32"}],"name":"getFinalAnswer","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"question_id","type":"bytes32"}],"name":"getFinalizeTS","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"templates","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"question_id","type":"bytes32"}],"name":"resultFor","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"question_id","type":"bytes32"},{"name":"answer_hash","type":"bytes32"},{"name":"max_previous","type":"uint256"},{"name":"_answerer","type":"address"}],"name":"submitAnswerCommitment","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"question_id","type":"bytes32"},{"name":"requester","type":"address"},{"name":"max_previous","type":"uint256"}],"name":"notifyOfArbitrationRequest","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"question_id","type":"bytes32"},{"name":"answer","type":"bytes32"},{"name":"answerer","type":"address"}],"name":"submitAnswerByArbitrator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"arbitrator","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"LogSetQuestionFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"template_id","type":"uint256"},{"indexed":true,"name":"user","type":"address"},{"indexed":false,"name":"question_text","type":"string"}],"name":"LogNewTemplate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"question_id","type":"bytes32"},{"indexed":true,"name":"user","type":"address"},{"indexed":false,"name":"template_id","type":"uint256"},{"indexed":false,"name":"question","type":"string"},{"indexed":true,"name":"content_hash","type":"bytes32"},{"indexed":false,"name":"arbitrator","type":"address"},{"indexed":false,"name":"timeout","type":"uint32"},{"indexed":false,"name":"opening_ts","type":"uint32"},{"indexed":false,"name":"nonce","type":"uint256"},{"indexed":false,"name":"created","type":"uint256"}],"name":"LogNewQuestion","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"question_id","type":"bytes32"},{"indexed":false,"name":"bounty_added","type":"uint256"},{"indexed":false,"name":"bounty","type":"uint256"},{"indexed":true,"name":"user","type":"address"}],"name":"LogFundAnswerBounty","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"answer","type":"bytes32"},{"indexed":true,"name":"question_id","type":"bytes32"},{"indexed":false,"name":"history_hash","type":"bytes32"},{"indexed":true,"name":"user","type":"address"},{"indexed":false,"name":"bond","type":"uint256"},{"indexed":false,"name":"ts","type":"uint256"},{"indexed":false,"name":"is_commitment","type":"bool"}],"name":"LogNewAnswer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"question_id","type":"bytes32"},{"indexed":true,"name":"user","type":"address"},{"indexed":true,"name":"answer_hash","type":"bytes32"},{"indexed":false,"name":"answer","type":"bytes32"},{"indexed":false,"name":"nonce","type":"uint256"},{"indexed":false,"name":"bond","type":"uint256"}],"name":"LogAnswerReveal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"question_id","type":"bytes32"},{"indexed":true,"name":"user","type":"address"}],"name":"LogNotifyOfArbitrationRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"question_id","type":"bytes32"},{"indexed":true,"name":"answer","type":"bytes32"}],"name":"LogFinalize","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"question_id","type":"bytes32"},{"indexed":true,"name":"user","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"LogClaim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"user","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"LogWithdraw","type":"event"}]} diff --git a/lib/assets/contracts/Realitio_v2_0_ArbitratorWithAppeals.json b/lib/assets/contracts/Realitio_v2_0_ArbitratorWithAppeals.json new file mode 100644 index 0000000..83ab55e --- /dev/null +++ b/lib/assets/contracts/Realitio_v2_0_ArbitratorWithAppeals.json @@ -0,0 +1,20938 @@ +{ + "contractName": "Realitio_v2_0_ArbitratorWithAppeals", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_realitio", + "type": "address" + }, + { + "internalType": "string", + "name": "_metadata", + "type": "string" + }, + { + "internalType": "contract IArbitrator", + "name": "_arbitrator", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_arbitratorExtraData", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_localDisputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_round", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ruling", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Contribution", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IArbitrator", + "name": "_arbitrator", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_metaEvidenceID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_evidenceGroupID", + "type": "uint256" + } + ], + "name": "Dispute", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "_questionID", + "type": "bytes32" + } + ], + "name": "DisputeIDToQuestionID", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IArbitrator", + "name": "_arbitrator", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_evidenceGroupID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_party", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "_evidence", + "type": "string" + } + ], + "name": "Evidence", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_metaEvidenceID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "_evidence", + "type": "string" + } + ], + "name": "MetaEvidence", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IArbitrator", + "name": "_arbitrator", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + } + ], + "name": "Ruling", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_localDisputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_round", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + } + ], + "name": "RulingFunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_localDisputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_round", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_reward", + "type": "uint256" + } + ], + "name": "Withdrawal", + "type": "event" + }, + { + "inputs": [], + "name": "MULTIPLIER_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VERSION", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "arbitrationRequests", + "outputs": [ + { + "internalType": "enum RealitioArbitratorWithAppealsBase.Status", + "name": "status", + "type": "uint8" + }, + { + "internalType": "address", + "name": "disputer", + "type": "address" + }, + { + "internalType": "uint256", + "name": "disputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "answer", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "arbitrator", + "outputs": [ + { + "internalType": "contract IArbitrator", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "arbitratorExtraData", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_governor", + "type": "address" + } + ], + "name": "changeGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_metaEvidence", + "type": "string" + } + ], + "name": "changeMetaEvidence", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_winnerStakeMultiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_loserStakeMultiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_loserAppealPeriodMultiplier", + "type": "uint256" + } + ], + "name": "changeMultipliers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "externalIDtoLocalID", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_questionID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + } + ], + "name": "fundAppeal", + "outputs": [ + { + "internalType": "bool", + "name": "fullyFunded", + "type": "bool" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "getDisputeFee", + "outputs": [ + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMultipliers", + "outputs": [ + { + "internalType": "uint256", + "name": "_winnerStakeMultiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_loserStakeMultiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_loserAppealPeriodMultiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_denominator", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_questionID", + "type": "uint256" + }, + { + "internalType": "address payable", + "name": "_contributor", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "_contributedTo", + "type": "uint256[]" + } + ], + "name": "getTotalWithdrawableAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "sum", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "loserAppealPeriodMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "loserStakeMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "metaEvidenceUpdates", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "metadata", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "numberOfRulingOptions", + "outputs": [ + { + "internalType": "uint256", + "name": "count", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "realitio", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_questionID", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_maxPrevious", + "type": "uint256" + } + ], + "name": "requestArbitration", + "outputs": [ + { + "internalType": "uint256", + "name": "disputeID", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + } + ], + "name": "rule", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_questionID", + "type": "uint256" + }, + { + "internalType": "string", + "name": "_evidenceURI", + "type": "string" + } + ], + "name": "submitEvidence", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "winnerStakeMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_questionID", + "type": "uint256" + }, + { + "internalType": "address payable", + "name": "_contributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_roundNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + } + ], + "name": "withdrawFeesAndRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_questionID", + "type": "uint256" + }, + { + "internalType": "address payable", + "name": "_contributor", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "_contributedTo", + "type": "uint256[]" + } + ], + "name": "withdrawFeesAndRewardsForAllRounds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_questionID", + "type": "uint256" + }, + { + "internalType": "address payable", + "name": "_contributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_roundNumber", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "_contributedTo", + "type": "uint256[]" + } + ], + "name": "withdrawFeesAndRewardsForMultipleRulings", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_questionID", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "_lastHistoryHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "_lastAnswerOrCommitmentID", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_lastBond", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_lastAnswerer", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isCommitment", + "type": "bool" + } + ], + "name": "computeWinnerAndReportAnswer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_realitio\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_metadata\",\"type\":\"string\"},{\"internalType\":\"contract IArbitrator\",\"name\":\"_arbitrator\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_arbitratorExtraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_localDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_round\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"ruling\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Contribution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IArbitrator\",\"name\":\"_arbitrator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_metaEvidenceID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_evidenceGroupID\",\"type\":\"uint256\"}],\"name\":\"Dispute\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_questionID\",\"type\":\"bytes32\"}],\"name\":\"DisputeIDToQuestionID\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IArbitrator\",\"name\":\"_arbitrator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_evidenceGroupID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_party\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_evidence\",\"type\":\"string\"}],\"name\":\"Evidence\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_metaEvidenceID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_evidence\",\"type\":\"string\"}],\"name\":\"MetaEvidence\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IArbitrator\",\"name\":\"_arbitrator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_ruling\",\"type\":\"uint256\"}],\"name\":\"Ruling\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_localDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_round\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_ruling\",\"type\":\"uint256\"}],\"name\":\"RulingFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_localDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_round\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_ruling\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_reward\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MULTIPLIER_DENOMINATOR\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"arbitrationRequests\",\"outputs\":[{\"internalType\":\"enum RealitioArbitratorWithAppealsBase.Status\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"disputer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"disputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"answer\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"arbitrator\",\"outputs\":[{\"internalType\":\"contract IArbitrator\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"arbitratorExtraData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"}],\"name\":\"changeGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_metaEvidence\",\"type\":\"string\"}],\"name\":\"changeMetaEvidence\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_winnerStakeMultiplier\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_loserStakeMultiplier\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_loserAppealPeriodMultiplier\",\"type\":\"uint256\"}],\"name\":\"changeMultipliers\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_questionID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_lastHistoryHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_lastAnswerOrCommitmentID\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_lastBond\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_lastAnswerer\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_isCommitment\",\"type\":\"bool\"}],\"name\":\"computeWinnerAndReportAnswer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"externalIDtoLocalID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_questionID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_ruling\",\"type\":\"uint256\"}],\"name\":\"fundAppeal\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"fullyFunded\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"getDisputeFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMultipliers\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_winnerStakeMultiplier\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_loserStakeMultiplier\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_loserAppealPeriodMultiplier\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_denominator\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_questionID\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"_contributor\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"_contributedTo\",\"type\":\"uint256[]\"}],\"name\":\"getTotalWithdrawableAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"sum\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"loserAppealPeriodMultiplier\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"loserStakeMultiplier\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"metaEvidenceUpdates\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"metadata\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"numberOfRulingOptions\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"realitio\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_questionID\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_maxPrevious\",\"type\":\"uint256\"}],\"name\":\"requestArbitration\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"disputeID\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_ruling\",\"type\":\"uint256\"}],\"name\":\"rule\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_questionID\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_evidenceURI\",\"type\":\"string\"}],\"name\":\"submitEvidence\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"winnerStakeMultiplier\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_questionID\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"_contributor\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_roundNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_ruling\",\"type\":\"uint256\"}],\"name\":\"withdrawFeesAndRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_questionID\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"_contributor\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"_contributedTo\",\"type\":\"uint256[]\"}],\"name\":\"withdrawFeesAndRewardsForAllRounds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_questionID\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"_contributor\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_roundNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_contributedTo\",\"type\":\"uint256[]\"}],\"name\":\"withdrawFeesAndRewardsForMultipleRulings\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"A Realitio arbitrator implementation that uses Realitio v2.0 and Kleros. It notifies Realitio contract for arbitration requests and creates corresponding dispute on Kleros. Transmits Kleros ruling to Realitio contract. Maintains crowdfunded appeals and notifies Kleros contract. Provides a function to submit evidence for Kleros dispute. There is a conversion between Kleros ruling and Realitio answer and there is a need for shifting by 1. This is because ruling 0 in Kleros signals tie or no-ruling but in Realitio 0 is a valid answer. For reviewers this should be a focus as it's quite easy to get confused. Any mistakes on this conversion will render this contract useless. NOTE: This contract trusts the Kleros arbitrator and Realitio.\",\"kind\":\"dev\",\"methods\":{\"changeGovernor(address)\":{\"params\":{\"_governor\":\"The address of the new governor.\"}},\"changeMetaEvidence(string)\":{\"details\":\"Updates the meta evidence used for disputes. This function needs to be executed at least once before requesting arbitration, because we don't emit MetaEvidence during construction.\",\"params\":{\"_metaEvidence\":\"URI to the new meta evidence file.\"}},\"changeMultipliers(uint256,uint256,uint256)\":{\"details\":\"Changes the proportion of appeal fees that must be paid by winner and loser and changes the appeal period portion for losers.\",\"params\":{\"_loserAppealPeriodMultiplier\":\"The new loser appeal period multiplier respect to DENOMINATOR.\",\"_loserStakeMultiplier\":\"The new loser stake multiplier value respect to DENOMINATOR.\",\"_winnerStakeMultiplier\":\"The new winner stake multiplier value respect to DENOMINATOR.\"}},\"computeWinnerAndReportAnswer(bytes32,bytes32,bytes32,uint256,address,bool)\":{\"details\":\"Compute winner and report the answer to a specified question from the ERC792 arbitrator to the Realitio v2.0 contract. TRUSTED.\",\"params\":{\"_isCommitment\":\"Whether the last answer to the question in the Realitio contract used commit or reveal or not. True if it did, false otherwise.\",\"_lastAnswerOrCommitmentID\":\"The last answer given, or its commitment ID if it was a commitment, to the question in the Realitio contract.\",\"_lastAnswerer\":\"The last answerer to the question in the Realitio contract.\",\"_lastBond\":\"The bond paid for the last answer to the question in the Realitio contract.\",\"_lastHistoryHash\":\"The history hash given with the last answer to the question in the Realitio contract.\",\"_questionID\":\"The ID of the question.\"}},\"constructor\":{\"details\":\"Constructor.\",\"params\":{\"_arbitrator\":\"The address of the ERC792 arbitrator.\",\"_arbitratorExtraData\":\"The extra data used to raise a dispute in the ERC792 arbitrator.\",\"_metadata\":\"The metadata required for RealitioArbitrator.\",\"_realitio\":\"The address of the Realitio contract.\"}},\"fundAppeal(uint256,uint256)\":{\"details\":\"TRUSTED. Manages crowdfunded appeals contributions and calls appeal function of the Kleros arbitrator to appeal a dispute. Note that we don\\u2019t need to check that msg.value is enough to pay arbitration fees as it\\u2019s the responsibility of the arbitrator contract.\",\"params\":{\"_questionID\":\"Identifier of the Realitio question, casted to uint. This also serves as the local identifier in this contract.\",\"_ruling\":\"The ruling option to which the caller wants to contribute to.\"},\"returns\":{\"fullyFunded\":\"True if the ruling option got fully funded as a result of this contribution.\"}},\"getDisputeFee(bytes32)\":{\"details\":\"Returns arbitration fee by calling arbitrationCost function in the arbitrator contract.\",\"returns\":{\"fee\":\"Arbitration that needs to be paid.\"}},\"getMultipliers()\":{\"details\":\"Calculate history has for givenReturns multipliers for appeals.\",\"returns\":{\"_denominator\":\"Multiplier denominator in basis points. Required for achieving floating-point-like behavior.\",\"_loserAppealPeriodMultiplier\":\"Losers appeal period multiplier. The loser is given less time to fund its appeal to defend against last minute appeal funding attacks.\",\"_loserStakeMultiplier\":\"Losers stake multiplier.\",\"_winnerStakeMultiplier\":\"Winners stake multiplier.\"}},\"getTotalWithdrawableAmount(uint256,address,uint256[])\":{\"details\":\"Returns the sum of withdrawable amount.\",\"params\":{\"_contributedTo\":\"Ruling options to look for potential withdrawals.\",\"_contributor\":\"The contributor for which to query.\",\"_questionID\":\"Identifier of the Realitio question, casted to uint. This also serves as the local identifier in this contract.\"},\"returns\":{\"sum\":\"The total amount available to withdraw.\"}},\"numberOfRulingOptions(uint256)\":{\"details\":\"Returns number of possible ruling options. Valid rulings are [0, count].\",\"returns\":{\"count\":\"The number of ruling options.\"}},\"requestArbitration(bytes32,uint256)\":{\"details\":\"Request arbitration from Kleros for given _questionID.\",\"params\":{\"_maxPrevious\":\"If specified, reverts if a bond higher than this was submitted after you sent your transaction.\",\"_questionID\":\"The question identifier in Realitio contract.\"},\"returns\":{\"disputeID\":\"ID of the resulting dispute on arbitrator.\"}},\"rule(uint256,uint256)\":{\"details\":\"Receives ruling from Kleros and enforces it.\",\"params\":{\"_disputeID\":\"ID of Kleros dispute.\",\"_ruling\":\"Ruling that is given by Kleros. This needs to be converted to Realitio answer before reporting the answer by shifting by 1.\"}},\"submitEvidence(uint256,string)\":{\"details\":\"Allows to submit evidence for a given dispute.\",\"params\":{\"_evidenceURI\":\"Link to evidence.\",\"_questionID\":\"Realitio question identifier.\"}},\"withdrawFeesAndRewards(uint256,address,uint256,uint256)\":{\"details\":\"Allows to withdraw any reimbursable fees or rewards after the dispute gets solved.\",\"params\":{\"_contributor\":\"The address whose rewards to withdraw.\",\"_questionID\":\"Identifier of the Realitio question, casted to uint. This also serves as the local identifier in this contract.\",\"_roundNumber\":\"The number of the round caller wants to withdraw from.\",\"_ruling\":\"Ruling that received contribution from contributor.\"},\"returns\":{\"amount\":\"The amount available to withdraw for given question, contributor, round number and ruling option.\"}},\"withdrawFeesAndRewardsForAllRounds(uint256,address,uint256[])\":{\"details\":\"Allows to withdraw any rewards or reimbursable fees after the dispute gets resolved. For multiple rulings options and for all rounds at once. This function has O(m*n) time complexity where m is number of rounds and n is the number of ruling options contributed by given user. It is safe to assume m is always less than 10 as appeal cost growth order is O(m^2).\",\"params\":{\"_contributedTo\":\"Rulings that received contributions from contributor.\",\"_contributor\":\"The address whose rewards to withdraw.\",\"_questionID\":\"Identifier of the Realitio question, casted to uint. This also serves as the local identifier in this contract.\"}},\"withdrawFeesAndRewardsForMultipleRulings(uint256,address,uint256,uint256[])\":{\"details\":\"Allows to withdraw any reimbursable fees or rewards after the dispute gets solved. For multiple ruling options at once. This function has O(n) time complexity where n is number of ruling options contributed by given user. It is safe to assume n is always less than 3 as it does not make sense to contribute to different ruling options in the same round, so it will rarely be greater than 1.\",\"params\":{\"_contributedTo\":\"Rulings that received contributions from contributor.\",\"_contributor\":\"The address whose rewards to withdraw.\",\"_questionID\":\"Identifier of the Realitio question, casted to uint. This also serves as the local identifier in this contract.\",\"_roundNumber\":\"The number of the round caller wants to withdraw from.\"}}},\"title\":\"Realitio_v2_0_ArbitratorWithAppeals\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"changeGovernor(address)\":{\"notice\":\"Changes the address of the governor.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"/home/f/repos/realitio-arbitrator-with-appeals/contracts/v2.0/Realitio_v2_0_ArbitratorWithAppeals.sol\":\"Realitio_v2_0_ArbitratorWithAppeals\"},\"evmVersion\":\"byzantium\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":20000},\"remappings\":[]},\"sources\":{\"/home/f/repos/realitio-arbitrator-with-appeals/contracts/IRealitioArbitrator.sol\":{\"keccak256\":\"0xa4c66788bf829c90495b4be7599db0895e92f6125eaf2ec174bdacd43b62efcc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://77f76fafc7edc6f27adb2caccc4479adf6c1b9f8552b27c6a0366f8a10aefc45\",\"dweb:/ipfs/Qmakhn3QDjAqowbvv5npamKZgsbXyjMqrMMz3o5XbjwT2c\"]},\"/home/f/repos/realitio-arbitrator-with-appeals/contracts/IRealitioBase.sol\":{\"keccak256\":\"0xb7542a31c27cacf12cc09d9f673c966351a6a86add13bf072cfa12df1088aee1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3649f211560577fb0d512ab0f310ff259833a3b7364b19bcf72edfa4349805a8\",\"dweb:/ipfs/QmfN5SuzviRSYzKYoF52mxCauAGXx6aLsgDjhEosrGgenN\"]},\"/home/f/repos/realitio-arbitrator-with-appeals/contracts/RealitioArbitratorWithAppealsBase.sol\":{\"keccak256\":\"0xecefcdad0288d210a815b68cf93cde0c9889e8331ca6c1ab7942cfb791b01b8e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c223f17b69dba6080d77bb051131184f109a45f90e2ef1bad1684143eb1eb6a1\",\"dweb:/ipfs/QmTSpJEBKHdoKz3VZTFxBCFqGEuZ9LfZqf2jcYv5Qdyqj1\"]},\"/home/f/repos/realitio-arbitrator-with-appeals/contracts/v2.0/IRealitio_v2_0.sol\":{\"keccak256\":\"0x089e153a74fefb1e9df091657367e6898a3682c976acf4dc73790fd59eea2386\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d49123c706b8d4e6b59d8cdf4985f0d66a1f32f1859186cda9aeb43da2d72181\",\"dweb:/ipfs/QmYzhnLyLDvJKrhiuxNUuQqFy4kyCEc2hYsc3VNGmmUB6u\"]},\"/home/f/repos/realitio-arbitrator-with-appeals/contracts/v2.0/Realitio_v2_0_ArbitratorWithAppeals.sol\":{\"keccak256\":\"0x7bb02077dfc79edd6c0682051c6c0c0a86723d059e15e112c5092a12cd267b41\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d570e043cccb4792c4b3671a845f969644c0f7821c4cc32015429131b0364f13\",\"dweb:/ipfs/QmUz19hKzwhy4LRLoi7g12aVbH7a8pj14N6VYqAnWKH25E\"]},\"@kleros/dispute-resolver-interface-contract/contracts/solc-0.7.x/IDisputeResolver.sol\":{\"keccak256\":\"0x90f7f1dfbda574ee567c7ec1c8a1542a9bc01d661f5bd7569548e301278d3be7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f65ca97d793bd8937580cd311d3dc166629ae6865c68d717169565f905c8a704\",\"dweb:/ipfs/QmUetVP9AuNbMi29UX4tgL7B9ZwKeLcUiYqWffwHizNACe\"]},\"@kleros/erc-792/contracts/IArbitrable.sol\":{\"keccak256\":\"0x1803a3433a78c509b20bd9477a2c60a71b2ce1ee7e17eb0ef0601618a8a72526\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a72a4b4b7048818eb14e698b7b493cb0e44456f91237b1a9a9251669b1de6484\",\"dweb:/ipfs/QmQLXrMT9S5uMe5WHFcf1G1s1GGZGCtNgXcQQGxwukQkXB\"]},\"@kleros/erc-792/contracts/IArbitrator.sol\":{\"keccak256\":\"0x240a4142f9ec379da0333dfc82409b7b058cff9ea118368eb5e8f15447996c1e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6a3a6d3631ce0ca5ef1266f1dc7cd6adb842c875fb6a45385a5adfad65f48c67\",\"dweb:/ipfs/QmZi9SpTkcVnUvwmwRdDin3KFALskAQCYWYAsh9AFzmi86\"]},\"@kleros/erc-792/contracts/erc-1497/IEvidence.sol\":{\"keccak256\":\"0x1ccedf5213730632540c748486637d7b1977ee73375818bf498a8276ca49dd13\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d58a60e8a3cdfe8515aa67a009cc139aab20d10fe0adc6058cc963b26c2e34a4\",\"dweb:/ipfs/QmUJY5dhS4KpXbLYhTBqMi33fNCUjFG19aLzxcDyeeBFkv\"]},\"@kleros/ethereum-libraries/contracts/CappedMath.sol\":{\"keccak256\":\"0x17dc8ae95582317df81532d06545576f0c509e462299ce71ddddd65ea506a5aa\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3a4f55c759e62bb02a4b9ff69c7e24844fdf9186730633d09af32ec70ebe64eb\",\"dweb:/ipfs/QmXcxEcHyk3ffHCAi7fwPu3Q1JEP5PpCricznM6TRkGoNw\"]}},\"version\":1}", + "bytecode": "0x60c060405260018054600160a060020a03191633179055610bb8600455611b586005556113886006553480156200003557600080fd5b5060405162002ffe38038062002ffe83398101604081905262000058916200020c565b6c01000000000000000000000000600160a060020a038516026080528251849084908490849062000091906002906020860190620000d2565b506c01000000000000000000000000600160a060020a0383160260a0528051620000c3906000906020840190620000d2565b505050505050505050620002e2565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200010a576000855562000155565b82601f106200012557805160ff191683800117855562000155565b8280016001018555821562000155579182015b828111156200015557825182559160200191906001019062000138565b506200016392915062000167565b5090565b5b8082111562000163576000815560010162000168565b60006001604060020a03808411156200019357fe5b6040516020601f8601601f1916820181018381118382101715620001b357fe5b8060405250819350858252868686011115620001ce57600080fd5b600092505b85831015620001f0578483015182840182015291820191620001d3565b85831115620002025760008187840101525b5050509392505050565b6000806000806080858703121562000222578384fd5b84516200022f81620002c9565b60208601519094506001604060020a03808211156200024c578485fd5b818701915087601f83011262000260578485fd5b62000271888351602085016200017e565b9450604087015191506200028582620002c9565b6060870151919350808211156200029a578283fd5b508501601f81018713620002ac578182fd5b620002bd878251602084016200017e565b91505092959194509250565b600160a060020a0381168114620002df57600080fd5b50565b6080516c01000000000000000000000000900460a0516c010000000000000000000000009004612c926200036c6000398061065d5280610b5b5280610e605280610f5b52806110cf52806111c5528061130c52806113d152806114825280611c305280611e025250806115e9528061168552806117f452806118f05280611ef35250612c926000f3fe6080604052600436106101d4576000357c0100000000000000000000000000000000000000000000000000000000900480637b94338311610109578063bc8802a2116100a7578063d35c82cb11610081578063d35c82cb146104b0578063e4c0aaf4146104d0578063fe6ca782146104f0578063ffa1ad7414610505576101d4565b8063bc8802a21461045b578063c21ae06114610470578063c25516e914610490576101d4565b806390765279116100e357806390765279146103e8578063a22352e214610408578063a6a7f0eb14610428578063a829c3d114610448576101d4565b80637b9433831461039357806385632b12146103a85780638d8b2d7e146103c8576101d4565b8063392f37e911610176578063631eabd511610150578063631eabd5146103145780636cc6cde1146103445780636cdc090f1461035957806379873f8a1461036e576101d4565b8063392f37e9146102bf5780634658eb01146102d45780634b2f0ea0146102f4576101d4565b80630e274e4c116101b25780630e274e4c146102485780631d5120851461026a578063311a6c561461027f578063362c34791461029f576101d4565b80630c139eb4146101d95780630c340a24146102045780630c7ac7b614610226575b600080fd5b3480156101e557600080fd5b506101ee61051a565b6040516101fb919061265e565b60405180910390f35b34801561021057600080fd5b50610219610520565b6040516101fb9190612632565b34801561023257600080fd5b5061023b61053c565b6040516101fb91906126bf565b34801561025457600080fd5b506102686102633660046122e6565b6105e8565b005b34801561027657600080fd5b506101ee610622565b34801561028b57600080fd5b5061026861029a366004612285565b610628565b3480156102ab57600080fd5b506101ee6102ba36600461239e565b61084f565b3480156102cb57600080fd5b5061023b61098e565b3480156102e057600080fd5b506102686102ef366004612447565b610a04565b610307610302366004612285565b610a63565b6040516101fb9190612653565b34801561032057600080fd5b5061033461032f3660046121f8565b610f18565b6040516101fb94939291906126e5565b34801561035057600080fd5b50610219610f59565b34801561036557600080fd5b506101ee610f7d565b34801561037a57600080fd5b50610383610f83565b6040516101fb9493929190612c02565b34801561039f57600080fd5b506101ee610f95565b3480156103b457600080fd5b506102686103c336600461233d565b610f9b565b3480156103d457600080fd5b506101ee6103e33660046121f8565b610fd0565b3480156103f457600080fd5b506102686104033660046122a6565b610ff5565b34801561041457600080fd5b506101ee6104233660046121f8565b61108f565b34801561043457600080fd5b506102686104433660046123da565b611154565b6101ee610456366004612285565b611239565b34801561046757600080fd5b50610219611683565b34801561047c57600080fd5b506101ee61048b3660046121f8565b6116a7565b34801561049c57600080fd5b506101ee6104ab3660046122e6565b6116b9565b3480156104bc57600080fd5b506102686104cb366004612228565b61176c565b3480156104dc57600080fd5b506102686104eb3660046121dc565b6119b8565b3480156104fc57600080fd5b506101ee611a50565b34801561051157600080fd5b5061023b611a56565b60065481565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815292918301828280156105e05780601f106105b5576101008083540402835291602001916105e0565b820191906000526020600020905b8154815290600101906020018083116105c357829003601f168201915b505050505081565b6000838152600760205260408120600381015490915b8181101561061a5761061286868387610f9b565b6001016105fe565b505050505050565b60055481565b60008281526008602090815260408083205480845260079092529091203373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b4906127cf565b60405180910390fd5b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe831115610717576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b4906128e6565b6001815460ff16600381111561072957fe5b14610760576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612ba4565b600381018054600091907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061079657fe5b90600052602060002090600502019050600081600401805490506001146107bd57846107d9565b816004016000815481106107cd57fe5b90600052602060002001545b600284810182905584547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016178455604051909150869033907f394027a5fa6e098a1191094d1719d6929b9abc535fcc0c8f448d6a4e756222769061083f90859061265e565b60405180910390a3505050505050565b60008481526007602052604081206003810180548391908690811061087057fe5b6000918252602090912060059091020190506001825460ff16600381111561089457fe5b116108cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b4906129c2565b6108db8187868560020154611a8f565b925082156109845773ffffffffffffffffffffffffffffffffffffffff8616600081815260028301602090815260408083208884529091528082208290555185156108fc0291869190818181858888f19350505050508573ffffffffffffffffffffffffffffffffffffffff1685887f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae878760405161097b929190612bf4565b60405180910390a45b5050949350505050565b600280546040805160206001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01909316849004601f810184900484028201840190925281815292918301828280156105e05780601f106105b5576101008083540402835291602001916105e0565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a55576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612954565b600492909255600555600655565b60007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe821115610abf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b49061298b565b600083815260076020526040902060018082015490825460ff166003811115610ae457fe5b14610b1b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b4906129f9565b6040517f1c3db16d00000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690631c3db16d90610b9090859060040161265e565b60206040518083038186803b158015610ba857600080fd5b505afa158015610bbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be09190612210565b9050610bed828683611c2b565b600080610bfb848885611da7565b6003870180549294509092507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201916000919083908110610c3957fe5b600091825260208083208c84526001600590930201918201905260409091205490915060ff1615610c96576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612a67565b6000898152602082905260408120543490610cb2908690611eba565b11610cd65760008a815260208390526040902054610cd1908590611eba565b610cd8565b345b90503373ffffffffffffffffffffffffffffffffffffffff16838c7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08d85604051610d24929190612bf4565b60405180910390a433600090815260028301602090815260408083208d8452825280832080548501905590849052902080548201908190558411610df55760008a81526020838152604080832054600386018054909101905560048501805460018181018355918552838520018e90558d845280860190925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909217909155518b9185918e917f39493c1b78d9a13bcc9e1d532fc7faed3889248d93affa811416ce3c6bcb1a6891a45b600482015460021415610ecd57600380890180546001018155600052820154610e1e9086611eba565b60038301556040517f49912f8800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906349912f88908790610e9a908b90600090600401612bdb565b6000604051808303818588803b158015610eb357600080fd5b505af1158015610ec7573d6000803e3d6000fd5b50505050505b336108fc610edb3484611eba565b6040518115909202916000818181858888f150505060008c81526001909401602052505060409091205460ff169750505050505050505b92915050565b60076020526000908152604090208054600182015460029092015460ff82169261010090920473ffffffffffffffffffffffffffffffffffffffff16919084565b7f000000000000000000000000000000000000000000000000000000000000000081565b60035481565b60045460055460065461271090919293565b60045481565b805160005b8181101561061a57610fc7868686868581518110610fba57fe5b602002602001015161084f565b50600101610fa0565b507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe90565b60015473ffffffffffffffffffffffffffffffffffffffff163314611046576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612954565b6003547f61606860eb6c87306811e2695215385101daab53bd6ab4e9f9049aead9363c7d838360405161107a929190612725565b60405180910390a25050600380546001019055565b6040517ff7434ea900000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063f7434ea9906111049084906004016126d2565b60206040518083038186803b15801561111c57600080fd5b505afa158015611130573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f129190612210565b60008381526007602052604090206002815460ff16600381111561117457fe5b106111ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612ac4565b3373ffffffffffffffffffffffffffffffffffffffff16847f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167fdccf2f8b2cc26eafcd61905cba744cff4b81d14740725f6376390dc6298a6a3c868660405161122b929190612725565b60405180910390a450505050565b60008060035411611276576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612a30565b600083815260076020526040812090815460ff16600381111561129557fe5b146112cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b4906128af565b6040517ff7434ea900000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063f7434ea9906113419084906004016126d2565b60206040518083038186803b15801561135957600080fd5b505afa15801561136d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113919190612210565b6040517fc13517e100000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063c13517e190839061142b907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe90600090600401612bdb565b6020604051808303818588803b15801561144457600080fd5b505af1158015611458573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061147d9190612210565b9250827f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f74baab670a4015ab2f1b467c5252a96141a2573f2908e58a92081e80d3cfde3d60016003540388600190046040516114f1929190612bf4565b60405180910390a3827fcbb827f06aed2dd1e157f8e6b29f32604bc4e88360964014c4d4ad259f8d3fa886604051611529919061265e565b60405180910390a2600083815260086020526040808220879055835460017fffffffffffffffffffffff0000000000000000000000000000000000000000ff909116336101008102919091177fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168217865581860187905560038601805490920182559252517ff6a94ecb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169163f6a94ecb916116209189918990600401612667565b600060405180830381600087803b15801561163a57600080fd5b505af115801561164e573d6000803e3d6000fd5b503392506108fc915061166390503484611eba565b6040518115909202916000818181858888f1935050505050505092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60086020526000908152604090205481565b60008381526007602052604081206002815460ff1660038111156116d957fe5b10156116e9576000915050611765565b6003810154600282015460005b8281101561176057600084600301828154811061170f57fe5b9060005260206000209060050201905060005b87518110156117565761174a828a8a848151811061173c57fe5b602002602001015187611a8f565b90960195600101611722565b50506001016116f6565b505050505b9392505050565b60008681526007602052604090206002815460ff16600381111561178c57fe5b146117c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b49061291d565b85858585856040516020016117dc9594939291906125c6565b604051602081830303815290604052805190602001207f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166382ffa9f7896040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401611867919061265e565b60206040518083038186803b15801561187f57600080fd5b505afa158015611893573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b79190612210565b146118ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612806565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663fe92049d886001846002015403600102611943858a8a8a8a611ed5565b6040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040161197d93929190612693565b600060405180830381600087803b15801561199757600080fd5b505af11580156119ab573d6000803e3d6000fd5b5050505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611a09576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612954565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b61271081565b6040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b600082815260018501602052604081205460ff16611ae0575073ffffffffffffffffffffffffffffffffffffffff831660009081526002850160209081526040808320858452909152902054611c23565b81831415611b5357600083815260208690526040902054611b02576000611b4c565b60008381526020868152604080832054600389015473ffffffffffffffffffffffffffffffffffffffff8916855260028a0184528285208886529093529220540281611b4a57fe5b045b9050611c23565b6004850154600111801590611b795750600082815260018601602052604090205460ff16155b15611c235784600001600086600401600181548110611b9457fe5b906000526020600020015481526020019081526020016000205485600001600087600401600081548110611bc457fe5b6000918252602080832090910154835282810193909352604091820181205460038a015473ffffffffffffffffffffffffffffffffffffffff8a16835260028b018552838320898452909452919020549201910281611c1f57fe5b0490505b949350505050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663afe15cfb866040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401611ca3919061265e565b604080518083038186803b158015611cba57600080fd5b505afa158015611cce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cf29190612424565b9150915083831415611d4857814210158015611d0d57508042105b611d43576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612772565b611da0565b814210158015611d6a57506127106006548383030281611d6457fe5b04820142105b611da0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612772565b5050505050565b600080600083851415611dbd5750600454611dc2565b506005545b6040517ff23f16e600000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063f23f16e690611e39908a908590600401612bdb565b60206040518083038186803b158015611e5157600080fd5b505afa158015611e65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e899190612210565b905080611eac612710611e9c838661208e565b81611ea357fe5b849190046120d6565b935093505050935093915050565b600082821115611ecc57506000610f12565b50808203610f12565b6000808085611ee657506000612028565b83156120215760008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663839df9458b6040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401611f66919061265e565b60606040518083038186803b158015611f7e57600080fd5b505afa158015611f92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb69190612472565b9250925092508115611fce5780945060019350612019565b4263ffffffff168363ffffffff161115612014576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612b21565b600093505b505050612028565b5085905060015b80801561205a575060028801547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0182145b612080578754610100900473ffffffffffffffffffffffffffffffffffffffff16612082565b845b98975050505050505050565b60008261209d57506000610f12565b828202828482816120aa57fe5b0414611765577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611c23565b600082820183811015611765577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611c23565b600082601f830112612119578081fd5b8135602067ffffffffffffffff8083111561213057fe5b8183026040518382820101818110848211171561214957fe5b60405284815283810192508684018288018501891015612167578687fd5b8692505b8583101561218957803584529284019260019290920191840161216b565b50979650505050505050565b60008083601f8401126121a6578182fd5b50813567ffffffffffffffff8111156121bd578182fd5b6020830191508360208285010111156121d557600080fd5b9250929050565b6000602082840312156121ed578081fd5b813561176581612c29565b600060208284031215612209578081fd5b5035919050565b600060208284031215612221578081fd5b5051919050565b60008060008060008060c08789031215612240578182fd5b86359550602087013594506040870135935060608701359250608087013561226781612c29565b915060a087013561227781612c4e565b809150509295509295509295565b60008060408385031215612297578182fd5b50508035926020909101359150565b600080602083850312156122b8578182fd5b823567ffffffffffffffff8111156122ce578283fd5b6122da85828601612195565b90969095509350505050565b6000806000606084860312156122fa578283fd5b83359250602084013561230c81612c29565b9150604084013567ffffffffffffffff811115612327578182fd5b61233386828701612109565b9150509250925092565b60008060008060808587031215612352578384fd5b84359350602085013561236481612c29565b925060408501359150606085013567ffffffffffffffff811115612386578182fd5b61239287828801612109565b91505092959194509250565b600080600080608085870312156123b3578384fd5b8435935060208501356123c581612c29565b93969395505050506040820135916060013590565b6000806000604084860312156123ee578081fd5b83359250602084013567ffffffffffffffff81111561240b578182fd5b61241786828701612195565b9497909650939450505050565b60008060408385031215612436578182fd5b505080516020909101519092909150565b60008060006060848603121561245b578081fd5b505081359360208301359350604090920135919050565b600080600060608486031215612486578081fd5b835163ffffffff81168114612499578182fd5b60208501519093506124aa81612c4e565b80925050604084015190509250925092565b60008151808452815b818110156124e1576020818501810151868301820152016124c5565b818111156124f25782602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60008154600180821660008114612543576001811461257f576125bd565b607f600284041686527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00831660208701526040860193506125bd565b6002830480875261258f86612c1d565b60005b828110156125b35781546020828b0101528482019150602081019050612592565b8801602001955050505b50505092915050565b9485526020850193909352604084019190915273ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002606083015215157f010000000000000000000000000000000000000000000000000000000000000002607482015260750190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b901515815260200190565b90815260200190565b92835273ffffffffffffffffffffffffffffffffffffffff919091166020830152604082015260600190565b928352602083019190915273ffffffffffffffffffffffffffffffffffffffff16604082015260600190565b60006020825261176560208301846124bc565b6000602082526117656020830184612525565b60808101600486106126f357fe5b94815273ffffffffffffffffffffffffffffffffffffffff939093166020840152604083019190915260609091015290565b60006020825282602083015282846040840137818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6020808252602e908201527f46756e64696e67206d757374206265206d6164652077697468696e207468652060408201527f61707065616c20706572696f642e000000000000000000000000000000000000606082015260800190565b60208082526017908201527f4f6e6c792061726269747261746f7220616c6c6f776564000000000000000000604082015260600190565b60208082526063908201527f5468652068617368206f662074686520686973746f727920706172616d65746560408201527f727320737570706c69656420646f6573206e6f74206d6174636820746865206f60608201527f6e652073746f72656420696e20746865205265616c6974696f20636f6e74726160808201527f63742e000000000000000000000000000000000000000000000000000000000060a082015260c00190565b6020808252601d908201527f4172626974726174696f6e20616c726561647920726571756573746564000000604082015260600190565b6020808252600e908201527f496e76616c69642072756c696e67000000000000000000000000000000000000604082015260600190565b6020808252601b908201527f546865207374617475732073686f756c642062652052756c65642e0000000000604082015260600190565b6020808252601f908201527f4f6e6c7920676f7665726e6f722063616e206578656375746520746869732e00604082015260600190565b60208082526017908201527f416e73776572206973206f7574206f6620626f756e6473000000000000000000604082015260600190565b60208082526017908201527f5468657265206973206e6f2072756c696e67207965742e000000000000000000604082015260600190565b60208082526015908201527f4e6f206469737075746520746f2061707065616c2e0000000000000000000000604082015260600190565b6020808252601d908201527f5468657265206973206e6f206d65746165766964656e6365207965742e000000604082015260600190565b60208082526021908201527f41707065616c206665652068617320616c7265616479206265656e207061696460408201527f2e00000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252602d908201527f43616e6e6f74207375626d69742065766964656e636520746f2061207265736f60408201527f6c76656420646973707574652e00000000000000000000000000000000000000606082015260800190565b60208082526059908201527f4172626974726174696f6e2063616e6e6f7420626520646f6e6520756e74696c60408201527f20746865206c61737420616e73776572657220686173206861642074696d652060608201527f746f2072657665616c2069747320636f6d6d69746d656e742e00000000000000608082015260a00190565b6020808252601a908201527f496e76616c6964206172626974726174696f6e20737461747573000000000000604082015260600190565b600083825260406020830152611c236040830184612525565b918252602082015260400190565b93845260208401929092526040830152606082015260800190565b60009081526020902090565b73ffffffffffffffffffffffffffffffffffffffff81168114612c4b57600080fd5b50565b8015158114612c4b57600080fdfea2646970667358221220220d236403aac69a52fca3d3ad14fedbd77a9983cf9144d0542dfc1083b5148c64736f6c63430007060033", + "deployedBytecode": "0x6080604052600436106101d4576000357c0100000000000000000000000000000000000000000000000000000000900480637b94338311610109578063bc8802a2116100a7578063d35c82cb11610081578063d35c82cb146104b0578063e4c0aaf4146104d0578063fe6ca782146104f0578063ffa1ad7414610505576101d4565b8063bc8802a21461045b578063c21ae06114610470578063c25516e914610490576101d4565b806390765279116100e357806390765279146103e8578063a22352e214610408578063a6a7f0eb14610428578063a829c3d114610448576101d4565b80637b9433831461039357806385632b12146103a85780638d8b2d7e146103c8576101d4565b8063392f37e911610176578063631eabd511610150578063631eabd5146103145780636cc6cde1146103445780636cdc090f1461035957806379873f8a1461036e576101d4565b8063392f37e9146102bf5780634658eb01146102d45780634b2f0ea0146102f4576101d4565b80630e274e4c116101b25780630e274e4c146102485780631d5120851461026a578063311a6c561461027f578063362c34791461029f576101d4565b80630c139eb4146101d95780630c340a24146102045780630c7ac7b614610226575b600080fd5b3480156101e557600080fd5b506101ee61051a565b6040516101fb919061265e565b60405180910390f35b34801561021057600080fd5b50610219610520565b6040516101fb9190612632565b34801561023257600080fd5b5061023b61053c565b6040516101fb91906126bf565b34801561025457600080fd5b506102686102633660046122e6565b6105e8565b005b34801561027657600080fd5b506101ee610622565b34801561028b57600080fd5b5061026861029a366004612285565b610628565b3480156102ab57600080fd5b506101ee6102ba36600461239e565b61084f565b3480156102cb57600080fd5b5061023b61098e565b3480156102e057600080fd5b506102686102ef366004612447565b610a04565b610307610302366004612285565b610a63565b6040516101fb9190612653565b34801561032057600080fd5b5061033461032f3660046121f8565b610f18565b6040516101fb94939291906126e5565b34801561035057600080fd5b50610219610f59565b34801561036557600080fd5b506101ee610f7d565b34801561037a57600080fd5b50610383610f83565b6040516101fb9493929190612c02565b34801561039f57600080fd5b506101ee610f95565b3480156103b457600080fd5b506102686103c336600461233d565b610f9b565b3480156103d457600080fd5b506101ee6103e33660046121f8565b610fd0565b3480156103f457600080fd5b506102686104033660046122a6565b610ff5565b34801561041457600080fd5b506101ee6104233660046121f8565b61108f565b34801561043457600080fd5b506102686104433660046123da565b611154565b6101ee610456366004612285565b611239565b34801561046757600080fd5b50610219611683565b34801561047c57600080fd5b506101ee61048b3660046121f8565b6116a7565b34801561049c57600080fd5b506101ee6104ab3660046122e6565b6116b9565b3480156104bc57600080fd5b506102686104cb366004612228565b61176c565b3480156104dc57600080fd5b506102686104eb3660046121dc565b6119b8565b3480156104fc57600080fd5b506101ee611a50565b34801561051157600080fd5b5061023b611a56565b60065481565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815292918301828280156105e05780601f106105b5576101008083540402835291602001916105e0565b820191906000526020600020905b8154815290600101906020018083116105c357829003601f168201915b505050505081565b6000838152600760205260408120600381015490915b8181101561061a5761061286868387610f9b565b6001016105fe565b505050505050565b60055481565b60008281526008602090815260408083205480845260079092529091203373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b4906127cf565b60405180910390fd5b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe831115610717576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b4906128e6565b6001815460ff16600381111561072957fe5b14610760576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612ba4565b600381018054600091907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061079657fe5b90600052602060002090600502019050600081600401805490506001146107bd57846107d9565b816004016000815481106107cd57fe5b90600052602060002001545b600284810182905584547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016178455604051909150869033907f394027a5fa6e098a1191094d1719d6929b9abc535fcc0c8f448d6a4e756222769061083f90859061265e565b60405180910390a3505050505050565b60008481526007602052604081206003810180548391908690811061087057fe5b6000918252602090912060059091020190506001825460ff16600381111561089457fe5b116108cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b4906129c2565b6108db8187868560020154611a8f565b925082156109845773ffffffffffffffffffffffffffffffffffffffff8616600081815260028301602090815260408083208884529091528082208290555185156108fc0291869190818181858888f19350505050508573ffffffffffffffffffffffffffffffffffffffff1685887f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae878760405161097b929190612bf4565b60405180910390a45b5050949350505050565b600280546040805160206001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01909316849004601f810184900484028201840190925281815292918301828280156105e05780601f106105b5576101008083540402835291602001916105e0565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a55576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612954565b600492909255600555600655565b60007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe821115610abf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b49061298b565b600083815260076020526040902060018082015490825460ff166003811115610ae457fe5b14610b1b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b4906129f9565b6040517f1c3db16d00000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690631c3db16d90610b9090859060040161265e565b60206040518083038186803b158015610ba857600080fd5b505afa158015610bbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be09190612210565b9050610bed828683611c2b565b600080610bfb848885611da7565b6003870180549294509092507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201916000919083908110610c3957fe5b600091825260208083208c84526001600590930201918201905260409091205490915060ff1615610c96576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612a67565b6000898152602082905260408120543490610cb2908690611eba565b11610cd65760008a815260208390526040902054610cd1908590611eba565b610cd8565b345b90503373ffffffffffffffffffffffffffffffffffffffff16838c7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08d85604051610d24929190612bf4565b60405180910390a433600090815260028301602090815260408083208d8452825280832080548501905590849052902080548201908190558411610df55760008a81526020838152604080832054600386018054909101905560048501805460018181018355918552838520018e90558d845280860190925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909217909155518b9185918e917f39493c1b78d9a13bcc9e1d532fc7faed3889248d93affa811416ce3c6bcb1a6891a45b600482015460021415610ecd57600380890180546001018155600052820154610e1e9086611eba565b60038301556040517f49912f8800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906349912f88908790610e9a908b90600090600401612bdb565b6000604051808303818588803b158015610eb357600080fd5b505af1158015610ec7573d6000803e3d6000fd5b50505050505b336108fc610edb3484611eba565b6040518115909202916000818181858888f150505060008c81526001909401602052505060409091205460ff169750505050505050505b92915050565b60076020526000908152604090208054600182015460029092015460ff82169261010090920473ffffffffffffffffffffffffffffffffffffffff16919084565b7f000000000000000000000000000000000000000000000000000000000000000081565b60035481565b60045460055460065461271090919293565b60045481565b805160005b8181101561061a57610fc7868686868581518110610fba57fe5b602002602001015161084f565b50600101610fa0565b507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe90565b60015473ffffffffffffffffffffffffffffffffffffffff163314611046576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612954565b6003547f61606860eb6c87306811e2695215385101daab53bd6ab4e9f9049aead9363c7d838360405161107a929190612725565b60405180910390a25050600380546001019055565b6040517ff7434ea900000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063f7434ea9906111049084906004016126d2565b60206040518083038186803b15801561111c57600080fd5b505afa158015611130573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f129190612210565b60008381526007602052604090206002815460ff16600381111561117457fe5b106111ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612ac4565b3373ffffffffffffffffffffffffffffffffffffffff16847f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167fdccf2f8b2cc26eafcd61905cba744cff4b81d14740725f6376390dc6298a6a3c868660405161122b929190612725565b60405180910390a450505050565b60008060035411611276576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612a30565b600083815260076020526040812090815460ff16600381111561129557fe5b146112cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b4906128af565b6040517ff7434ea900000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063f7434ea9906113419084906004016126d2565b60206040518083038186803b15801561135957600080fd5b505afa15801561136d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113919190612210565b6040517fc13517e100000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063c13517e190839061142b907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe90600090600401612bdb565b6020604051808303818588803b15801561144457600080fd5b505af1158015611458573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061147d9190612210565b9250827f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f74baab670a4015ab2f1b467c5252a96141a2573f2908e58a92081e80d3cfde3d60016003540388600190046040516114f1929190612bf4565b60405180910390a3827fcbb827f06aed2dd1e157f8e6b29f32604bc4e88360964014c4d4ad259f8d3fa886604051611529919061265e565b60405180910390a2600083815260086020526040808220879055835460017fffffffffffffffffffffff0000000000000000000000000000000000000000ff909116336101008102919091177fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168217865581860187905560038601805490920182559252517ff6a94ecb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169163f6a94ecb916116209189918990600401612667565b600060405180830381600087803b15801561163a57600080fd5b505af115801561164e573d6000803e3d6000fd5b503392506108fc915061166390503484611eba565b6040518115909202916000818181858888f1935050505050505092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60086020526000908152604090205481565b60008381526007602052604081206002815460ff1660038111156116d957fe5b10156116e9576000915050611765565b6003810154600282015460005b8281101561176057600084600301828154811061170f57fe5b9060005260206000209060050201905060005b87518110156117565761174a828a8a848151811061173c57fe5b602002602001015187611a8f565b90960195600101611722565b50506001016116f6565b505050505b9392505050565b60008681526007602052604090206002815460ff16600381111561178c57fe5b146117c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b49061291d565b85858585856040516020016117dc9594939291906125c6565b604051602081830303815290604052805190602001207f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166382ffa9f7896040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401611867919061265e565b60206040518083038186803b15801561187f57600080fd5b505afa158015611893573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b79190612210565b146118ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612806565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663fe92049d886001846002015403600102611943858a8a8a8a611ed5565b6040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040161197d93929190612693565b600060405180830381600087803b15801561199757600080fd5b505af11580156119ab573d6000803e3d6000fd5b5050505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611a09576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612954565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b61271081565b6040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b600082815260018501602052604081205460ff16611ae0575073ffffffffffffffffffffffffffffffffffffffff831660009081526002850160209081526040808320858452909152902054611c23565b81831415611b5357600083815260208690526040902054611b02576000611b4c565b60008381526020868152604080832054600389015473ffffffffffffffffffffffffffffffffffffffff8916855260028a0184528285208886529093529220540281611b4a57fe5b045b9050611c23565b6004850154600111801590611b795750600082815260018601602052604090205460ff16155b15611c235784600001600086600401600181548110611b9457fe5b906000526020600020015481526020019081526020016000205485600001600087600401600081548110611bc457fe5b6000918252602080832090910154835282810193909352604091820181205460038a015473ffffffffffffffffffffffffffffffffffffffff8a16835260028b018552838320898452909452919020549201910281611c1f57fe5b0490505b949350505050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663afe15cfb866040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401611ca3919061265e565b604080518083038186803b158015611cba57600080fd5b505afa158015611cce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cf29190612424565b9150915083831415611d4857814210158015611d0d57508042105b611d43576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612772565b611da0565b814210158015611d6a57506127106006548383030281611d6457fe5b04820142105b611da0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612772565b5050505050565b600080600083851415611dbd5750600454611dc2565b506005545b6040517ff23f16e600000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063f23f16e690611e39908a908590600401612bdb565b60206040518083038186803b158015611e5157600080fd5b505afa158015611e65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e899190612210565b905080611eac612710611e9c838661208e565b81611ea357fe5b849190046120d6565b935093505050935093915050565b600082821115611ecc57506000610f12565b50808203610f12565b6000808085611ee657506000612028565b83156120215760008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663839df9458b6040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401611f66919061265e565b60606040518083038186803b158015611f7e57600080fd5b505afa158015611f92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb69190612472565b9250925092508115611fce5780945060019350612019565b4263ffffffff168363ffffffff161115612014576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612b21565b600093505b505050612028565b5085905060015b80801561205a575060028801547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0182145b612080578754610100900473ffffffffffffffffffffffffffffffffffffffff16612082565b845b98975050505050505050565b60008261209d57506000610f12565b828202828482816120aa57fe5b0414611765577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611c23565b600082820183811015611765577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611c23565b600082601f830112612119578081fd5b8135602067ffffffffffffffff8083111561213057fe5b8183026040518382820101818110848211171561214957fe5b60405284815283810192508684018288018501891015612167578687fd5b8692505b8583101561218957803584529284019260019290920191840161216b565b50979650505050505050565b60008083601f8401126121a6578182fd5b50813567ffffffffffffffff8111156121bd578182fd5b6020830191508360208285010111156121d557600080fd5b9250929050565b6000602082840312156121ed578081fd5b813561176581612c29565b600060208284031215612209578081fd5b5035919050565b600060208284031215612221578081fd5b5051919050565b60008060008060008060c08789031215612240578182fd5b86359550602087013594506040870135935060608701359250608087013561226781612c29565b915060a087013561227781612c4e565b809150509295509295509295565b60008060408385031215612297578182fd5b50508035926020909101359150565b600080602083850312156122b8578182fd5b823567ffffffffffffffff8111156122ce578283fd5b6122da85828601612195565b90969095509350505050565b6000806000606084860312156122fa578283fd5b83359250602084013561230c81612c29565b9150604084013567ffffffffffffffff811115612327578182fd5b61233386828701612109565b9150509250925092565b60008060008060808587031215612352578384fd5b84359350602085013561236481612c29565b925060408501359150606085013567ffffffffffffffff811115612386578182fd5b61239287828801612109565b91505092959194509250565b600080600080608085870312156123b3578384fd5b8435935060208501356123c581612c29565b93969395505050506040820135916060013590565b6000806000604084860312156123ee578081fd5b83359250602084013567ffffffffffffffff81111561240b578182fd5b61241786828701612195565b9497909650939450505050565b60008060408385031215612436578182fd5b505080516020909101519092909150565b60008060006060848603121561245b578081fd5b505081359360208301359350604090920135919050565b600080600060608486031215612486578081fd5b835163ffffffff81168114612499578182fd5b60208501519093506124aa81612c4e565b80925050604084015190509250925092565b60008151808452815b818110156124e1576020818501810151868301820152016124c5565b818111156124f25782602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60008154600180821660008114612543576001811461257f576125bd565b607f600284041686527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00831660208701526040860193506125bd565b6002830480875261258f86612c1d565b60005b828110156125b35781546020828b0101528482019150602081019050612592565b8801602001955050505b50505092915050565b9485526020850193909352604084019190915273ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002606083015215157f010000000000000000000000000000000000000000000000000000000000000002607482015260750190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b901515815260200190565b90815260200190565b92835273ffffffffffffffffffffffffffffffffffffffff919091166020830152604082015260600190565b928352602083019190915273ffffffffffffffffffffffffffffffffffffffff16604082015260600190565b60006020825261176560208301846124bc565b6000602082526117656020830184612525565b60808101600486106126f357fe5b94815273ffffffffffffffffffffffffffffffffffffffff939093166020840152604083019190915260609091015290565b60006020825282602083015282846040840137818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6020808252602e908201527f46756e64696e67206d757374206265206d6164652077697468696e207468652060408201527f61707065616c20706572696f642e000000000000000000000000000000000000606082015260800190565b60208082526017908201527f4f6e6c792061726269747261746f7220616c6c6f776564000000000000000000604082015260600190565b60208082526063908201527f5468652068617368206f662074686520686973746f727920706172616d65746560408201527f727320737570706c69656420646f6573206e6f74206d6174636820746865206f60608201527f6e652073746f72656420696e20746865205265616c6974696f20636f6e74726160808201527f63742e000000000000000000000000000000000000000000000000000000000060a082015260c00190565b6020808252601d908201527f4172626974726174696f6e20616c726561647920726571756573746564000000604082015260600190565b6020808252600e908201527f496e76616c69642072756c696e67000000000000000000000000000000000000604082015260600190565b6020808252601b908201527f546865207374617475732073686f756c642062652052756c65642e0000000000604082015260600190565b6020808252601f908201527f4f6e6c7920676f7665726e6f722063616e206578656375746520746869732e00604082015260600190565b60208082526017908201527f416e73776572206973206f7574206f6620626f756e6473000000000000000000604082015260600190565b60208082526017908201527f5468657265206973206e6f2072756c696e67207965742e000000000000000000604082015260600190565b60208082526015908201527f4e6f206469737075746520746f2061707065616c2e0000000000000000000000604082015260600190565b6020808252601d908201527f5468657265206973206e6f206d65746165766964656e6365207965742e000000604082015260600190565b60208082526021908201527f41707065616c206665652068617320616c7265616479206265656e207061696460408201527f2e00000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252602d908201527f43616e6e6f74207375626d69742065766964656e636520746f2061207265736f60408201527f6c76656420646973707574652e00000000000000000000000000000000000000606082015260800190565b60208082526059908201527f4172626974726174696f6e2063616e6e6f7420626520646f6e6520756e74696c60408201527f20746865206c61737420616e73776572657220686173206861642074696d652060608201527f746f2072657665616c2069747320636f6d6d69746d656e742e00000000000000608082015260a00190565b6020808252601a908201527f496e76616c6964206172626974726174696f6e20737461747573000000000000604082015260600190565b600083825260406020830152611c236040830184612525565b918252602082015260400190565b93845260208401929092526040830152606082015260800190565b60009081526020902090565b73ffffffffffffffffffffffffffffffffffffffff81168114612c4b57600080fd5b50565b8015158114612c4b57600080fdfea2646970667358221220220d236403aac69a52fca3d3ad14fedbd77a9983cf9144d0542dfc1083b5148c64736f6c63430007060033", + "immutableReferences": { + "56": [ + { + "length": 32, + "start": 5609 + }, + { + "length": 32, + "start": 5765 + }, + { + "length": 32, + "start": 6132 + }, + { + "length": 32, + "start": 6384 + }, + { + "length": 32, + "start": 7923 + } + ], + "58": [ + { + "length": 32, + "start": 1629 + }, + { + "length": 32, + "start": 2907 + }, + { + "length": 32, + "start": 3680 + }, + { + "length": 32, + "start": 3931 + }, + { + "length": 32, + "start": 4303 + }, + { + "length": 32, + "start": 4549 + }, + { + "length": 32, + "start": 4876 + }, + { + "length": 32, + "start": 5073 + }, + { + "length": 32, + "start": 5250 + }, + { + "length": 32, + "start": 7216 + }, + { + "length": 32, + "start": 7682 + } + ] + }, + "generatedSources": [ + { + "ast": { + "nodeType": "YulBlock", + "src": "0:2071:10", + "statements": [ + { + "nodeType": "YulBlock", + "src": "6:3:10", + "statements": [] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "101:681:10", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "111:28:10", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "121:18:10", + "type": "", + "value": "0xffffffffffffffff" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "115:2:10", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "166:13:10", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "invalid", + "nodeType": "YulIdentifier", + "src": "168:7:10" + }, + "nodeType": "YulFunctionCall", + "src": "168:9:10" + }, + "nodeType": "YulExpressionStatement", + "src": "168:9:10" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "154:6:10" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "162:2:10" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "151:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "151:14:10" + }, + "nodeType": "YulIf", + "src": "148:2:10" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "188:23:10", + "value": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "208:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "202:5:10" + }, + "nodeType": "YulFunctionCall", + "src": "202:9:10" + }, + "variables": [ + { + "name": "memPtr", + "nodeType": "YulTypedName", + "src": "192:6:10", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "220:14:10", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "230:4:10", + "type": "", + "value": "0x20" + }, + "variables": [ + { + "name": "_2", + "nodeType": "YulTypedName", + "src": "224:2:10", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "243:71:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "269:6:10" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "285:6:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "293:4:10", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "281:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "281:17:10" + }, + { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "304:2:10", + "type": "", + "value": "31" + } + ], + "functionName": { + "name": "not", + "nodeType": "YulIdentifier", + "src": "300:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "300:7:10" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "277:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "277:31:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "265:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "265:44:10" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "311:2:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "261:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "261:53:10" + }, + "variables": [ + { + "name": "newFreePtr", + "nodeType": "YulTypedName", + "src": "247:10:10", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "373:13:10", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "invalid", + "nodeType": "YulIdentifier", + "src": "375:7:10" + }, + "nodeType": "YulFunctionCall", + "src": "375:9:10" + }, + "nodeType": "YulExpressionStatement", + "src": "375:9:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "332:10:10" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "344:2:10" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "329:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "329:18:10" + }, + { + "arguments": [ + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "352:10:10" + }, + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "364:6:10" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "349:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "349:22:10" + } + ], + "functionName": { + "name": "or", + "nodeType": "YulIdentifier", + "src": "326:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "326:46:10" + }, + "nodeType": "YulIf", + "src": "323:2:10" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "402:2:10", + "type": "", + "value": "64" + }, + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "406:10:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "395:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "395:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "395:22:10" + }, + { + "nodeType": "YulAssignment", + "src": "426:15:10", + "value": { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "435:6:10" + }, + "variableNames": [ + { + "name": "array", + "nodeType": "YulIdentifier", + "src": "426:5:10" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "457:6:10" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "465:6:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "450:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "450:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "450:22:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "510:16:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "519:1:10", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "522:1:10", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "512:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "512:12:10" + }, + "nodeType": "YulExpressionStatement", + "src": "512:12:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "src", + "nodeType": "YulIdentifier", + "src": "491:3:10" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "496:6:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "487:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "487:16:10" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "505:3:10" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "484:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "484:25:10" + }, + "nodeType": "YulIf", + "src": "481:2:10" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "535:10:10", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "544:1:10", + "type": "", + "value": "0" + }, + "variables": [ + { + "name": "i", + "nodeType": "YulTypedName", + "src": "539:1:10", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "604:75:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "633:6:10" + }, + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "641:1:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "629:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "629:14:10" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "645:2:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "625:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "625:23:10" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "src", + "nodeType": "YulIdentifier", + "src": "660:3:10" + }, + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "665:1:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "656:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "656:11:10" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "650:5:10" + }, + "nodeType": "YulFunctionCall", + "src": "650:18:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "618:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "618:51:10" + }, + "nodeType": "YulExpressionStatement", + "src": "618:51:10" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "565:1:10" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "568:6:10" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "562:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "562:13:10" + }, + "nodeType": "YulForLoop", + "post": { + "nodeType": "YulBlock", + "src": "576:19:10", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "578:15:10", + "value": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "587:1:10" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "590:2:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "583:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "583:10:10" + }, + "variableNames": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "578:1:10" + } + ] + } + ] + }, + "pre": { + "nodeType": "YulBlock", + "src": "558:3:10", + "statements": [] + }, + "src": "554:125:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "713:63:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "742:6:10" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "750:6:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "738:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "738:19:10" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "759:2:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "734:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "734:28:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "764:1:10", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "727:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "727:39:10" + }, + "nodeType": "YulExpressionStatement", + "src": "727:39:10" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "694:1:10" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "697:6:10" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "691:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "691:13:10" + }, + "nodeType": "YulIf", + "src": "688:2:10" + } + ] + }, + "name": "abi_decode_available_length_t_bytes_fromMemory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "src", + "nodeType": "YulTypedName", + "src": "70:3:10", + "type": "" + }, + { + "name": "length", + "nodeType": "YulTypedName", + "src": "75:6:10", + "type": "" + }, + { + "name": "end", + "nodeType": "YulTypedName", + "src": "83:3:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "array", + "nodeType": "YulTypedName", + "src": "91:5:10", + "type": "" + } + ], + "src": "14:768:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "958:973:10", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "1005:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1014:6:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1022:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1007:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "1007:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "1007:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "979:7:10" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "988:9:10" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "975:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "975:23:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1000:3:10", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "971:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "971:33:10" + }, + "nodeType": "YulIf", + "src": "968:2:10" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1040:29:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1059:9:10" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "1053:5:10" + }, + "nodeType": "YulFunctionCall", + "src": "1053:16:10" + }, + "variables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "1044:5:10", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "1105:5:10" + } + ], + "functionName": { + "name": "validator_revert_t_address", + "nodeType": "YulIdentifier", + "src": "1078:26:10" + }, + "nodeType": "YulFunctionCall", + "src": "1078:33:10" + }, + "nodeType": "YulExpressionStatement", + "src": "1078:33:10" + }, + { + "nodeType": "YulAssignment", + "src": "1120:15:10", + "value": { + "name": "value", + "nodeType": "YulIdentifier", + "src": "1130:5:10" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1120:6:10" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1144:39:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1168:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1179:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1164:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "1164:18:10" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "1158:5:10" + }, + "nodeType": "YulFunctionCall", + "src": "1158:25:10" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "1148:6:10", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1192:28:10", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1202:18:10", + "type": "", + "value": "0xffffffffffffffff" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "1196:2:10", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1247:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "1256:6:10" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "1264:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1249:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "1249:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "1249:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "1235:6:10" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "1243:2:10" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "1232:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "1232:14:10" + }, + "nodeType": "YulIf", + "src": "1229:2:10" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1282:32:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1296:9:10" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "1307:6:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1292:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "1292:22:10" + }, + "variables": [ + { + "name": "_2", + "nodeType": "YulTypedName", + "src": "1286:2:10", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1362:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "1371:6:10" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "1379:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1364:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "1364:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "1364:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "1341:2:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1345:4:10", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1337:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "1337:13:10" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "1352:7:10" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "1333:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "1333:27:10" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "1326:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "1326:35:10" + }, + "nodeType": "YulIf", + "src": "1323:2:10" + }, + { + "nodeType": "YulAssignment", + "src": "1397:89:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "1458:2:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1462:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1454:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "1454:11:10" + }, + { + "arguments": [ + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "1473:2:10" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "1467:5:10" + }, + "nodeType": "YulFunctionCall", + "src": "1467:9:10" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "1478:7:10" + } + ], + "functionName": { + "name": "abi_decode_available_length_t_bytes_fromMemory", + "nodeType": "YulIdentifier", + "src": "1407:46:10" + }, + "nodeType": "YulFunctionCall", + "src": "1407:79:10" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "1397:6:10" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1495:40:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1520:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1531:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1516:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "1516:18:10" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "1510:5:10" + }, + "nodeType": "YulFunctionCall", + "src": "1510:25:10" + }, + "variables": [ + { + "name": "value_1", + "nodeType": "YulTypedName", + "src": "1499:7:10", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "1571:7:10" + } + ], + "functionName": { + "name": "validator_revert_t_address", + "nodeType": "YulIdentifier", + "src": "1544:26:10" + }, + "nodeType": "YulFunctionCall", + "src": "1544:35:10" + }, + "nodeType": "YulExpressionStatement", + "src": "1544:35:10" + }, + { + "nodeType": "YulAssignment", + "src": "1588:17:10", + "value": { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "1598:7:10" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "1588:6:10" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1614:41:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1640:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1651:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1636:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "1636:18:10" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "1630:5:10" + }, + "nodeType": "YulFunctionCall", + "src": "1630:25:10" + }, + "variables": [ + { + "name": "offset_1", + "nodeType": "YulTypedName", + "src": "1618:8:10", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1684:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "1693:6:10" + }, + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "1701:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1686:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "1686:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "1686:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset_1", + "nodeType": "YulIdentifier", + "src": "1670:8:10" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "1680:2:10" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "1667:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "1667:16:10" + }, + "nodeType": "YulIf", + "src": "1664:2:10" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1719:34:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1733:9:10" + }, + { + "name": "offset_1", + "nodeType": "YulIdentifier", + "src": "1744:8:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1729:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "1729:24:10" + }, + "variables": [ + { + "name": "_3", + "nodeType": "YulTypedName", + "src": "1723:2:10", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1801:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "1810:6:10" + }, + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "1818:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1803:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "1803:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "1803:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "1780:2:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1784:4:10", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1776:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "1776:13:10" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "1791:7:10" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "1772:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "1772:27:10" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "1765:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "1765:35:10" + }, + "nodeType": "YulIf", + "src": "1762:2:10" + }, + { + "nodeType": "YulAssignment", + "src": "1836:89:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "1897:2:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1901:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1893:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "1893:11:10" + }, + { + "arguments": [ + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "1912:2:10" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "1906:5:10" + }, + "nodeType": "YulFunctionCall", + "src": "1906:9:10" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "1917:7:10" + } + ], + "functionName": { + "name": "abi_decode_available_length_t_bytes_fromMemory", + "nodeType": "YulIdentifier", + "src": "1846:46:10" + }, + "nodeType": "YulFunctionCall", + "src": "1846:79:10" + }, + "variableNames": [ + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "1836:6:10" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_addresst_string_memory_ptrt_contract$_IArbitrator_$1736t_bytes_memory_ptr_fromMemory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "900:9:10", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "911:7:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "923:6:10", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "931:6:10", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "939:6:10", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "947:6:10", + "type": "" + } + ], + "src": "787:1144:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1983:86:10", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "2047:16:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2056:1:10", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2059:1:10", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "2049:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "2049:12:10" + }, + "nodeType": "YulExpressionStatement", + "src": "2049:12:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "2006:5:10" + }, + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "2017:5:10" + }, + { + "arguments": [ + { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2032:1:10", + "type": "", + "value": "2" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2035:3:10", + "type": "", + "value": "160" + } + ], + "functionName": { + "name": "exp", + "nodeType": "YulIdentifier", + "src": "2028:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "2028:11:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2041:1:10", + "type": "", + "value": "1" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "2024:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "2024:19:10" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "2013:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "2013:31:10" + } + ], + "functionName": { + "name": "eq", + "nodeType": "YulIdentifier", + "src": "2003:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "2003:42:10" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "1996:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "1996:50:10" + }, + "nodeType": "YulIf", + "src": "1993:2:10" + } + ] + }, + "name": "validator_revert_t_address", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "1972:5:10", + "type": "" + } + ], + "src": "1936:133:10" + } + ] + }, + "contents": "{\n { }\n function abi_decode_available_length_t_bytes_fromMemory(src, length, end) -> array\n {\n let _1 := 0xffffffffffffffff\n if gt(length, _1) { invalid() }\n let memPtr := mload(64)\n let _2 := 0x20\n let newFreePtr := add(add(memPtr, and(add(length, 0x1f), not(31))), _2)\n if or(gt(newFreePtr, _1), lt(newFreePtr, memPtr)) { invalid() }\n mstore(64, newFreePtr)\n array := memPtr\n mstore(memPtr, length)\n if gt(add(src, length), end) { revert(0, 0) }\n let i := 0\n for { } lt(i, length) { i := add(i, _2) }\n {\n mstore(add(add(memPtr, i), _2), mload(add(src, i)))\n }\n if gt(i, length)\n {\n mstore(add(add(memPtr, length), _2), 0)\n }\n }\n function abi_decode_tuple_t_addresst_string_memory_ptrt_contract$_IArbitrator_$1736t_bytes_memory_ptr_fromMemory(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 128) { revert(value0, value0) }\n let value := mload(headStart)\n validator_revert_t_address(value)\n value0 := value\n let offset := mload(add(headStart, 32))\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(value1, value1) }\n let _2 := add(headStart, offset)\n if iszero(slt(add(_2, 0x1f), dataEnd)) { revert(value1, value1) }\n value1 := abi_decode_available_length_t_bytes_fromMemory(add(_2, 32), mload(_2), dataEnd)\n let value_1 := mload(add(headStart, 64))\n validator_revert_t_address(value_1)\n value2 := value_1\n let offset_1 := mload(add(headStart, 96))\n if gt(offset_1, _1) { revert(value3, value3) }\n let _3 := add(headStart, offset_1)\n if iszero(slt(add(_3, 0x1f), dataEnd)) { revert(value3, value3) }\n value3 := abi_decode_available_length_t_bytes_fromMemory(add(_3, 32), mload(_3), dataEnd)\n }\n function validator_revert_t_address(value)\n {\n if iszero(eq(value, and(value, sub(exp(2, 160), 1)))) { revert(0, 0) }\n }\n}", + "id": 10, + "language": "Yul", + "name": "#utility.yul" + } + ], + "deployedGeneratedSources": [ + { + "ast": { + "nodeType": "YulBlock", + "src": "0:19906:10", + "statements": [ + { + "nodeType": "YulBlock", + "src": "6:3:10", + "statements": [] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "84:838:10", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "133:24:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "array", + "nodeType": "YulIdentifier", + "src": "142:5:10" + }, + { + "name": "array", + "nodeType": "YulIdentifier", + "src": "149:5:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "135:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "135:20:10" + }, + "nodeType": "YulExpressionStatement", + "src": "135:20:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "112:6:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "120:4:10", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "108:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "108:17:10" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "127:3:10" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "104:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "104:27:10" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "97:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "97:35:10" + }, + "nodeType": "YulIf", + "src": "94:2:10" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "166:30:10", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "189:6:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "176:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "176:20:10" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "170:2:10", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "205:14:10", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "215:4:10", + "type": "", + "value": "0x20" + }, + "variables": [ + { + "name": "_2", + "nodeType": "YulTypedName", + "src": "209:2:10", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "228:28:10", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "238:18:10", + "type": "", + "value": "0xffffffffffffffff" + }, + "variables": [ + { + "name": "_3", + "nodeType": "YulTypedName", + "src": "232:2:10", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "279:13:10", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "invalid", + "nodeType": "YulIdentifier", + "src": "281:7:10" + }, + "nodeType": "YulFunctionCall", + "src": "281:9:10" + }, + "nodeType": "YulExpressionStatement", + "src": "281:9:10" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "271:2:10" + }, + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "275:2:10" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "268:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "268:10:10" + }, + "nodeType": "YulIf", + "src": "265:2:10" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "301:21:10", + "value": { + "arguments": [ + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "315:2:10" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "319:2:10" + } + ], + "functionName": { + "name": "mul", + "nodeType": "YulIdentifier", + "src": "311:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "311:11:10" + }, + "variables": [ + { + "name": "_4", + "nodeType": "YulTypedName", + "src": "305:2:10", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "331:23:10", + "value": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "351:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "345:5:10" + }, + "nodeType": "YulFunctionCall", + "src": "345:9:10" + }, + "variables": [ + { + "name": "memPtr", + "nodeType": "YulTypedName", + "src": "335:6:10", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "363:42:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "389:6:10" + }, + { + "name": "_4", + "nodeType": "YulIdentifier", + "src": "397:2:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "385:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "385:15:10" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "402:2:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "381:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "381:24:10" + }, + "variables": [ + { + "name": "newFreePtr", + "nodeType": "YulTypedName", + "src": "367:10:10", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "464:13:10", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "invalid", + "nodeType": "YulIdentifier", + "src": "466:7:10" + }, + "nodeType": "YulFunctionCall", + "src": "466:9:10" + }, + "nodeType": "YulExpressionStatement", + "src": "466:9:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "423:10:10" + }, + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "435:2:10" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "420:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "420:18:10" + }, + { + "arguments": [ + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "443:10:10" + }, + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "455:6:10" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "440:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "440:22:10" + } + ], + "functionName": { + "name": "or", + "nodeType": "YulIdentifier", + "src": "417:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "417:46:10" + }, + "nodeType": "YulIf", + "src": "414:2:10" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "493:2:10", + "type": "", + "value": "64" + }, + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "497:10:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "486:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "486:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "486:22:10" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "517:17:10", + "value": { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "528:6:10" + }, + "variables": [ + { + "name": "dst", + "nodeType": "YulTypedName", + "src": "521:3:10", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "550:6:10" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "558:2:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "543:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "543:18:10" + }, + "nodeType": "YulExpressionStatement", + "src": "543:18:10" + }, + { + "nodeType": "YulAssignment", + "src": "570:22:10", + "value": { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "581:6:10" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "589:2:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "577:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "577:15:10" + }, + "variableNames": [ + { + "name": "dst", + "nodeType": "YulIdentifier", + "src": "570:3:10" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "601:26:10", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "616:6:10" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "624:2:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "612:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "612:15:10" + }, + "variables": [ + { + "name": "src", + "nodeType": "YulTypedName", + "src": "605:3:10", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "673:24:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "array", + "nodeType": "YulIdentifier", + "src": "682:5:10" + }, + { + "name": "array", + "nodeType": "YulIdentifier", + "src": "689:5:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "675:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "675:20:10" + }, + "nodeType": "YulExpressionStatement", + "src": "675:20:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "650:6:10" + }, + { + "name": "_4", + "nodeType": "YulIdentifier", + "src": "658:2:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "646:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "646:15:10" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "663:2:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "642:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "642:24:10" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "668:3:10" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "639:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "639:33:10" + }, + "nodeType": "YulIf", + "src": "636:2:10" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "706:14:10", + "value": { + "name": "array", + "nodeType": "YulIdentifier", + "src": "715:5:10" + }, + "variables": [ + { + "name": "i", + "nodeType": "YulTypedName", + "src": "710:1:10", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "774:118:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "dst", + "nodeType": "YulIdentifier", + "src": "795:3:10" + }, + { + "arguments": [ + { + "name": "src", + "nodeType": "YulIdentifier", + "src": "813:3:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "800:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "800:17:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "788:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "788:30:10" + }, + "nodeType": "YulExpressionStatement", + "src": "788:30:10" + }, + { + "nodeType": "YulAssignment", + "src": "831:19:10", + "value": { + "arguments": [ + { + "name": "dst", + "nodeType": "YulIdentifier", + "src": "842:3:10" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "847:2:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "838:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "838:12:10" + }, + "variableNames": [ + { + "name": "dst", + "nodeType": "YulIdentifier", + "src": "831:3:10" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "863:19:10", + "value": { + "arguments": [ + { + "name": "src", + "nodeType": "YulIdentifier", + "src": "874:3:10" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "879:2:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "870:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "870:12:10" + }, + "variableNames": [ + { + "name": "src", + "nodeType": "YulIdentifier", + "src": "863:3:10" + } + ] + } + ] + }, + "condition": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "740:1:10" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "743:2:10" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "737:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "737:9:10" + }, + "nodeType": "YulForLoop", + "post": { + "nodeType": "YulBlock", + "src": "747:18:10", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "749:14:10", + "value": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "758:1:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "761:1:10", + "type": "", + "value": "1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "754:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "754:9:10" + }, + "variableNames": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "749:1:10" + } + ] + } + ] + }, + "pre": { + "nodeType": "YulBlock", + "src": "733:3:10", + "statements": [] + }, + "src": "729:163:10" + }, + { + "nodeType": "YulAssignment", + "src": "901:15:10", + "value": { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "910:6:10" + }, + "variableNames": [ + { + "name": "array", + "nodeType": "YulIdentifier", + "src": "901:5:10" + } + ] + } + ] + }, + "name": "abi_decode_t_array$_t_uint256_$dyn", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "58:6:10", + "type": "" + }, + { + "name": "end", + "nodeType": "YulTypedName", + "src": "66:3:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "array", + "nodeType": "YulTypedName", + "src": "74:5:10", + "type": "" + } + ], + "src": "14:908:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1002:303:10", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "1051:30:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "arrayPos", + "nodeType": "YulIdentifier", + "src": "1060:8:10" + }, + { + "name": "arrayPos", + "nodeType": "YulIdentifier", + "src": "1070:8:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1053:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "1053:26:10" + }, + "nodeType": "YulExpressionStatement", + "src": "1053:26:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "1030:6:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1038:4:10", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1026:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "1026:17:10" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "1045:3:10" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "1022:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "1022:27:10" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "1015:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "1015:35:10" + }, + "nodeType": "YulIf", + "src": "1012:2:10" + }, + { + "nodeType": "YulAssignment", + "src": "1090:30:10", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "1113:6:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "1100:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "1100:20:10" + }, + "variableNames": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "1090:6:10" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1163:30:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "arrayPos", + "nodeType": "YulIdentifier", + "src": "1172:8:10" + }, + { + "name": "arrayPos", + "nodeType": "YulIdentifier", + "src": "1182:8:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1165:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "1165:26:10" + }, + "nodeType": "YulExpressionStatement", + "src": "1165:26:10" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "1135:6:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1143:18:10", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "1132:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "1132:30:10" + }, + "nodeType": "YulIf", + "src": "1129:2:10" + }, + { + "nodeType": "YulAssignment", + "src": "1202:29:10", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "1218:6:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1226:4:10", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1214:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "1214:17:10" + }, + "variableNames": [ + { + "name": "arrayPos", + "nodeType": "YulIdentifier", + "src": "1202:8:10" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1283:16:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1292:1:10", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1295:1:10", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1285:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "1285:12:10" + }, + "nodeType": "YulExpressionStatement", + "src": "1285:12:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "1254:6:10" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "1262:6:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1250:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "1250:19:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1271:4:10", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1246:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "1246:30:10" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "1278:3:10" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "1243:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "1243:39:10" + }, + "nodeType": "YulIf", + "src": "1240:2:10" + } + ] + }, + "name": "abi_decode_t_string_calldata", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "965:6:10", + "type": "" + }, + { + "name": "end", + "nodeType": "YulTypedName", + "src": "973:3:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "arrayPos", + "nodeType": "YulTypedName", + "src": "981:8:10", + "type": "" + }, + { + "name": "length", + "nodeType": "YulTypedName", + "src": "991:6:10", + "type": "" + } + ], + "src": "927:378:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1380:189:10", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "1426:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1435:6:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1443:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1428:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "1428:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "1428:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "1401:7:10" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1410:9:10" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "1397:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "1397:23:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1422:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "1393:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "1393:32:10" + }, + "nodeType": "YulIf", + "src": "1390:2:10" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1461:36:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1487:9:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "1474:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "1474:23:10" + }, + "variables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "1465:5:10", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "1533:5:10" + } + ], + "functionName": { + "name": "validator_revert_t_address", + "nodeType": "YulIdentifier", + "src": "1506:26:10" + }, + "nodeType": "YulFunctionCall", + "src": "1506:33:10" + }, + "nodeType": "YulExpressionStatement", + "src": "1506:33:10" + }, + { + "nodeType": "YulAssignment", + "src": "1548:15:10", + "value": { + "name": "value", + "nodeType": "YulIdentifier", + "src": "1558:5:10" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1548:6:10" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_address", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "1346:9:10", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "1357:7:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "1369:6:10", + "type": "" + } + ], + "src": "1310:259:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1644:120:10", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "1690:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1699:6:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1707:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1692:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "1692:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "1692:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "1665:7:10" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1674:9:10" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "1661:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "1661:23:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1686:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "1657:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "1657:32:10" + }, + "nodeType": "YulIf", + "src": "1654:2:10" + }, + { + "nodeType": "YulAssignment", + "src": "1725:33:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1748:9:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "1735:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "1735:23:10" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1725:6:10" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes32", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "1610:9:10", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "1621:7:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "1633:6:10", + "type": "" + } + ], + "src": "1574:190:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1850:113:10", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "1896:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1905:6:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1913:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1898:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "1898:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "1898:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "1871:7:10" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1880:9:10" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "1867:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "1867:23:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1892:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "1863:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "1863:32:10" + }, + "nodeType": "YulIf", + "src": "1860:2:10" + }, + { + "nodeType": "YulAssignment", + "src": "1931:26:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1947:9:10" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "1941:5:10" + }, + "nodeType": "YulFunctionCall", + "src": "1941:16:10" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1931:6:10" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes32_fromMemory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "1816:9:10", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "1827:7:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "1839:6:10", + "type": "" + } + ], + "src": "1769:194:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2120:519:10", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "2167:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value4", + "nodeType": "YulIdentifier", + "src": "2176:6:10" + }, + { + "name": "value4", + "nodeType": "YulIdentifier", + "src": "2184:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "2169:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "2169:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "2169:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "2141:7:10" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2150:9:10" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "2137:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "2137:23:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2162:3:10", + "type": "", + "value": "192" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "2133:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "2133:33:10" + }, + "nodeType": "YulIf", + "src": "2130:2:10" + }, + { + "nodeType": "YulAssignment", + "src": "2202:33:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2225:9:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "2212:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "2212:23:10" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "2202:6:10" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "2244:42:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2271:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2282:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2267:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "2267:18:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "2254:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "2254:32:10" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "2244:6:10" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "2295:42:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2322:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2333:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2318:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "2318:18:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "2305:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "2305:32:10" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "2295:6:10" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "2346:42:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2373:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2384:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2369:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "2369:18:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "2356:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "2356:32:10" + }, + "variableNames": [ + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "2346:6:10" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "2397:46:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2427:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2438:3:10", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2423:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "2423:19:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "2410:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "2410:33:10" + }, + "variables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "2401:5:10", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "2479:5:10" + } + ], + "functionName": { + "name": "validator_revert_t_address", + "nodeType": "YulIdentifier", + "src": "2452:26:10" + }, + "nodeType": "YulFunctionCall", + "src": "2452:33:10" + }, + "nodeType": "YulExpressionStatement", + "src": "2452:33:10" + }, + { + "nodeType": "YulAssignment", + "src": "2494:15:10", + "value": { + "name": "value", + "nodeType": "YulIdentifier", + "src": "2504:5:10" + }, + "variableNames": [ + { + "name": "value4", + "nodeType": "YulIdentifier", + "src": "2494:6:10" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "2518:48:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2550:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2561:3:10", + "type": "", + "value": "160" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2546:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "2546:19:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "2533:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "2533:33:10" + }, + "variables": [ + { + "name": "value_1", + "nodeType": "YulTypedName", + "src": "2522:7:10", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "2599:7:10" + } + ], + "functionName": { + "name": "validator_revert_t_bool", + "nodeType": "YulIdentifier", + "src": "2575:23:10" + }, + "nodeType": "YulFunctionCall", + "src": "2575:32:10" + }, + "nodeType": "YulExpressionStatement", + "src": "2575:32:10" + }, + { + "nodeType": "YulAssignment", + "src": "2616:17:10", + "value": { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "2626:7:10" + }, + "variableNames": [ + { + "name": "value5", + "nodeType": "YulIdentifier", + "src": "2616:6:10" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes32t_bytes32t_bytes32t_uint256t_addresst_bool", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "2046:9:10", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "2057:7:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "2069:6:10", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "2077:6:10", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "2085:6:10", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "2093:6:10", + "type": "" + }, + { + "name": "value4", + "nodeType": "YulTypedName", + "src": "2101:6:10", + "type": "" + }, + { + "name": "value5", + "nodeType": "YulTypedName", + "src": "2109:6:10", + "type": "" + } + ], + "src": "1968:671:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2731:171:10", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "2777:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "2786:6:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "2794:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "2779:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "2779:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "2779:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "2752:7:10" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2761:9:10" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "2748:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "2748:23:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2773:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "2744:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "2744:32:10" + }, + "nodeType": "YulIf", + "src": "2741:2:10" + }, + { + "nodeType": "YulAssignment", + "src": "2812:33:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2835:9:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "2822:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "2822:23:10" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "2812:6:10" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "2854:42:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2881:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2892:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2877:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "2877:18:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "2864:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "2864:32:10" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "2854:6:10" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes32t_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "2689:9:10", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "2700:7:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "2712:6:10", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "2720:6:10", + "type": "" + } + ], + "src": "2644:258:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2997:343:10", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "3043:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3052:6:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3060:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "3045:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "3045:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "3045:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "3018:7:10" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3027:9:10" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "3014:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "3014:23:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3039:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "3010:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "3010:32:10" + }, + "nodeType": "YulIf", + "src": "3007:2:10" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "3078:37:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3105:9:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "3092:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "3092:23:10" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "3082:6:10", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "3158:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3167:6:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3175:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "3160:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "3160:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "3160:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "3130:6:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3138:18:10", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "3127:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "3127:30:10" + }, + "nodeType": "YulIf", + "src": "3124:2:10" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "3193:87:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3252:9:10" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "3263:6:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "3248:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "3248:22:10" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "3272:7:10" + } + ], + "functionName": { + "name": "abi_decode_t_string_calldata", + "nodeType": "YulIdentifier", + "src": "3219:28:10" + }, + "nodeType": "YulFunctionCall", + "src": "3219:61:10" + }, + "variables": [ + { + "name": "value0_1", + "nodeType": "YulTypedName", + "src": "3197:8:10", + "type": "" + }, + { + "name": "value1_1", + "nodeType": "YulTypedName", + "src": "3207:8:10", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "3289:18:10", + "value": { + "name": "value0_1", + "nodeType": "YulIdentifier", + "src": "3299:8:10" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3289:6:10" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "3316:18:10", + "value": { + "name": "value1_1", + "nodeType": "YulIdentifier", + "src": "3326:8:10" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "3316:6:10" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_string_calldata_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "2955:9:10", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "2966:7:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "2978:6:10", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "2986:6:10", + "type": "" + } + ], + "src": "2907:433:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "3415:120:10", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "3461:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3470:6:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3478:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "3463:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "3463:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "3463:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "3436:7:10" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3445:9:10" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "3432:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "3432:23:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3457:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "3428:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "3428:32:10" + }, + "nodeType": "YulIf", + "src": "3425:2:10" + }, + { + "nodeType": "YulAssignment", + "src": "3496:33:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3519:9:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "3506:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "3506:23:10" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3496:6:10" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "3381:9:10", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "3392:7:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "3404:6:10", + "type": "" + } + ], + "src": "3345:190:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "3621:113:10", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "3667:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3676:6:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3684:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "3669:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "3669:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "3669:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "3642:7:10" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3651:9:10" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "3638:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "3638:23:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3663:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "3634:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "3634:32:10" + }, + "nodeType": "YulIf", + "src": "3631:2:10" + }, + { + "nodeType": "YulAssignment", + "src": "3702:26:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3718:9:10" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "3712:5:10" + }, + "nodeType": "YulFunctionCall", + "src": "3712:16:10" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3702:6:10" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint256_fromMemory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "3587:9:10", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "3598:7:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "3610:6:10", + "type": "" + } + ], + "src": "3540:194:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "3876:450:10", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "3922:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3931:6:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3939:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "3924:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "3924:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "3924:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "3897:7:10" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3906:9:10" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "3893:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "3893:23:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3918:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "3889:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "3889:32:10" + }, + "nodeType": "YulIf", + "src": "3886:2:10" + }, + { + "nodeType": "YulAssignment", + "src": "3957:33:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3980:9:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "3967:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "3967:23:10" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3957:6:10" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "3999:45:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4029:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4040:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4025:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "4025:18:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "4012:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "4012:32:10" + }, + "variables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "4003:5:10", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "4080:5:10" + } + ], + "functionName": { + "name": "validator_revert_t_address", + "nodeType": "YulIdentifier", + "src": "4053:26:10" + }, + "nodeType": "YulFunctionCall", + "src": "4053:33:10" + }, + "nodeType": "YulExpressionStatement", + "src": "4053:33:10" + }, + { + "nodeType": "YulAssignment", + "src": "4095:15:10", + "value": { + "name": "value", + "nodeType": "YulIdentifier", + "src": "4105:5:10" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "4095:6:10" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "4119:46:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4150:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4161:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4146:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "4146:18:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "4133:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "4133:32:10" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "4123:6:10", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "4208:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "4217:6:10" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "4225:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "4210:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "4210:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "4210:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "4180:6:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4188:18:10", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "4177:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "4177:30:10" + }, + "nodeType": "YulIf", + "src": "4174:2:10" + }, + { + "nodeType": "YulAssignment", + "src": "4243:77:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4292:9:10" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "4303:6:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4288:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "4288:22:10" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "4312:7:10" + } + ], + "functionName": { + "name": "abi_decode_t_array$_t_uint256_$dyn", + "nodeType": "YulIdentifier", + "src": "4253:34:10" + }, + "nodeType": "YulFunctionCall", + "src": "4253:67:10" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "4243:6:10" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint256t_address_payablet_array$_t_uint256_$dyn_memory_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "3826:9:10", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "3837:7:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "3849:6:10", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "3857:6:10", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "3865:6:10", + "type": "" + } + ], + "src": "3739:587:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "4485:502:10", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "4532:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "4541:6:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "4549:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "4534:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "4534:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "4534:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "4506:7:10" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4515:9:10" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "4502:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "4502:23:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4527:3:10", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "4498:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "4498:33:10" + }, + "nodeType": "YulIf", + "src": "4495:2:10" + }, + { + "nodeType": "YulAssignment", + "src": "4567:33:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4590:9:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "4577:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "4577:23:10" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "4567:6:10" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "4609:45:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4639:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4650:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4635:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "4635:18:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "4622:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "4622:32:10" + }, + "variables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "4613:5:10", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "4690:5:10" + } + ], + "functionName": { + "name": "validator_revert_t_address", + "nodeType": "YulIdentifier", + "src": "4663:26:10" + }, + "nodeType": "YulFunctionCall", + "src": "4663:33:10" + }, + "nodeType": "YulExpressionStatement", + "src": "4663:33:10" + }, + { + "nodeType": "YulAssignment", + "src": "4705:15:10", + "value": { + "name": "value", + "nodeType": "YulIdentifier", + "src": "4715:5:10" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "4705:6:10" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "4729:42:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4756:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4767:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4752:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "4752:18:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "4739:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "4739:32:10" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "4729:6:10" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "4780:46:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4811:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4822:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4807:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "4807:18:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "4794:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "4794:32:10" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "4784:6:10", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "4869:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "4878:6:10" + }, + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "4886:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "4871:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "4871:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "4871:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "4841:6:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4849:18:10", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "4838:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "4838:30:10" + }, + "nodeType": "YulIf", + "src": "4835:2:10" + }, + { + "nodeType": "YulAssignment", + "src": "4904:77:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4953:9:10" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "4964:6:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4949:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "4949:22:10" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "4973:7:10" + } + ], + "functionName": { + "name": "abi_decode_t_array$_t_uint256_$dyn", + "nodeType": "YulIdentifier", + "src": "4914:34:10" + }, + "nodeType": "YulFunctionCall", + "src": "4914:67:10" + }, + "variableNames": [ + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "4904:6:10" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint256t_address_payablet_uint256t_array$_t_uint256_$dyn_memory_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "4427:9:10", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "4438:7:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "4450:6:10", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "4458:6:10", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "4466:6:10", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "4474:6:10", + "type": "" + } + ], + "src": "4331:656:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5121:343:10", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "5168:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "5177:6:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "5185:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "5170:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "5170:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "5170:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "5142:7:10" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5151:9:10" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "5138:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "5138:23:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5163:3:10", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "5134:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "5134:33:10" + }, + "nodeType": "YulIf", + "src": "5131:2:10" + }, + { + "nodeType": "YulAssignment", + "src": "5203:33:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5226:9:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "5213:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "5213:23:10" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "5203:6:10" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "5245:45:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5275:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5286:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "5271:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "5271:18:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "5258:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "5258:32:10" + }, + "variables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "5249:5:10", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "5326:5:10" + } + ], + "functionName": { + "name": "validator_revert_t_address", + "nodeType": "YulIdentifier", + "src": "5299:26:10" + }, + "nodeType": "YulFunctionCall", + "src": "5299:33:10" + }, + "nodeType": "YulExpressionStatement", + "src": "5299:33:10" + }, + { + "nodeType": "YulAssignment", + "src": "5341:15:10", + "value": { + "name": "value", + "nodeType": "YulIdentifier", + "src": "5351:5:10" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "5341:6:10" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "5365:42:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5392:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5403:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "5388:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "5388:18:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "5375:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "5375:32:10" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "5365:6:10" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "5416:42:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5443:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5454:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "5439:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "5439:18:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "5426:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "5426:32:10" + }, + "variableNames": [ + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "5416:6:10" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint256t_address_payablet_uint256t_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "5063:9:10", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "5074:7:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "5086:6:10", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "5094:6:10", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "5102:6:10", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "5110:6:10", + "type": "" + } + ], + "src": "4992:472:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5576:394:10", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "5622:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "5631:6:10" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "5639:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "5624:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "5624:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "5624:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "5597:7:10" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5606:9:10" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "5593:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "5593:23:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5618:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "5589:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "5589:32:10" + }, + "nodeType": "YulIf", + "src": "5586:2:10" + }, + { + "nodeType": "YulAssignment", + "src": "5657:33:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5680:9:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "5667:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "5667:23:10" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "5657:6:10" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "5699:46:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5730:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5741:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "5726:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "5726:18:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "5713:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "5713:32:10" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "5703:6:10", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5788:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "5797:6:10" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "5805:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "5790:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "5790:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "5790:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "5760:6:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5768:18:10", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "5757:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "5757:30:10" + }, + "nodeType": "YulIf", + "src": "5754:2:10" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "5823:87:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5882:9:10" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "5893:6:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "5878:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "5878:22:10" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "5902:7:10" + } + ], + "functionName": { + "name": "abi_decode_t_string_calldata", + "nodeType": "YulIdentifier", + "src": "5849:28:10" + }, + "nodeType": "YulFunctionCall", + "src": "5849:61:10" + }, + "variables": [ + { + "name": "value1_1", + "nodeType": "YulTypedName", + "src": "5827:8:10", + "type": "" + }, + { + "name": "value2_1", + "nodeType": "YulTypedName", + "src": "5837:8:10", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "5919:18:10", + "value": { + "name": "value1_1", + "nodeType": "YulIdentifier", + "src": "5929:8:10" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "5919:6:10" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "5946:18:10", + "value": { + "name": "value2_1", + "nodeType": "YulIdentifier", + "src": "5956:8:10" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "5946:6:10" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint256t_string_calldata_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "5526:9:10", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "5537:7:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "5549:6:10", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "5557:6:10", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "5565:6:10", + "type": "" + } + ], + "src": "5469:501:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "6062:171:10", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "6108:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "6117:6:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "6125:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "6110:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "6110:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "6110:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "6083:7:10" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6092:9:10" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "6079:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "6079:23:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6104:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "6075:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "6075:32:10" + }, + "nodeType": "YulIf", + "src": "6072:2:10" + }, + { + "nodeType": "YulAssignment", + "src": "6143:33:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6166:9:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "6153:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "6153:23:10" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "6143:6:10" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "6185:42:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6212:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6223:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6208:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "6208:18:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "6195:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "6195:32:10" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "6185:6:10" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint256t_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "6020:9:10", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "6031:7:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "6043:6:10", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "6051:6:10", + "type": "" + } + ], + "src": "5975:258:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "6336:157:10", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "6382:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "6391:6:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "6399:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "6384:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "6384:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "6384:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "6357:7:10" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6366:9:10" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "6353:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "6353:23:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6378:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "6349:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "6349:32:10" + }, + "nodeType": "YulIf", + "src": "6346:2:10" + }, + { + "nodeType": "YulAssignment", + "src": "6417:26:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6433:9:10" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "6427:5:10" + }, + "nodeType": "YulFunctionCall", + "src": "6427:16:10" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "6417:6:10" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "6452:35:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6472:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6483:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6468:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "6468:18:10" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "6462:5:10" + }, + "nodeType": "YulFunctionCall", + "src": "6462:25:10" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "6452:6:10" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint256t_uint256_fromMemory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "6294:9:10", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "6305:7:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "6317:6:10", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "6325:6:10", + "type": "" + } + ], + "src": "6238:255:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "6602:222:10", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "6648:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "6657:6:10" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "6665:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "6650:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "6650:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "6650:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "6623:7:10" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6632:9:10" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "6619:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "6619:23:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6644:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "6615:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "6615:32:10" + }, + "nodeType": "YulIf", + "src": "6612:2:10" + }, + { + "nodeType": "YulAssignment", + "src": "6683:33:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6706:9:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "6693:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "6693:23:10" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "6683:6:10" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "6725:42:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6752:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6763:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6748:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "6748:18:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "6735:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "6735:32:10" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "6725:6:10" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "6776:42:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6803:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6814:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6799:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "6799:18:10" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "6786:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "6786:32:10" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "6776:6:10" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint256t_uint256t_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "6552:9:10", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "6563:7:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "6575:6:10", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "6583:6:10", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "6591:6:10", + "type": "" + } + ], + "src": "6498:326:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "6940:380:10", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "6986:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "6995:6:10" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "7003:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "6988:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "6988:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "6988:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "6961:7:10" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6970:9:10" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "6957:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "6957:23:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6982:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "6953:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "6953:32:10" + }, + "nodeType": "YulIf", + "src": "6950:2:10" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "7021:29:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "7040:9:10" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "7034:5:10" + }, + "nodeType": "YulFunctionCall", + "src": "7034:16:10" + }, + "variables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "7025:5:10", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7104:26:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "7113:6:10" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "7121:6:10" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "7106:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "7106:22:10" + }, + "nodeType": "YulExpressionStatement", + "src": "7106:22:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "7072:5:10" + }, + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "7083:5:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7090:10:10", + "type": "", + "value": "0xffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "7079:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "7079:22:10" + } + ], + "functionName": { + "name": "eq", + "nodeType": "YulIdentifier", + "src": "7069:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "7069:33:10" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "7062:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "7062:41:10" + }, + "nodeType": "YulIf", + "src": "7059:2:10" + }, + { + "nodeType": "YulAssignment", + "src": "7139:15:10", + "value": { + "name": "value", + "nodeType": "YulIdentifier", + "src": "7149:5:10" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "7139:6:10" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "7163:40:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "7188:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7199:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7184:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "7184:18:10" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "7178:5:10" + }, + "nodeType": "YulFunctionCall", + "src": "7178:25:10" + }, + "variables": [ + { + "name": "value_1", + "nodeType": "YulTypedName", + "src": "7167:7:10", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "7236:7:10" + } + ], + "functionName": { + "name": "validator_revert_t_bool", + "nodeType": "YulIdentifier", + "src": "7212:23:10" + }, + "nodeType": "YulFunctionCall", + "src": "7212:32:10" + }, + "nodeType": "YulExpressionStatement", + "src": "7212:32:10" + }, + { + "nodeType": "YulAssignment", + "src": "7253:17:10", + "value": { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "7263:7:10" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "7253:6:10" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "7279:35:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "7299:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7310:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7295:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "7295:18:10" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "7289:5:10" + }, + "nodeType": "YulFunctionCall", + "src": "7289:25:10" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "7279:6:10" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint32t_boolt_bytes32_fromMemory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "6890:9:10", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "6901:7:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "6913:6:10", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "6921:6:10", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "6929:6:10", + "type": "" + } + ], + "src": "6829:491:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7376:485:10", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "7386:26:10", + "value": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "7406:5:10" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "7400:5:10" + }, + "nodeType": "YulFunctionCall", + "src": "7400:12:10" + }, + "variables": [ + { + "name": "length", + "nodeType": "YulTypedName", + "src": "7390:6:10", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "7428:3:10" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "7433:6:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "7421:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "7421:19:10" + }, + "nodeType": "YulExpressionStatement", + "src": "7421:19:10" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "7449:12:10", + "value": { + "name": "end", + "nodeType": "YulIdentifier", + "src": "7458:3:10" + }, + "variables": [ + { + "name": "i", + "nodeType": "YulTypedName", + "src": "7453:1:10", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7522:110:10", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "7536:14:10", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7546:4:10", + "type": "", + "value": "0x20" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "7540:2:10", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "7578:3:10" + }, + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "7583:1:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7574:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "7574:11:10" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "7587:2:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7570:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "7570:20:10" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "7606:5:10" + }, + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "7613:1:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7602:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "7602:13:10" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "7617:2:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7598:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "7598:22:10" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "7592:5:10" + }, + "nodeType": "YulFunctionCall", + "src": "7592:29:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "7563:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "7563:59:10" + }, + "nodeType": "YulExpressionStatement", + "src": "7563:59:10" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "7481:1:10" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "7484:6:10" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "7478:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "7478:13:10" + }, + "nodeType": "YulForLoop", + "post": { + "nodeType": "YulBlock", + "src": "7492:21:10", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "7494:17:10", + "value": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "7503:1:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7506:4:10", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7499:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "7499:12:10" + }, + "variableNames": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "7494:1:10" + } + ] + } + ] + }, + "pre": { + "nodeType": "YulBlock", + "src": "7474:3:10", + "statements": [] + }, + "src": "7470:162:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7666:64:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "7695:3:10" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "7700:6:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7691:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "7691:16:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7709:4:10", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7687:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "7687:27:10" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "7716:3:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "7680:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "7680:40:10" + }, + "nodeType": "YulExpressionStatement", + "src": "7680:40:10" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "7647:1:10" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "7650:6:10" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "7644:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "7644:13:10" + }, + "nodeType": "YulIf", + "src": "7641:2:10" + }, + { + "nodeType": "YulAssignment", + "src": "7739:116:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "7754:3:10" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "7767:6:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7775:2:10", + "type": "", + "value": "31" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7763:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "7763:15:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7780:66:10", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "7759:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "7759:88:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7750:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "7750:98:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7850:4:10", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7746:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "7746:109:10" + }, + "variableNames": [ + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "7739:3:10" + } + ] + } + ] + }, + "name": "abi_encode_t_bytes", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "7353:5:10", + "type": "" + }, + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "7360:3:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nodeType": "YulTypedName", + "src": "7368:3:10", + "type": "" + } + ], + "src": "7325:536:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7925:755:10", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "7935:29:10", + "value": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "7958:5:10" + } + ], + "functionName": { + "name": "sload", + "nodeType": "YulIdentifier", + "src": "7952:5:10" + }, + "nodeType": "YulFunctionCall", + "src": "7952:12:10" + }, + "variables": [ + { + "name": "slotValue", + "nodeType": "YulTypedName", + "src": "7939:9:10", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "7973:11:10", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7983:1:10", + "type": "", + "value": "1" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "7977:2:10", + "type": "" + } + ] + }, + { + "cases": [ + { + "body": { + "nodeType": "YulBlock", + "src": "8034:216:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "8055:3:10" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "slotValue", + "nodeType": "YulIdentifier", + "src": "8068:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8079:1:10", + "type": "", + "value": "2" + } + ], + "functionName": { + "name": "div", + "nodeType": "YulIdentifier", + "src": "8064:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "8064:17:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8083:4:10", + "type": "", + "value": "0x7f" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "8060:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "8060:28:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "8048:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "8048:41:10" + }, + "nodeType": "YulExpressionStatement", + "src": "8048:41:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "8113:3:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8118:4:10", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8109:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "8109:14:10" + }, + { + "arguments": [ + { + "name": "slotValue", + "nodeType": "YulIdentifier", + "src": "8129:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8140:66:10", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "8125:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "8125:82:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "8102:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "8102:106:10" + }, + "nodeType": "YulExpressionStatement", + "src": "8102:106:10" + }, + { + "nodeType": "YulAssignment", + "src": "8221:19:10", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "8232:3:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8237:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8228:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "8228:12:10" + }, + "variableNames": [ + { + "name": "ret", + "nodeType": "YulIdentifier", + "src": "8221:3:10" + } + ] + } + ] + }, + "nodeType": "YulCase", + "src": "8027:223:10", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8032:1:10", + "type": "", + "value": "0" + } + }, + { + "body": { + "nodeType": "YulBlock", + "src": "8266:408:10", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "8280:31:10", + "value": { + "arguments": [ + { + "name": "slotValue", + "nodeType": "YulIdentifier", + "src": "8298:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8309:1:10", + "type": "", + "value": "2" + } + ], + "functionName": { + "name": "div", + "nodeType": "YulIdentifier", + "src": "8294:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "8294:17:10" + }, + "variables": [ + { + "name": "length", + "nodeType": "YulTypedName", + "src": "8284:6:10", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "8331:3:10" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "8336:6:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "8324:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "8324:19:10" + }, + "nodeType": "YulExpressionStatement", + "src": "8324:19:10" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "8356:52:10", + "value": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "8402:5:10" + } + ], + "functionName": { + "name": "array_dataslot_t_bytes_storage", + "nodeType": "YulIdentifier", + "src": "8371:30:10" + }, + "nodeType": "YulFunctionCall", + "src": "8371:37:10" + }, + "variables": [ + { + "name": "dataPos", + "nodeType": "YulTypedName", + "src": "8360:7:10", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "8421:10:10", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8430:1:10", + "type": "", + "value": "0" + }, + "variables": [ + { + "name": "i", + "nodeType": "YulTypedName", + "src": "8425:1:10", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "8500:122:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "8533:3:10" + }, + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "8538:1:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8529:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "8529:11:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8542:4:10", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8525:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "8525:22:10" + }, + { + "arguments": [ + { + "name": "dataPos", + "nodeType": "YulIdentifier", + "src": "8555:7:10" + } + ], + "functionName": { + "name": "sload", + "nodeType": "YulIdentifier", + "src": "8549:5:10" + }, + "nodeType": "YulFunctionCall", + "src": "8549:14:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "8518:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "8518:46:10" + }, + "nodeType": "YulExpressionStatement", + "src": "8518:46:10" + }, + { + "nodeType": "YulAssignment", + "src": "8581:27:10", + "value": { + "arguments": [ + { + "name": "dataPos", + "nodeType": "YulIdentifier", + "src": "8596:7:10" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "8605:2:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8592:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "8592:16:10" + }, + "variableNames": [ + { + "name": "dataPos", + "nodeType": "YulIdentifier", + "src": "8581:7:10" + } + ] + } + ] + }, + "condition": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "8455:1:10" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "8458:6:10" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "8452:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "8452:13:10" + }, + "nodeType": "YulForLoop", + "post": { + "nodeType": "YulBlock", + "src": "8466:21:10", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "8468:17:10", + "value": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "8477:1:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8480:4:10", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8473:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "8473:12:10" + }, + "variableNames": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "8468:1:10" + } + ] + } + ] + }, + "pre": { + "nodeType": "YulBlock", + "src": "8448:3:10", + "statements": [] + }, + "src": "8444:178:10" + }, + { + "nodeType": "YulAssignment", + "src": "8635:29:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "8650:3:10" + }, + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "8655:1:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8646:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "8646:11:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8659:4:10", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8642:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "8642:22:10" + }, + "variableNames": [ + { + "name": "ret", + "nodeType": "YulIdentifier", + "src": "8635:3:10" + } + ] + } + ] + }, + "nodeType": "YulCase", + "src": "8259:415:10", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8264:1:10", + "type": "", + "value": "1" + } + } + ], + "expression": { + "arguments": [ + { + "name": "slotValue", + "nodeType": "YulIdentifier", + "src": "8004:9:10" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "8015:2:10" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "8000:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "8000:18:10" + }, + "nodeType": "YulSwitch", + "src": "7993:681:10" + } + ] + }, + "name": "abi_encode_t_bytes_storage", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "7902:5:10", + "type": "" + }, + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "7909:3:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "ret", + "nodeType": "YulTypedName", + "src": "7917:3:10", + "type": "" + } + ], + "src": "7866:814:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "8910:386:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "8927:3:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "8932:6:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "8920:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "8920:19:10" + }, + "nodeType": "YulExpressionStatement", + "src": "8920:19:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "8959:3:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8964:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8955:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "8955:12:10" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "8969:6:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "8948:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "8948:28:10" + }, + "nodeType": "YulExpressionStatement", + "src": "8948:28:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "8996:3:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9001:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8992:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "8992:12:10" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "9006:6:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "8985:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "8985:28:10" + }, + "nodeType": "YulExpressionStatement", + "src": "8985:28:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "9033:3:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9038:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9029:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "9029:12:10" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "9051:6:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9059:42:10", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "9047:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "9047:55:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9104:28:10", + "type": "", + "value": "0x01000000000000000000000000" + } + ], + "functionName": { + "name": "mul", + "nodeType": "YulIdentifier", + "src": "9043:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "9043:90:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "9022:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "9022:112:10" + }, + "nodeType": "YulExpressionStatement", + "src": "9022:112:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "9154:3:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9159:3:10", + "type": "", + "value": "116" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9150:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "9150:13:10" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "value4", + "nodeType": "YulIdentifier", + "src": "9183:6:10" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "9176:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "9176:14:10" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "9169:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "9169:22:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9193:66:10", + "type": "", + "value": "0x0100000000000000000000000000000000000000000000000000000000000000" + } + ], + "functionName": { + "name": "mul", + "nodeType": "YulIdentifier", + "src": "9165:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "9165:95:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "9143:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "9143:118:10" + }, + "nodeType": "YulExpressionStatement", + "src": "9143:118:10" + }, + { + "nodeType": "YulAssignment", + "src": "9270:20:10", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "9281:3:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9286:3:10", + "type": "", + "value": "117" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9277:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "9277:13:10" + }, + "variableNames": [ + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "9270:3:10" + } + ] + } + ] + }, + "name": "abi_encode_tuple_packed_t_bytes32_t_bytes32_t_uint256_t_address_t_bool__to_t_bytes32_t_bytes32_t_uint256_t_address_t_bool__nonPadded_inplace_fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "8854:3:10", + "type": "" + }, + { + "name": "value4", + "nodeType": "YulTypedName", + "src": "8859:6:10", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "8867:6:10", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "8875:6:10", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "8883:6:10", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "8891:6:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nodeType": "YulTypedName", + "src": "8902:3:10", + "type": "" + } + ], + "src": "8685:611:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "9402:125:10", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "9412:26:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9424:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9435:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9420:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "9420:18:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "9412:4:10" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9454:9:10" + }, + { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "9469:6:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9477:42:10", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "9465:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "9465:55:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "9447:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "9447:74:10" + }, + "nodeType": "YulExpressionStatement", + "src": "9447:74:10" + } + ] + }, + "name": "abi_encode_tuple_t_address__to_t_address__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "9371:9:10", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "9382:6:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "9393:4:10", + "type": "" + } + ], + "src": "9301:226:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "9627:92:10", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "9637:26:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9649:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9660:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9645:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "9645:18:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "9637:4:10" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9679:9:10" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "9704:6:10" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "9697:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "9697:14:10" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "9690:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "9690:22:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "9672:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "9672:41:10" + }, + "nodeType": "YulExpressionStatement", + "src": "9672:41:10" + } + ] + }, + "name": "abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "9596:9:10", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "9607:6:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "9618:4:10", + "type": "" + } + ], + "src": "9532:187:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "9825:76:10", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "9835:26:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9847:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9858:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9843:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "9843:18:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "9835:4:10" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9877:9:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "9888:6:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "9870:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "9870:25:10" + }, + "nodeType": "YulExpressionStatement", + "src": "9870:25:10" + } + ] + }, + "name": "abi_encode_tuple_t_bytes32__to_t_bytes32__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "9794:9:10", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "9805:6:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "9816:4:10", + "type": "" + } + ], + "src": "9724:177:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "10071:211:10", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "10081:26:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10093:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10104:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10089:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "10089:18:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "10081:4:10" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10123:9:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "10134:6:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10116:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "10116:25:10" + }, + "nodeType": "YulExpressionStatement", + "src": "10116:25:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10161:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10172:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10157:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "10157:18:10" + }, + { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "10181:6:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10189:42:10", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "10177:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "10177:55:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10150:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "10150:83:10" + }, + "nodeType": "YulExpressionStatement", + "src": "10150:83:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10253:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10264:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10249:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "10249:18:10" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "10269:6:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10242:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "10242:34:10" + }, + "nodeType": "YulExpressionStatement", + "src": "10242:34:10" + } + ] + }, + "name": "abi_encode_tuple_t_bytes32_t_address_payable_t_uint256__to_t_bytes32_t_address_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "10024:9:10", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "10035:6:10", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "10043:6:10", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "10051:6:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "10062:4:10", + "type": "" + } + ], + "src": "9906:376:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "10444:211:10", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "10454:26:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10466:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10477:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10462:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "10462:18:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "10454:4:10" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10496:9:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "10507:6:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10489:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "10489:25:10" + }, + "nodeType": "YulExpressionStatement", + "src": "10489:25:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10534:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10545:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10530:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "10530:18:10" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "10550:6:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10523:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "10523:34:10" + }, + "nodeType": "YulExpressionStatement", + "src": "10523:34:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10577:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10588:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10573:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "10573:18:10" + }, + { + "arguments": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "10597:6:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10605:42:10", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "10593:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "10593:55:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10566:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "10566:83:10" + }, + "nodeType": "YulExpressionStatement", + "src": "10566:83:10" + } + ] + }, + "name": "abi_encode_tuple_t_bytes32_t_bytes32_t_address__to_t_bytes32_t_bytes32_t_address__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "10397:9:10", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "10408:6:10", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "10416:6:10", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "10424:6:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "10435:4:10", + "type": "" + } + ], + "src": "10287:368:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "10779:100:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10796:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10807:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10789:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "10789:21:10" + }, + "nodeType": "YulExpressionStatement", + "src": "10789:21:10" + }, + { + "nodeType": "YulAssignment", + "src": "10819:54:10", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "10846:6:10" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10858:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10869:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10854:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "10854:18:10" + } + ], + "functionName": { + "name": "abi_encode_t_bytes", + "nodeType": "YulIdentifier", + "src": "10827:18:10" + }, + "nodeType": "YulFunctionCall", + "src": "10827:46:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "10819:4:10" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "10748:9:10", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "10759:6:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "10770:4:10", + "type": "" + } + ], + "src": "10660:219:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "11000:108:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11017:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11028:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11010:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "11010:21:10" + }, + "nodeType": "YulExpressionStatement", + "src": "11010:21:10" + }, + { + "nodeType": "YulAssignment", + "src": "11040:62:10", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "11075:6:10" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11087:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11098:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11083:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "11083:18:10" + } + ], + "functionName": { + "name": "abi_encode_t_bytes_storage", + "nodeType": "YulIdentifier", + "src": "11048:26:10" + }, + "nodeType": "YulFunctionCall", + "src": "11048:54:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "11040:4:10" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_bytes_storage__to_t_bytes_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "10969:9:10", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "10980:6:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "10991:4:10", + "type": "" + } + ], + "src": "10884:224:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "11234:125:10", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "11244:26:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11256:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11267:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11252:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "11252:18:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "11244:4:10" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11286:9:10" + }, + { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "11301:6:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11309:42:10", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "11297:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "11297:55:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11279:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "11279:74:10" + }, + "nodeType": "YulExpressionStatement", + "src": "11279:74:10" + } + ] + }, + "name": "abi_encode_tuple_t_contract$_IArbitrator_$1736__to_t_address__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "11203:9:10", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "11214:6:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "11225:4:10", + "type": "" + } + ], + "src": "11113:246:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "11556:302:10", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "11566:27:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11578:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11589:3:10", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11574:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "11574:19:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "11566:4:10" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "11627:13:10", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "invalid", + "nodeType": "YulIdentifier", + "src": "11629:7:10" + }, + "nodeType": "YulFunctionCall", + "src": "11629:9:10" + }, + "nodeType": "YulExpressionStatement", + "src": "11629:9:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "11615:6:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11623:1:10", + "type": "", + "value": "4" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "11612:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "11612:13:10" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "11605:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "11605:21:10" + }, + "nodeType": "YulIf", + "src": "11602:2:10" + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11656:9:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "11667:6:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11649:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "11649:25:10" + }, + "nodeType": "YulExpressionStatement", + "src": "11649:25:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11694:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11705:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11690:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "11690:18:10" + }, + { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "11714:6:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11722:42:10", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "11710:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "11710:55:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11683:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "11683:83:10" + }, + "nodeType": "YulExpressionStatement", + "src": "11683:83:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11786:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11797:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11782:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "11782:18:10" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "11802:6:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11775:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "11775:34:10" + }, + "nodeType": "YulExpressionStatement", + "src": "11775:34:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11829:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11840:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11825:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "11825:18:10" + }, + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "11845:6:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11818:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "11818:34:10" + }, + "nodeType": "YulExpressionStatement", + "src": "11818:34:10" + } + ] + }, + "name": "abi_encode_tuple_t_enum$_Status_$95_t_address_t_uint256_t_uint256__to_t_uint8_t_address_t_uint256_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "11501:9:10", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "11512:6:10", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "11520:6:10", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "11528:6:10", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "11536:6:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "11547:4:10", + "type": "" + } + ], + "src": "11364:494:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "11994:321:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12011:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12022:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12004:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "12004:21:10" + }, + "nodeType": "YulExpressionStatement", + "src": "12004:21:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12045:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12056:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12041:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "12041:18:10" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "12061:6:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12034:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "12034:34:10" + }, + "nodeType": "YulExpressionStatement", + "src": "12034:34:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12094:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12105:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12090:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "12090:18:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "12110:6:10" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "12118:6:10" + } + ], + "functionName": { + "name": "calldatacopy", + "nodeType": "YulIdentifier", + "src": "12077:12:10" + }, + "nodeType": "YulFunctionCall", + "src": "12077:48:10" + }, + "nodeType": "YulExpressionStatement", + "src": "12077:48:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12149:9:10" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "12160:6:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12145:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "12145:22:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12169:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12141:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "12141:31:10" + }, + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "12174:4:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12134:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "12134:45:10" + }, + "nodeType": "YulExpressionStatement", + "src": "12134:45:10" + }, + { + "nodeType": "YulAssignment", + "src": "12188:121:10", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12204:9:10" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "12223:6:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12231:2:10", + "type": "", + "value": "31" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12219:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "12219:15:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12236:66:10", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "12215:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "12215:88:10" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12200:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "12200:104:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12306:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12196:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "12196:113:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "12188:4:10" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_string_calldata_ptr__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "11955:9:10", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "11966:6:10", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "11974:6:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "11985:4:10", + "type": "" + } + ], + "src": "11863:452:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "12441:100:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12458:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12469:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12451:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "12451:21:10" + }, + "nodeType": "YulExpressionStatement", + "src": "12451:21:10" + }, + { + "nodeType": "YulAssignment", + "src": "12481:54:10", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "12508:6:10" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12520:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12531:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12516:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "12516:18:10" + } + ], + "functionName": { + "name": "abi_encode_t_bytes", + "nodeType": "YulIdentifier", + "src": "12489:18:10" + }, + "nodeType": "YulFunctionCall", + "src": "12489:46:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "12481:4:10" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "12410:9:10", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "12421:6:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "12432:4:10", + "type": "" + } + ], + "src": "12320:221:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "12720:236:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12737:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12748:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12730:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "12730:21:10" + }, + "nodeType": "YulExpressionStatement", + "src": "12730:21:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12771:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12782:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12767:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "12767:18:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12787:2:10", + "type": "", + "value": "46" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12760:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "12760:30:10" + }, + "nodeType": "YulExpressionStatement", + "src": "12760:30:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12810:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12821:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12806:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "12806:18:10" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "12826:34:10", + "type": "", + "value": "Funding must be made within the " + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12799:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "12799:62:10" + }, + "nodeType": "YulExpressionStatement", + "src": "12799:62:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12881:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12892:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12877:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "12877:18:10" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "12897:16:10", + "type": "", + "value": "appeal period." + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12870:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "12870:44:10" + }, + "nodeType": "YulExpressionStatement", + "src": "12870:44:10" + }, + { + "nodeType": "YulAssignment", + "src": "12923:27:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12935:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12946:3:10", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12931:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "12931:19:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "12923:4:10" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_0345b6b07b3f7ea23ce7c0682ae193a7b3933d232b736d656630025e0007450f__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "12697:9:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "12711:4:10", + "type": "" + } + ], + "src": "12546:410:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "13135:173:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13152:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13163:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13145:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "13145:21:10" + }, + "nodeType": "YulExpressionStatement", + "src": "13145:21:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13186:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13197:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13182:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "13182:18:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13202:2:10", + "type": "", + "value": "23" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13175:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "13175:30:10" + }, + "nodeType": "YulExpressionStatement", + "src": "13175:30:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13225:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13236:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13221:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "13221:18:10" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "13241:25:10", + "type": "", + "value": "Only arbitrator allowed" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13214:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "13214:53:10" + }, + "nodeType": "YulExpressionStatement", + "src": "13214:53:10" + }, + { + "nodeType": "YulAssignment", + "src": "13276:26:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13288:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13299:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13284:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "13284:18:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "13276:4:10" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_1587ae476a4c91cb27e60192a738172f2d3bd86eda002a76489557322fbcd606__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "13112:9:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "13126:4:10", + "type": "" + } + ], + "src": "12961:347:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "13487:369:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13504:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13515:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13497:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "13497:21:10" + }, + "nodeType": "YulExpressionStatement", + "src": "13497:21:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13538:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13549:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13534:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "13534:18:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13554:2:10", + "type": "", + "value": "99" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13527:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "13527:30:10" + }, + "nodeType": "YulExpressionStatement", + "src": "13527:30:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13577:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13588:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13573:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "13573:18:10" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "13593:34:10", + "type": "", + "value": "The hash of the history paramete" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13566:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "13566:62:10" + }, + "nodeType": "YulExpressionStatement", + "src": "13566:62:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13648:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13659:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13644:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "13644:18:10" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "13664:34:10", + "type": "", + "value": "rs supplied does not match the o" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13637:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "13637:62:10" + }, + "nodeType": "YulExpressionStatement", + "src": "13637:62:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13719:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13730:3:10", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13715:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "13715:19:10" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "13736:34:10", + "type": "", + "value": "ne stored in the Realitio contra" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13708:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "13708:63:10" + }, + "nodeType": "YulExpressionStatement", + "src": "13708:63:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13791:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13802:3:10", + "type": "", + "value": "160" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13787:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "13787:19:10" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "13808:5:10", + "type": "", + "value": "ct." + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13780:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "13780:34:10" + }, + "nodeType": "YulExpressionStatement", + "src": "13780:34:10" + }, + { + "nodeType": "YulAssignment", + "src": "13823:27:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13835:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13846:3:10", + "type": "", + "value": "192" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13831:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "13831:19:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "13823:4:10" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_281e1d87b180850f34e67af4ee84b890763a546671bbe4c68d9b7e0f4b9d0bd4__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "13464:9:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "13478:4:10", + "type": "" + } + ], + "src": "13313:543:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "14035:179:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14052:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14063:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "14045:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "14045:21:10" + }, + "nodeType": "YulExpressionStatement", + "src": "14045:21:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14086:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14097:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14082:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "14082:18:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14102:2:10", + "type": "", + "value": "29" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "14075:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "14075:30:10" + }, + "nodeType": "YulExpressionStatement", + "src": "14075:30:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14125:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14136:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14121:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "14121:18:10" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "14141:31:10", + "type": "", + "value": "Arbitration already requested" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "14114:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "14114:59:10" + }, + "nodeType": "YulExpressionStatement", + "src": "14114:59:10" + }, + { + "nodeType": "YulAssignment", + "src": "14182:26:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14194:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14205:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14190:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "14190:18:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "14182:4:10" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_55423884b287f9932d36a37128861bfbe4d8feea42af3dd3ab8bbf80c9ba5cb7__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "14012:9:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "14026:4:10", + "type": "" + } + ], + "src": "13861:353:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "14393:164:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14410:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14421:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "14403:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "14403:21:10" + }, + "nodeType": "YulExpressionStatement", + "src": "14403:21:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14444:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14455:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14440:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "14440:18:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14460:2:10", + "type": "", + "value": "14" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "14433:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "14433:30:10" + }, + "nodeType": "YulExpressionStatement", + "src": "14433:30:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14483:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14494:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14479:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "14479:18:10" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "14499:16:10", + "type": "", + "value": "Invalid ruling" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "14472:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "14472:44:10" + }, + "nodeType": "YulExpressionStatement", + "src": "14472:44:10" + }, + { + "nodeType": "YulAssignment", + "src": "14525:26:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14537:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14548:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14533:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "14533:18:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "14525:4:10" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_7a8ecda55f6cca96c1978f4fd25ea15366a0d0c7eef1b0ddd6bb2039bf48c978__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "14370:9:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "14384:4:10", + "type": "" + } + ], + "src": "14219:338:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "14736:177:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14753:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14764:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "14746:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "14746:21:10" + }, + "nodeType": "YulExpressionStatement", + "src": "14746:21:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14787:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14798:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14783:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "14783:18:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14803:2:10", + "type": "", + "value": "27" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "14776:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "14776:30:10" + }, + "nodeType": "YulExpressionStatement", + "src": "14776:30:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14826:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14837:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14822:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "14822:18:10" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "14842:29:10", + "type": "", + "value": "The status should be Ruled." + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "14815:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "14815:57:10" + }, + "nodeType": "YulExpressionStatement", + "src": "14815:57:10" + }, + { + "nodeType": "YulAssignment", + "src": "14881:26:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14893:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14904:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14889:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "14889:18:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "14881:4:10" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_7b12e68595b54b95620c01e48f1dc5573a4c5ef17b89e01ed1eb1d416d772095__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "14713:9:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "14727:4:10", + "type": "" + } + ], + "src": "14562:351:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "15092:181:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15109:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15120:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15102:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "15102:21:10" + }, + "nodeType": "YulExpressionStatement", + "src": "15102:21:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15143:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15154:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15139:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "15139:18:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15159:2:10", + "type": "", + "value": "31" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15132:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "15132:30:10" + }, + "nodeType": "YulExpressionStatement", + "src": "15132:30:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15182:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15193:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15178:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "15178:18:10" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "15198:33:10", + "type": "", + "value": "Only governor can execute this." + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15171:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "15171:61:10" + }, + "nodeType": "YulExpressionStatement", + "src": "15171:61:10" + }, + { + "nodeType": "YulAssignment", + "src": "15241:26:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15253:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15264:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15249:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "15249:18:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "15241:4:10" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_7f704123736d1b3a92e260c8141259bdf1f9f67d73c4011b0e241b32535a29c0__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "15069:9:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "15083:4:10", + "type": "" + } + ], + "src": "14918:355:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "15452:173:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15469:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15480:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15462:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "15462:21:10" + }, + "nodeType": "YulExpressionStatement", + "src": "15462:21:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15503:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15514:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15499:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "15499:18:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15519:2:10", + "type": "", + "value": "23" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15492:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "15492:30:10" + }, + "nodeType": "YulExpressionStatement", + "src": "15492:30:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15542:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15553:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15538:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "15538:18:10" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "15558:25:10", + "type": "", + "value": "Answer is out of bounds" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15531:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "15531:53:10" + }, + "nodeType": "YulExpressionStatement", + "src": "15531:53:10" + }, + { + "nodeType": "YulAssignment", + "src": "15593:26:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15605:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15616:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15601:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "15601:18:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "15593:4:10" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_807f252b41bd7d25b9b54c1160c4b1e87b4c73129edc3c10cb4da24c4632a9c3__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "15429:9:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "15443:4:10", + "type": "" + } + ], + "src": "15278:347:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "15804:173:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15821:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15832:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15814:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "15814:21:10" + }, + "nodeType": "YulExpressionStatement", + "src": "15814:21:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15855:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15866:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15851:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "15851:18:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15871:2:10", + "type": "", + "value": "23" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15844:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "15844:30:10" + }, + "nodeType": "YulExpressionStatement", + "src": "15844:30:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15894:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15905:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15890:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "15890:18:10" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "15910:25:10", + "type": "", + "value": "There is no ruling yet." + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15883:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "15883:53:10" + }, + "nodeType": "YulExpressionStatement", + "src": "15883:53:10" + }, + { + "nodeType": "YulAssignment", + "src": "15945:26:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15957:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15968:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15953:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "15953:18:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "15945:4:10" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_9591a49cf5d9e3ba9b3aea5505a2b8a639d2f239a0cb6a9059466b60c54a080f__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "15781:9:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "15795:4:10", + "type": "" + } + ], + "src": "15630:347:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "16156:171:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16173:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16184:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16166:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "16166:21:10" + }, + "nodeType": "YulExpressionStatement", + "src": "16166:21:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16207:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16218:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16203:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "16203:18:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16223:2:10", + "type": "", + "value": "21" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16196:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "16196:30:10" + }, + "nodeType": "YulExpressionStatement", + "src": "16196:30:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16246:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16257:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16242:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "16242:18:10" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "16262:23:10", + "type": "", + "value": "No dispute to appeal." + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16235:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "16235:51:10" + }, + "nodeType": "YulExpressionStatement", + "src": "16235:51:10" + }, + { + "nodeType": "YulAssignment", + "src": "16295:26:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16307:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16318:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16303:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "16303:18:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "16295:4:10" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_977851d5d407d7cd7d94a1de96a1bef813f7600043d5e83553db2bd20019e46d__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "16133:9:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "16147:4:10", + "type": "" + } + ], + "src": "15982:345:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "16506:179:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16523:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16534:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16516:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "16516:21:10" + }, + "nodeType": "YulExpressionStatement", + "src": "16516:21:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16557:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16568:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16553:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "16553:18:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16573:2:10", + "type": "", + "value": "29" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16546:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "16546:30:10" + }, + "nodeType": "YulExpressionStatement", + "src": "16546:30:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16596:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16607:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16592:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "16592:18:10" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "16612:31:10", + "type": "", + "value": "There is no metaevidence yet." + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16585:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "16585:59:10" + }, + "nodeType": "YulExpressionStatement", + "src": "16585:59:10" + }, + { + "nodeType": "YulAssignment", + "src": "16653:26:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16665:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16676:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16661:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "16661:18:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "16653:4:10" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_aa7d933803aa49666b2a880b5e0ce2616fb839013df37734e6f96b996f511bfc__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "16483:9:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "16497:4:10", + "type": "" + } + ], + "src": "16332:353:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "16864:223:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16881:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16892:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16874:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "16874:21:10" + }, + "nodeType": "YulExpressionStatement", + "src": "16874:21:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16915:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16926:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16911:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "16911:18:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16931:2:10", + "type": "", + "value": "33" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16904:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "16904:30:10" + }, + "nodeType": "YulExpressionStatement", + "src": "16904:30:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16954:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16965:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16950:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "16950:18:10" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "16970:34:10", + "type": "", + "value": "Appeal fee has already been paid" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16943:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "16943:62:10" + }, + "nodeType": "YulExpressionStatement", + "src": "16943:62:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17025:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17036:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17021:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "17021:18:10" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "17041:3:10", + "type": "", + "value": "." + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17014:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "17014:31:10" + }, + "nodeType": "YulExpressionStatement", + "src": "17014:31:10" + }, + { + "nodeType": "YulAssignment", + "src": "17054:27:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17066:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17077:3:10", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17062:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "17062:19:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "17054:4:10" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_c2f2256a77e1cd7cdc564a3b966df4f3e5bfbdc15f00156637ffbff138e529be__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "16841:9:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "16855:4:10", + "type": "" + } + ], + "src": "16690:397:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "17266:235:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17283:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17294:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17276:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "17276:21:10" + }, + "nodeType": "YulExpressionStatement", + "src": "17276:21:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17317:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17328:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17313:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "17313:18:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17333:2:10", + "type": "", + "value": "45" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17306:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "17306:30:10" + }, + "nodeType": "YulExpressionStatement", + "src": "17306:30:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17356:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17367:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17352:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "17352:18:10" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "17372:34:10", + "type": "", + "value": "Cannot submit evidence to a reso" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17345:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "17345:62:10" + }, + "nodeType": "YulExpressionStatement", + "src": "17345:62:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17427:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17438:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17423:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "17423:18:10" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "17443:15:10", + "type": "", + "value": "lved dispute." + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17416:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "17416:43:10" + }, + "nodeType": "YulExpressionStatement", + "src": "17416:43:10" + }, + { + "nodeType": "YulAssignment", + "src": "17468:27:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17480:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17491:3:10", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17476:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "17476:19:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "17468:4:10" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_ca4412daad1a7629a806d6ed5fb65348818aea0846591a9cf2015068ce96fd51__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "17243:9:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "17257:4:10", + "type": "" + } + ], + "src": "17092:409:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "17680:319:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17697:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17708:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17690:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "17690:21:10" + }, + "nodeType": "YulExpressionStatement", + "src": "17690:21:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17731:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17742:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17727:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "17727:18:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17747:2:10", + "type": "", + "value": "89" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17720:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "17720:30:10" + }, + "nodeType": "YulExpressionStatement", + "src": "17720:30:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17770:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17781:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17766:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "17766:18:10" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "17786:34:10", + "type": "", + "value": "Arbitration cannot be done until" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17759:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "17759:62:10" + }, + "nodeType": "YulExpressionStatement", + "src": "17759:62:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17841:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17852:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17837:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "17837:18:10" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "17857:34:10", + "type": "", + "value": " the last answerer has had time " + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17830:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "17830:62:10" + }, + "nodeType": "YulExpressionStatement", + "src": "17830:62:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17912:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17923:3:10", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17908:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "17908:19:10" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "17929:27:10", + "type": "", + "value": "to reveal its commitment." + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17901:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "17901:56:10" + }, + "nodeType": "YulExpressionStatement", + "src": "17901:56:10" + }, + { + "nodeType": "YulAssignment", + "src": "17966:27:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17978:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17989:3:10", + "type": "", + "value": "160" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17974:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "17974:19:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "17966:4:10" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_d686c78ed011130263da78637058c22087c97502c2e1ecdc794fbd91e85f16cc__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "17657:9:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "17671:4:10", + "type": "" + } + ], + "src": "17506:493:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "18178:176:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18195:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18206:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "18188:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "18188:21:10" + }, + "nodeType": "YulExpressionStatement", + "src": "18188:21:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18229:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18240:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "18225:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "18225:18:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18245:2:10", + "type": "", + "value": "26" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "18218:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "18218:30:10" + }, + "nodeType": "YulExpressionStatement", + "src": "18218:30:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18268:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18279:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "18264:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "18264:18:10" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "18284:28:10", + "type": "", + "value": "Invalid arbitration status" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "18257:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "18257:56:10" + }, + "nodeType": "YulExpressionStatement", + "src": "18257:56:10" + }, + { + "nodeType": "YulAssignment", + "src": "18322:26:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18334:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18345:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "18330:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "18330:18:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "18322:4:10" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_eff7a83c06f307332f22e019405c9ddb8a5159f654bea9234a3c2d855632b2b1__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "18155:9:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "18169:4:10", + "type": "" + } + ], + "src": "18004:350:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "18460:76:10", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "18470:26:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18482:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18493:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "18478:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "18478:18:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "18470:4:10" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18512:9:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "18523:6:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "18505:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "18505:25:10" + }, + "nodeType": "YulExpressionStatement", + "src": "18505:25:10" + } + ] + }, + "name": "abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "18429:9:10", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "18440:6:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "18451:4:10", + "type": "" + } + ], + "src": "18359:177:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "18685:151:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18702:9:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "18713:6:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "18695:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "18695:25:10" + }, + "nodeType": "YulExpressionStatement", + "src": "18695:25:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18740:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18751:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "18736:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "18736:18:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18756:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "18729:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "18729:30:10" + }, + "nodeType": "YulExpressionStatement", + "src": "18729:30:10" + }, + { + "nodeType": "YulAssignment", + "src": "18768:62:10", + "value": { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "18803:6:10" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18815:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18826:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "18811:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "18811:18:10" + } + ], + "functionName": { + "name": "abi_encode_t_bytes_storage", + "nodeType": "YulIdentifier", + "src": "18776:26:10" + }, + "nodeType": "YulFunctionCall", + "src": "18776:54:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "18768:4:10" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_uint256_t_bytes_storage__to_t_uint256_t_bytes_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "18646:9:10", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "18657:6:10", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "18665:6:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "18676:4:10", + "type": "" + } + ], + "src": "18541:295:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "18970:119:10", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "18980:26:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18992:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19003:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "18988:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "18988:18:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "18980:4:10" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19022:9:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "19033:6:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "19015:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "19015:25:10" + }, + "nodeType": "YulExpressionStatement", + "src": "19015:25:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19060:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19071:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "19056:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "19056:18:10" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "19076:6:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "19049:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "19049:34:10" + }, + "nodeType": "YulExpressionStatement", + "src": "19049:34:10" + } + ] + }, + "name": "abi_encode_tuple_t_uint256_t_uint256__to_t_uint256_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "18931:9:10", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "18942:6:10", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "18950:6:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "18961:4:10", + "type": "" + } + ], + "src": "18841:248:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "19279:206:10", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "19289:27:10", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19301:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19312:3:10", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "19297:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "19297:19:10" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "19289:4:10" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19332:9:10" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "19343:6:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "19325:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "19325:25:10" + }, + "nodeType": "YulExpressionStatement", + "src": "19325:25:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19370:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19381:2:10", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "19366:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "19366:18:10" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "19386:6:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "19359:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "19359:34:10" + }, + "nodeType": "YulExpressionStatement", + "src": "19359:34:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19413:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19424:2:10", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "19409:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "19409:18:10" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "19429:6:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "19402:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "19402:34:10" + }, + "nodeType": "YulExpressionStatement", + "src": "19402:34:10" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19456:9:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19467:2:10", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "19452:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "19452:18:10" + }, + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "19472:6:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "19445:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "19445:34:10" + }, + "nodeType": "YulExpressionStatement", + "src": "19445:34:10" + } + ] + }, + "name": "abi_encode_tuple_t_uint256_t_uint256_t_uint256_t_uint256__to_t_uint256_t_uint256_t_uint256_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "19224:9:10", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "19235:6:10", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "19243:6:10", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "19251:6:10", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "19259:6:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "19270:4:10", + "type": "" + } + ], + "src": "19094:391:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "19547:71:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "data", + "nodeType": "YulIdentifier", + "src": "19564:4:10" + }, + { + "name": "ptr", + "nodeType": "YulIdentifier", + "src": "19570:3:10" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "19557:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "19557:17:10" + }, + "nodeType": "YulExpressionStatement", + "src": "19557:17:10" + }, + { + "nodeType": "YulAssignment", + "src": "19583:29:10", + "value": { + "arguments": [ + { + "name": "data", + "nodeType": "YulIdentifier", + "src": "19601:4:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19607:4:10", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "keccak256", + "nodeType": "YulIdentifier", + "src": "19591:9:10" + }, + "nodeType": "YulFunctionCall", + "src": "19591:21:10" + }, + "variableNames": [ + { + "name": "data", + "nodeType": "YulIdentifier", + "src": "19583:4:10" + } + ] + } + ] + }, + "name": "array_dataslot_t_bytes_storage", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "ptr", + "nodeType": "YulTypedName", + "src": "19530:3:10", + "type": "" + } + ], + "returnVariables": [ + { + "name": "data", + "nodeType": "YulTypedName", + "src": "19538:4:10", + "type": "" + } + ], + "src": "19490:128:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "19670:109:10", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "19757:16:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19766:1:10", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19769:1:10", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "19759:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "19759:12:10" + }, + "nodeType": "YulExpressionStatement", + "src": "19759:12:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "19693:5:10" + }, + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "19704:5:10" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19711:42:10", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "19700:3:10" + }, + "nodeType": "YulFunctionCall", + "src": "19700:54:10" + } + ], + "functionName": { + "name": "eq", + "nodeType": "YulIdentifier", + "src": "19690:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "19690:65:10" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "19683:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "19683:73:10" + }, + "nodeType": "YulIf", + "src": "19680:2:10" + } + ] + }, + "name": "validator_revert_t_address", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "19659:5:10", + "type": "" + } + ], + "src": "19623:156:10" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "19828:76:10", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "19882:16:10", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19891:1:10", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19894:1:10", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "19884:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "19884:12:10" + }, + "nodeType": "YulExpressionStatement", + "src": "19884:12:10" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "19851:5:10" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "19872:5:10" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "19865:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "19865:13:10" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "19858:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "19858:21:10" + } + ], + "functionName": { + "name": "eq", + "nodeType": "YulIdentifier", + "src": "19848:2:10" + }, + "nodeType": "YulFunctionCall", + "src": "19848:32:10" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "19841:6:10" + }, + "nodeType": "YulFunctionCall", + "src": "19841:40:10" + }, + "nodeType": "YulIf", + "src": "19838:2:10" + } + ] + }, + "name": "validator_revert_t_bool", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "19817:5:10", + "type": "" + } + ], + "src": "19784:120:10" + } + ] + }, + "contents": "{\n { }\n function abi_decode_t_array$_t_uint256_$dyn(offset, end) -> array\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(array, array) }\n let _1 := calldataload(offset)\n let _2 := 0x20\n let _3 := 0xffffffffffffffff\n if gt(_1, _3) { invalid() }\n let _4 := mul(_1, _2)\n let memPtr := mload(64)\n let newFreePtr := add(add(memPtr, _4), _2)\n if or(gt(newFreePtr, _3), lt(newFreePtr, memPtr)) { invalid() }\n mstore(64, newFreePtr)\n let dst := memPtr\n mstore(memPtr, _1)\n dst := add(memPtr, _2)\n let src := add(offset, _2)\n if gt(add(add(offset, _4), _2), end) { revert(array, array) }\n let i := array\n for { } lt(i, _1) { i := add(i, 1) }\n {\n mstore(dst, calldataload(src))\n dst := add(dst, _2)\n src := add(src, _2)\n }\n array := memPtr\n }\n function abi_decode_t_string_calldata(offset, end) -> arrayPos, length\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(arrayPos, arrayPos) }\n length := calldataload(offset)\n if gt(length, 0xffffffffffffffff) { revert(arrayPos, arrayPos) }\n arrayPos := add(offset, 0x20)\n if gt(add(add(offset, length), 0x20), end) { revert(0, 0) }\n }\n function abi_decode_tuple_t_address(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(value0, value0) }\n let value := calldataload(headStart)\n validator_revert_t_address(value)\n value0 := value\n }\n function abi_decode_tuple_t_bytes32(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(value0, value0) }\n value0 := calldataload(headStart)\n }\n function abi_decode_tuple_t_bytes32_fromMemory(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(value0, value0) }\n value0 := mload(headStart)\n }\n function abi_decode_tuple_t_bytes32t_bytes32t_bytes32t_uint256t_addresst_bool(headStart, dataEnd) -> value0, value1, value2, value3, value4, value5\n {\n if slt(sub(dataEnd, headStart), 192) { revert(value4, value4) }\n value0 := calldataload(headStart)\n value1 := calldataload(add(headStart, 32))\n value2 := calldataload(add(headStart, 64))\n value3 := calldataload(add(headStart, 96))\n let value := calldataload(add(headStart, 128))\n validator_revert_t_address(value)\n value4 := value\n let value_1 := calldataload(add(headStart, 160))\n validator_revert_t_bool(value_1)\n value5 := value_1\n }\n function abi_decode_tuple_t_bytes32t_uint256(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(value0, value0) }\n value0 := calldataload(headStart)\n value1 := calldataload(add(headStart, 32))\n }\n function abi_decode_tuple_t_string_calldata_ptr(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 32) { revert(value0, value0) }\n let offset := calldataload(headStart)\n if gt(offset, 0xffffffffffffffff) { revert(value0, value0) }\n let value0_1, value1_1 := abi_decode_t_string_calldata(add(headStart, offset), dataEnd)\n value0 := value0_1\n value1 := value1_1\n }\n function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(value0, value0) }\n value0 := calldataload(headStart)\n }\n function abi_decode_tuple_t_uint256_fromMemory(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(value0, value0) }\n value0 := mload(headStart)\n }\n function abi_decode_tuple_t_uint256t_address_payablet_array$_t_uint256_$dyn_memory_ptr(headStart, dataEnd) -> value0, value1, value2\n {\n if slt(sub(dataEnd, headStart), 96) { revert(value0, value0) }\n value0 := calldataload(headStart)\n let value := calldataload(add(headStart, 32))\n validator_revert_t_address(value)\n value1 := value\n let offset := calldataload(add(headStart, 64))\n if gt(offset, 0xffffffffffffffff) { revert(value2, value2) }\n value2 := abi_decode_t_array$_t_uint256_$dyn(add(headStart, offset), dataEnd)\n }\n function abi_decode_tuple_t_uint256t_address_payablet_uint256t_array$_t_uint256_$dyn_memory_ptr(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 128) { revert(value0, value0) }\n value0 := calldataload(headStart)\n let value := calldataload(add(headStart, 32))\n validator_revert_t_address(value)\n value1 := value\n value2 := calldataload(add(headStart, 64))\n let offset := calldataload(add(headStart, 96))\n if gt(offset, 0xffffffffffffffff) { revert(value3, value3) }\n value3 := abi_decode_t_array$_t_uint256_$dyn(add(headStart, offset), dataEnd)\n }\n function abi_decode_tuple_t_uint256t_address_payablet_uint256t_uint256(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 128) { revert(value0, value0) }\n value0 := calldataload(headStart)\n let value := calldataload(add(headStart, 32))\n validator_revert_t_address(value)\n value1 := value\n value2 := calldataload(add(headStart, 64))\n value3 := calldataload(add(headStart, 96))\n }\n function abi_decode_tuple_t_uint256t_string_calldata_ptr(headStart, dataEnd) -> value0, value1, value2\n {\n if slt(sub(dataEnd, headStart), 64) { revert(value2, value2) }\n value0 := calldataload(headStart)\n let offset := calldataload(add(headStart, 32))\n if gt(offset, 0xffffffffffffffff) { revert(value2, value2) }\n let value1_1, value2_1 := abi_decode_t_string_calldata(add(headStart, offset), dataEnd)\n value1 := value1_1\n value2 := value2_1\n }\n function abi_decode_tuple_t_uint256t_uint256(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(value0, value0) }\n value0 := calldataload(headStart)\n value1 := calldataload(add(headStart, 32))\n }\n function abi_decode_tuple_t_uint256t_uint256_fromMemory(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(value0, value0) }\n value0 := mload(headStart)\n value1 := mload(add(headStart, 32))\n }\n function abi_decode_tuple_t_uint256t_uint256t_uint256(headStart, dataEnd) -> value0, value1, value2\n {\n if slt(sub(dataEnd, headStart), 96) { revert(value2, value2) }\n value0 := calldataload(headStart)\n value1 := calldataload(add(headStart, 32))\n value2 := calldataload(add(headStart, 64))\n }\n function abi_decode_tuple_t_uint32t_boolt_bytes32_fromMemory(headStart, dataEnd) -> value0, value1, value2\n {\n if slt(sub(dataEnd, headStart), 96) { revert(value2, value2) }\n let value := mload(headStart)\n if iszero(eq(value, and(value, 0xffffffff))) { revert(value2, value2) }\n value0 := value\n let value_1 := mload(add(headStart, 32))\n validator_revert_t_bool(value_1)\n value1 := value_1\n value2 := mload(add(headStart, 64))\n }\n function abi_encode_t_bytes(value, pos) -> end\n {\n let length := mload(value)\n mstore(pos, length)\n let i := end\n for { } lt(i, length) { i := add(i, 0x20) }\n {\n let _1 := 0x20\n mstore(add(add(pos, i), _1), mload(add(add(value, i), _1)))\n }\n if gt(i, length)\n {\n mstore(add(add(pos, length), 0x20), end)\n }\n end := add(add(pos, and(add(length, 31), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0)), 0x20)\n }\n function abi_encode_t_bytes_storage(value, pos) -> ret\n {\n let slotValue := sload(value)\n let _1 := 1\n switch and(slotValue, _1)\n case 0 {\n mstore(pos, and(div(slotValue, 2), 0x7f))\n mstore(add(pos, 0x20), and(slotValue, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00))\n ret := add(pos, 64)\n }\n case 1 {\n let length := div(slotValue, 2)\n mstore(pos, length)\n let dataPos := array_dataslot_t_bytes_storage(value)\n let i := 0\n for { } lt(i, length) { i := add(i, 0x20) }\n {\n mstore(add(add(pos, i), 0x20), sload(dataPos))\n dataPos := add(dataPos, _1)\n }\n ret := add(add(pos, i), 0x20)\n }\n }\n function abi_encode_tuple_packed_t_bytes32_t_bytes32_t_uint256_t_address_t_bool__to_t_bytes32_t_bytes32_t_uint256_t_address_t_bool__nonPadded_inplace_fromStack_reversed(pos, value4, value3, value2, value1, value0) -> end\n {\n mstore(pos, value0)\n mstore(add(pos, 32), value1)\n mstore(add(pos, 64), value2)\n mstore(add(pos, 96), mul(and(value3, 0xffffffffffffffffffffffffffffffffffffffff), 0x01000000000000000000000000))\n mstore(add(pos, 116), mul(iszero(iszero(value4)), 0x0100000000000000000000000000000000000000000000000000000000000000))\n end := add(pos, 117)\n }\n function abi_encode_tuple_t_address__to_t_address__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, 0xffffffffffffffffffffffffffffffffffffffff))\n }\n function abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, iszero(iszero(value0)))\n }\n function abi_encode_tuple_t_bytes32__to_t_bytes32__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, value0)\n }\n function abi_encode_tuple_t_bytes32_t_address_payable_t_uint256__to_t_bytes32_t_address_t_uint256__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n tail := add(headStart, 96)\n mstore(headStart, value0)\n mstore(add(headStart, 32), and(value1, 0xffffffffffffffffffffffffffffffffffffffff))\n mstore(add(headStart, 64), value2)\n }\n function abi_encode_tuple_t_bytes32_t_bytes32_t_address__to_t_bytes32_t_bytes32_t_address__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n tail := add(headStart, 96)\n mstore(headStart, value0)\n mstore(add(headStart, 32), value1)\n mstore(add(headStart, 64), and(value2, 0xffffffffffffffffffffffffffffffffffffffff))\n }\n function abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed(headStart, value0) -> tail\n {\n mstore(headStart, 32)\n tail := abi_encode_t_bytes(value0, add(headStart, 32))\n }\n function abi_encode_tuple_t_bytes_storage__to_t_bytes_memory_ptr__fromStack_reversed(headStart, value0) -> tail\n {\n mstore(headStart, 32)\n tail := abi_encode_t_bytes_storage(value0, add(headStart, 32))\n }\n function abi_encode_tuple_t_contract$_IArbitrator_$1736__to_t_address__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, 0xffffffffffffffffffffffffffffffffffffffff))\n }\n function abi_encode_tuple_t_enum$_Status_$95_t_address_t_uint256_t_uint256__to_t_uint8_t_address_t_uint256_t_uint256__fromStack_reversed(headStart, value3, value2, value1, value0) -> tail\n {\n tail := add(headStart, 128)\n if iszero(lt(value0, 4)) { invalid() }\n mstore(headStart, value0)\n mstore(add(headStart, 32), and(value1, 0xffffffffffffffffffffffffffffffffffffffff))\n mstore(add(headStart, 64), value2)\n mstore(add(headStart, 96), value3)\n }\n function abi_encode_tuple_t_string_calldata_ptr__to_t_string_memory_ptr__fromStack_reversed(headStart, value1, value0) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), value1)\n calldatacopy(add(headStart, 64), value0, value1)\n mstore(add(add(headStart, value1), 64), tail)\n tail := add(add(headStart, and(add(value1, 31), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0)), 64)\n }\n function abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack_reversed(headStart, value0) -> tail\n {\n mstore(headStart, 32)\n tail := abi_encode_t_bytes(value0, add(headStart, 32))\n }\n function abi_encode_tuple_t_stringliteral_0345b6b07b3f7ea23ce7c0682ae193a7b3933d232b736d656630025e0007450f__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 46)\n mstore(add(headStart, 64), \"Funding must be made within the \")\n mstore(add(headStart, 96), \"appeal period.\")\n tail := add(headStart, 128)\n }\n function abi_encode_tuple_t_stringliteral_1587ae476a4c91cb27e60192a738172f2d3bd86eda002a76489557322fbcd606__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 23)\n mstore(add(headStart, 64), \"Only arbitrator allowed\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_281e1d87b180850f34e67af4ee84b890763a546671bbe4c68d9b7e0f4b9d0bd4__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 99)\n mstore(add(headStart, 64), \"The hash of the history paramete\")\n mstore(add(headStart, 96), \"rs supplied does not match the o\")\n mstore(add(headStart, 128), \"ne stored in the Realitio contra\")\n mstore(add(headStart, 160), \"ct.\")\n tail := add(headStart, 192)\n }\n function abi_encode_tuple_t_stringliteral_55423884b287f9932d36a37128861bfbe4d8feea42af3dd3ab8bbf80c9ba5cb7__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 29)\n mstore(add(headStart, 64), \"Arbitration already requested\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_7a8ecda55f6cca96c1978f4fd25ea15366a0d0c7eef1b0ddd6bb2039bf48c978__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 14)\n mstore(add(headStart, 64), \"Invalid ruling\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_7b12e68595b54b95620c01e48f1dc5573a4c5ef17b89e01ed1eb1d416d772095__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 27)\n mstore(add(headStart, 64), \"The status should be Ruled.\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_7f704123736d1b3a92e260c8141259bdf1f9f67d73c4011b0e241b32535a29c0__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 31)\n mstore(add(headStart, 64), \"Only governor can execute this.\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_807f252b41bd7d25b9b54c1160c4b1e87b4c73129edc3c10cb4da24c4632a9c3__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 23)\n mstore(add(headStart, 64), \"Answer is out of bounds\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_9591a49cf5d9e3ba9b3aea5505a2b8a639d2f239a0cb6a9059466b60c54a080f__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 23)\n mstore(add(headStart, 64), \"There is no ruling yet.\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_977851d5d407d7cd7d94a1de96a1bef813f7600043d5e83553db2bd20019e46d__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 21)\n mstore(add(headStart, 64), \"No dispute to appeal.\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_aa7d933803aa49666b2a880b5e0ce2616fb839013df37734e6f96b996f511bfc__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 29)\n mstore(add(headStart, 64), \"There is no metaevidence yet.\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_c2f2256a77e1cd7cdc564a3b966df4f3e5bfbdc15f00156637ffbff138e529be__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 33)\n mstore(add(headStart, 64), \"Appeal fee has already been paid\")\n mstore(add(headStart, 96), \".\")\n tail := add(headStart, 128)\n }\n function abi_encode_tuple_t_stringliteral_ca4412daad1a7629a806d6ed5fb65348818aea0846591a9cf2015068ce96fd51__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 45)\n mstore(add(headStart, 64), \"Cannot submit evidence to a reso\")\n mstore(add(headStart, 96), \"lved dispute.\")\n tail := add(headStart, 128)\n }\n function abi_encode_tuple_t_stringliteral_d686c78ed011130263da78637058c22087c97502c2e1ecdc794fbd91e85f16cc__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 89)\n mstore(add(headStart, 64), \"Arbitration cannot be done until\")\n mstore(add(headStart, 96), \" the last answerer has had time \")\n mstore(add(headStart, 128), \"to reveal its commitment.\")\n tail := add(headStart, 160)\n }\n function abi_encode_tuple_t_stringliteral_eff7a83c06f307332f22e019405c9ddb8a5159f654bea9234a3c2d855632b2b1__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 26)\n mstore(add(headStart, 64), \"Invalid arbitration status\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, value0)\n }\n function abi_encode_tuple_t_uint256_t_bytes_storage__to_t_uint256_t_bytes_memory_ptr__fromStack_reversed(headStart, value1, value0) -> tail\n {\n mstore(headStart, value0)\n mstore(add(headStart, 32), 64)\n tail := abi_encode_t_bytes_storage(value1, add(headStart, 64))\n }\n function abi_encode_tuple_t_uint256_t_uint256__to_t_uint256_t_uint256__fromStack_reversed(headStart, value1, value0) -> tail\n {\n tail := add(headStart, 64)\n mstore(headStart, value0)\n mstore(add(headStart, 32), value1)\n }\n function abi_encode_tuple_t_uint256_t_uint256_t_uint256_t_uint256__to_t_uint256_t_uint256_t_uint256_t_uint256__fromStack_reversed(headStart, value3, value2, value1, value0) -> tail\n {\n tail := add(headStart, 128)\n mstore(headStart, value0)\n mstore(add(headStart, 32), value1)\n mstore(add(headStart, 64), value2)\n mstore(add(headStart, 96), value3)\n }\n function array_dataslot_t_bytes_storage(ptr) -> data\n {\n mstore(data, ptr)\n data := keccak256(data, 0x20)\n }\n function validator_revert_t_address(value)\n {\n if iszero(eq(value, and(value, 0xffffffffffffffffffffffffffffffffffffffff))) { revert(0, 0) }\n }\n function validator_revert_t_bool(value)\n {\n if iszero(eq(value, iszero(iszero(value)))) { revert(0, 0) }\n }\n}", + "id": 10, + "language": "Yul", + "name": "#utility.yul" + } + ], + "sourceMap": "1135:4549:4:-:0;;;1879:36:2;;;-1:-1:-1;;;;;;1879:36:2;1905:10;1879:36;;;2479:4;2440:43;;2634:4;2596:42;;2795:4;2750:49;;1557:247:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6169:20:2;-1:-1:-1;;;;;6169:20:2;;;;;6199;;1745:9:4;;1756;;1767:11;;1780:20;;6199::2;;:8;;:20;;;;;:::i;:::-;-1:-1:-1;6229:24:2;-1:-1:-1;;;;;6229:24:2;;;;;6263:42;;;;:19;;:42;;;;;:::i;:::-;;6005:307;;;;1557:247:4;;;;1135:4549;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1135:4549:4;;;-1:-1:-1;1135:4549:4;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:768:10;;-1:-1:-1;;;;;162:2:10;154:6;151:14;148:2;;;168:9;148:2;208;202:9;230:4;304:2;281:17;;-1:-1:-1;;277:31:10;265:44;;261:53;;329:18;;;349:22;;;326:46;323:2;;;375:9;323:2;406:10;402:2;395:22;;435:6;426:15;;465:6;457;450:22;505:3;496:6;491:3;487:16;484:25;481:2;;;522:1;519;512:12;481:2;544:1;535:10;;554:125;568:6;565:1;562:13;554:125;;;656:11;;;650:18;629:14;;;625:23;;618:51;583:10;;;;554:125;;;697:6;694:1;691:13;688:2;;;764:1;759:2;750:6;742;738:19;734:28;727:39;688:2;;;;101:681;;;;;:::o;787:1144::-;;;;;1000:3;988:9;979:7;975:23;971:33;968:2;;;1022:6;1014;1007:22;968:2;1059:9;1053:16;1078:33;1105:5;1078:33;:::i;:::-;1179:2;1164:18;;1158:25;1130:5;;-1:-1:-1;;;;;;1232:14:10;;;1229:2;;;1264:6;1256;1249:22;1229:2;1307:6;1296:9;1292:22;1282:32;;1352:7;1345:4;1341:2;1337:13;1333:27;1323:2;;1379:6;1371;1364:22;1323:2;1407:79;1478:7;1473:2;1467:9;1462:2;1458;1454:11;1407:79;:::i;:::-;1397:89;;1531:2;1520:9;1516:18;1510:25;1495:40;;1544:35;1571:7;1544:35;:::i;:::-;1651:2;1636:18;;1630:25;1598:7;;-1:-1:-1;1667:16:10;;;1664:2;;;1701:6;1693;1686:22;1664:2;-1:-1:-1;1729:24:10;;1784:4;1776:13;;1772:27;-1:-1:-1;1762:2:10;;1818:6;1810;1803:22;1762:2;1846:79;1917:7;1912:2;1906:9;1901:2;1897;1893:11;1846:79;:::i;:::-;1836:89;;;958:973;;;;;;;:::o;1936:133::-;-1:-1:-1;;;;;2013:31:10;;2003:42;;1993:2;;2059:1;2056;2049:12;1993:2;1983:86;:::o;:::-;1135:4549:4;;;;;;;;;;;;;;;;;;", + "deployedSourceMap": "1135:4549:4:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2750:49:2;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1879:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;1701:32::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;16457:538::-;;;;;;;;;;-1:-1:-1;16457:538:2;;;;;:::i;:::-;;:::i;:::-;;2596:42;;;;;;;;;;;;;:::i;9425:1074::-;;;;;;;;;;-1:-1:-1;9425:1074:2;;;;;:::i;:::-;;:::i;18917:826::-;;;;;;;;;;-1:-1:-1;18917:826:2;;;;;:::i;:::-;;:::i;1970:31::-;;;;;;;;;;;;;:::i;13860:365::-;;;;;;;;;;-1:-1:-1;13860:365:2;;;;;:::i;:::-;;:::i;11127:2042::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;4786:65::-;;;;;;;;;;-1:-1:-1;4786:65:2;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;1630:39::-;;;;;;;;;;;;;:::i;2058:34::-;;;;;;;;;;;;;:::i;15366:397::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;2440:43::-;;;;;;;;;;;;;:::i;17802:520::-;;;;;;;;;;-1:-1:-1;17802:520:2;;;;;:::i;:::-;;:::i;14377:135::-;;;;;;;;;;-1:-1:-1;14377:135:2;;;;;:::i;:::-;;:::i;7187:184::-;;;;;;;;;;-1:-1:-1;7187:184:2;;;;;:::i;:::-;;:::i;14682:148::-;;;;;;;;;;-1:-1:-1;14682:148:2;;;;;:::i;:::-;;:::i;6490:425::-;;;;;;;;;;-1:-1:-1;6490:425:2;;;;;:::i;:::-;;:::i;7719:1439::-;;;;;;:::i;:::-;;:::i;1544:42::-;;;;;;;;;;;;;:::i;4923:63::-;;;;;;;;;;-1:-1:-1;4923:63:2;;;;;:::i;:::-;;:::i;20153:889::-;;;;;;;;;;-1:-1:-1;20153:889:2;;;;;:::i;:::-;;:::i;2626:1062:4:-;;;;;;;;;;-1:-1:-1;2626:1062:4;;;;;:::i;:::-;;:::i;13300:102:2:-;;;;;;;;;;-1:-1:-1;13300:102:2;;;;;:::i;:::-;;:::i;2997:54::-;;;;;;;;;;;;;:::i;710:40:5:-;;;;;;;;;;;;;:::i;2750:49:2:-;;;;:::o;1879:36::-;;;;;;:::o;1701:32::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;16457:538::-;16643:45;16691:32;;;:19;:32;;;;;16754:25;;;:32;16691;;16797:192;16841:10;16827:11;:24;16797:192;;;16882:96;16923:11;16936:12;16950:11;16963:14;16882:40;:96::i;:::-;16853:13;;16797:192;;;;16457:538;;;;;:::o;2596:42::-;;;;:::o;9425:1074::-;9502:18;9523:31;;;:19;:31;;;;;;;;;9612;;;:19;:31;;;;;;9674:10;9662:37;9689:10;9662:37;;9654:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;3141:21;9745:35;;;9737:62;;;;;;;;;;;;:::i;:::-;9846:15;9817:25;;;;:44;;;;;;;;;9809:83;;;;;;;;;;;;:::i;:::-;9925:25;;;9951:32;;9903:19;;9925:25;9951:36;;;;9925:63;;;;;;;;;;;;;;;;9903:85;;10159:19;10182:5;:19;;:26;;;;10212:1;10182:31;10181:68;;10242:7;10181:68;;;10217:5;:19;;10237:1;10217:22;;;;;;;;;;;;;;;;10181:68;10260:25;;;;:39;;;10309:40;;;;;;;10390:56;;10260:39;;-1:-1:-1;10422:10:2;;10409;;10390:56;;;;10260:39;;10390:56;:::i;:::-;;;;;;;;9425:1074;;;;;;:::o;18917:826::-;19102:14;19176:32;;;:19;:32;;;;;19241:25;;;:39;;19102:14;;19241:25;19267:12;;19241:39;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19327:15:2;19299:25;;;;:43;;;;;;;;;19291:79;;;;;;;;;;;;:::i;:::-;19390:78;19412:5;19419:12;19433:7;19442:18;:25;;;19390:21;:78::i;:::-;19381:87;-1:-1:-1;19483:11:2;;19479:258;;19510:33;;;19555:1;19510:33;;;:19;;;:33;;;;;;;;:42;;;;;;;;;:46;;;19570:25;;;;;;19588:6;;19570:25;;19555:1;19570:25;19588:6;19510:33;19570:25;;;;;;;;19705:12;19658:68;;19682:12;19669:11;19658:68;19696:7;19719:6;19658:68;;;;;;;:::i;:::-;;;;;;;;19479:258;18917:826;;;;;;;;:::o;1970:31::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13860:365;5603:8;;;;5589:10;:22;5581:66;;;;;;;;;;;;:::i;:::-;14050:21:::1;:46:::0;;;;14106:20:::1;:44:::0;14160:27:::1;:58:::0;13860:365::o;11127:2042::-;11220:16;3141:21;11256:35;;;11248:71;;;;;;;;;;;;:::i;:::-;11329:45;11377:32;;;:19;:32;;;;;11439:28;;;;;;11485:25;;;;:44;;;;;;;;;11477:78;;;;;;;;;;;;:::i;:::-;11590:35;;;;;11566:21;;11590:24;:10;:24;;;;:35;;11615:9;;11590:35;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11566:59;;11636:52;11654:9;11665:7;11674:13;11636:17;:52::i;:::-;11699:20;11721:17;11742:45;11753:9;11764:7;11773:13;11742:10;:45::i;:::-;11823:25;;;:32;;11698:89;;-1:-1:-1;11698:89:2;;-1:-1:-1;11823:36:2;;;;11798:22;;11823:25;:36;;11895:41;;;;;;;;;;;;;;11955:26;;;:17;11895:41;;;;;11955:17;;;:26;;;;;;;11895:41;;-1:-1:-1;11955:26:2;;11954:27;11946:73;;;;;;;;;;;;:::i;:::-;12030:20;12070:27;;;;;;;;;;;12101:9;;12053:45;;:9;;:16;:45::i;:::-;:57;:117;;12142:18;:27;;;;;;;;;;;12125:45;;:9;;:16;:45::i;:::-;12053:117;;;12113:9;12053:117;12030:140;;12236:10;12185:76;;12211:14;12198:11;12185:76;12227:7;12248:12;12185:76;;;;;;;:::i;:::-;;;;;;;;12296:10;12272:35;;;;:23;;;:35;;;;;;;;:44;;;;;;;;:60;;;;;;12342:27;;;;;;:43;;;;;;;;12400:40;-1:-1:-1;12396:289:2;;12480:18;:27;;;;;;;;;;;;12456:20;;;:51;;;;;;;12521:23;;;:37;;-1:-1:-1;12521:37:2;;;;;;;;;;;;;;;12572:26;;;:17;;;:26;;;;;;:33;;;;;;;;;;12624:50;12499:7;;12650:14;;12637:11;;12624:50;;;12396:289;12699:23;;;:30;12733:1;12699:35;12695:322;;;12811:25;;;;:32;;;;;;-1:-1:-1;12811:32:2;12881:20;;;:41;;12909:12;12881:27;:41::i;:::-;12858:20;;;:64;12936:70;;;;;:17;:10;:17;;;;12961:12;;12936:70;;12975:9;;12986:19;;12936:70;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12695:322;13027:10;:47;13043:30;:9;13060:12;13043:16;:30::i;:::-;13027:47;;;;;;;;;;;;;;;;-1:-1:-1;;;13136:26:2;;;;:17;;;;:26;;-1:-1:-1;;13136:26:2;;;;;;;;-1:-1:-1;;;;;;;;11127:2042:2;;;;;:::o;4786:65::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;1630:39::-;;;:::o;2058:34::-;;;;:::o;15366:397::-;15659:21;;15682:20;;15704:27;;3046:5;15366:397;;;;:::o;2440:43::-;;;;:::o;17802:520::-;18056:21;;18022:31;18087:229;18145:23;18124:18;:44;18087:229;;;18206:99;18229:11;18242:12;18256;18270:14;18285:18;18270:34;;;;;;;;;;;;;;18206:22;:99::i;:::-;-1:-1:-1;18170:20:2;;18087:229;;14377:135;-1:-1:-1;3141:21:2;;14377:135::o;7187:184::-;5603:8;;;;5589:10;:22;5581:66;;;;;;;;;;;;:::i;:::-;7298:19:::1;;7285:48;7319:13;;7285:48;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1::0;;7343:19:2::1;:21:::0;;::::1;;::::0;;7187:184::o;14682:148::-;14776:47;;;;;14746:11;;14776:26;:10;:26;;;;:47;;14746:11;;14776:47;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;6490:425::-;6593:45;6641:32;;;:19;:32;;;;;6719:12;6691:25;;;;:40;;;;;;;;;6683:98;;;;;;;;;;;;:::i;:::-;6830:10;6796:59;;6817:11;6805:10;6796:59;;;6842:12;;6796:59;;;;;;;:::i;:::-;;;;;;;;6490:425;;;;:::o;7719:1439::-;7816:17;7875:1;7853:19;;:23;7845:65;;;;;;;;;;;;:::i;:::-;7921:45;7969:41;;;:19;:41;;;;;;8028:25;;;;:40;;;;;;;;;8020:82;;;;;;;;;;;;:::i;:::-;8164:47;;;;;8138:23;;8164:26;:10;:26;;;;:47;;8138:23;;8164:47;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8233:95;;;;;8138:73;;-1:-1:-1;8233:24:2;:10;:24;;;;8138:73;;8233:95;;3141:21;;8308:19;;8233:95;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8221:107;;8363:9;8351:10;8343:77;;;8396:1;8374:19;;:23;8407:11;8399:20;;;8343:77;;;;;;;:::i;:::-;;;;;;;;8517:9;8495:45;8528:11;8495:45;;;;;;:::i;:::-;;;;;;;;8643:30;;;;:19;:30;;;;;;:53;;;8740:40;;-1:-1:-1;8740:40:2;;;;8770:10;8740:40;;;;;;;8790:43;;;;;;8843:28;;;:40;;;8893:25;;;:32;;;;;;;;;8963:89;;;;:50;8977:8;8963:50;;;;:89;;8643:53;;9039:12;;8963:89;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9063:10:2;;-1:-1:-1;9063:50:2;;-1:-1:-1;9079:33:2;;-1:-1:-1;9079:9:2;9096:15;9079:16;:33::i;:::-;9063:50;;;;;;;;;;;;;;;;;;;;;;7719:1439;;;;;;:::o;1544:42::-;;;:::o;4923:63::-;;;;;;;;;;;;;:::o;20153:889::-;20335:11;20406:32;;;:19;:32;;;;;20480:12;20452:25;;;;:40;;;;;;;;;20448:54;;;20501:1;20494:8;;;;;20448:54;20533:25;;;:32;20597:25;;;;20512:18;20633:403;20677:10;20663:11;:24;20633:403;;;20718:19;20740:18;:25;;20766:11;20740:38;;;;;;;;;;;;;;;;;;20718:60;;20797:26;20792:234;20850:14;:21;20829:18;:42;20792:234;;;20920:91;20942:5;20949:12;20963:14;20978:18;20963:34;;;;;;;;;;;;;;20999:11;20920:21;:91::i;:::-;20913:98;;;;20873:20;;20792:234;;;-1:-1:-1;;20689:13:2;;20633:403;;;;20153:889;;;;;;;;;:::o;2626:1062:4:-;2881:45;2929:41;;;:19;:41;;;;;3017:12;2988:25;;;;:41;;;;;;;;;2980:81;;;;;;;;;;;;:::i;:::-;3162:16;3180:25;3207:9;3218:13;3233;3145:102;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;3135:113;;;;;;3094:8;3079:39;;;3119:11;3079:52;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:169;3071:281;;;;;;;;;;;;:::i;:::-;3491:8;3476:49;;;3526:11;3575:1;3547:18;:25;;;:29;3539:38;;3579:101;3593:18;3613:25;3640:9;3651:13;3666;3579;:101::i;:::-;3476:205;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2626:1062;;;;;;;:::o;13300:102:2:-;5603:8;;;;5589:10;:22;5581:66;;;;;;;;;;;;:::i;:::-;13375:8:::1;:20:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;13300:102::o;2997:54::-;3046:5;2997:54;:::o;710:40:5:-;;;;;;;;;;;;;;;;;;;:::o;21478:1270:2:-;21660:14;21691:30;;;:14;;;:30;;;;;;;;21686:1056;;-1:-1:-1;21832:34:2;;;;;;;:20;;;:34;;;;;;;;:50;;;;;;;;;21686:1056;;;21996:12;21978:14;:30;21974:758;;;22133:1;22099:31;;;;;;;;;;;:148;;22246:1;22099:148;;;22212:15;:31;;;;;;;;;;;;22191:17;;;;22138:34;;;;;:20;;;:34;;;;;:50;;;;;;;;;:70;22212:31;22137:106;;;;;22099:148;22090:157;;21974:758;;;22272:20;;;:27;22303:1;-1:-1:-1;22272:32:2;;;:65;;-1:-1:-1;22309:28:2;;;;:14;;;:28;;;;;;;;22308:29;22272:65;22268:464;;;22676:6;:15;;:40;22692:6;:20;;22713:1;22692:23;;;;;;;;;;;;;;;;22676:40;;;;;;;;;;;;22633:6;:15;;:40;22649:6;:20;;22670:1;22649:23;;;;;;;;;;;;;;;;;;;;22633:40;;;;;;;;;;;;;;;;22611:17;;;;22558:34;;;;;:20;;;:34;;;;;:50;;;;;;;;;;22633:83;;;22558:70;22633:83;22557:160;;;;;22548:169;;22268:464;21478:1270;;;;;;:::o;24177:669::-;24320:21;24343:19;24366:10;:23;;;24390:10;24366:35;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;24319:82;;;;24434:7;24416:14;:25;24412:428;;;24484:13;24465:15;:32;;:65;;;;;24519:11;24501:15;:29;24465:65;24457:124;;;;;;;;;;;;:::i;:::-;24412:428;;;24639:13;24620:15;:32;;:158;;;;;3046:5;24724:27;;24707:13;24693:11;:27;24692:59;24691:86;;;;;;24675:13;:102;24656:15;:122;24620:158;24612:217;;;;;;;;;;;;:::i;:::-;24177:669;;;;;:::o;23239:522::-;23373:20;23395;23427:18;23470:14;23459:7;:25;23455:113;;;-1:-1:-1;23499:21:2;;23455:113;;;-1:-1:-1;23548:20:2;;23455:113;23599:54;;;;;23579:17;;23599:21;:10;:21;;;;:54;;23621:10;;23579:17;;23599:54;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;23579:74;-1:-1:-1;23579:74:2;23682:71;3046:5;23699:28;23579:74;23716:10;23699:16;:28::i;:::-;:53;;;;;23682:9;;23699:53;;23682:16;:71::i;:::-;23663:91;;;;;;23239:522;;;;;;:::o;699:154:9:-;756:4;781:2;776;:7;772:74;;;-1:-1:-1;804:1:9;797:8;;772:74;-1:-1:-1;839:7:9;;;832:14;;4480:1202:4;4717:14;;;4800;4796:748;;-1:-1:-1;4918:5:4;4796:748;;;4944:13;4940:604;;;4974:15;4991;5008:22;5049:8;5034:36;;;5071:25;5034:63;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4973:124;;;;;;5115:10;5111:323;;;5158:14;5145:27;;5203:4;5190:17;;5111:323;;;5273:15;5254:35;;:8;:35;;;;5246:137;;;;;;;;;;;;:::i;:::-;5414:5;5401:18;;5111:323;4940:604;;;;;;-1:-1:-1;5477:25:4;;-1:-1:-1;5529:4:4;4940:604;5561:10;:67;;;;-1:-1:-1;5597:26:4;;;;:30;;5575:53;;5561:67;:114;;5647:28;;;;;;;5561:114;;;5631:13;5561:114;5554:121;4480:1202;-1:-1:-1;;;;;;;;4480:1202:4:o;952:403:9:-;1009:4;1248:7;1244:33;;-1:-1:-1;1276:1:9;1269:8;;1244:33;1297:7;;;1302:2;1297;:7;:2;1321:6;;;;;:12;:27;;378:10;1321:27;;482:135;539:4;564:7;;;588;;;;:22;;378:10;588:22;;14:908:10;;127:3;120:4;112:6;108:17;104:27;94:2;;149:5;142;135:20;94:2;189:6;176:20;215:4;238:18;275:2;271;268:10;265:2;;;281:9;265:2;319;315;311:11;351:2;345:9;402:2;397;389:6;385:15;381:24;455:6;443:10;440:22;435:2;423:10;420:18;417:46;414:2;;;466:9;414:2;493;486:22;543:18;;;577:15;;;;-1:-1:-1;612:15:10;;;646;;;642:24;;639:33;-1:-1:-1;636:2:10;;;689:5;682;675:20;636:2;715:5;706:14;;729:163;743:2;740:1;737:9;729:163;;;800:17;;788:30;;838:12;;;;761:1;754:9;;;;;870:12;;729:163;;;-1:-1:-1;910:6:10;84:838;-1:-1:-1;;;;;;;84:838:10:o;927:378::-;;;1045:3;1038:4;1030:6;1026:17;1022:27;1012:2;;1070:8;1060;1053:26;1012:2;-1:-1:-1;1100:20:10;;1143:18;1132:30;;1129:2;;;1182:8;1172;1165:26;1129:2;1226:4;1218:6;1214:17;1202:29;;1278:3;1271:4;1262:6;1254;1250:19;1246:30;1243:39;1240:2;;;1295:1;1292;1285:12;1240:2;1002:303;;;;;:::o;1310:259::-;;1422:2;1410:9;1401:7;1397:23;1393:32;1390:2;;;1443:6;1435;1428:22;1390:2;1487:9;1474:23;1506:33;1533:5;1506:33;:::i;1574:190::-;;1686:2;1674:9;1665:7;1661:23;1657:32;1654:2;;;1707:6;1699;1692:22;1654:2;-1:-1:-1;1735:23:10;;1644:120;-1:-1:-1;1644:120:10:o;1769:194::-;;1892:2;1880:9;1871:7;1867:23;1863:32;1860:2;;;1913:6;1905;1898:22;1860:2;-1:-1:-1;1941:16:10;;1850:113;-1:-1:-1;1850:113:10:o;1968:671::-;;;;;;;2162:3;2150:9;2141:7;2137:23;2133:33;2130:2;;;2184:6;2176;2169:22;2130:2;2225:9;2212:23;2202:33;;2282:2;2271:9;2267:18;2254:32;2244:42;;2333:2;2322:9;2318:18;2305:32;2295:42;;2384:2;2373:9;2369:18;2356:32;2346:42;;2438:3;2427:9;2423:19;2410:33;2452;2479:5;2452:33;:::i;:::-;2504:5;-1:-1:-1;2561:3:10;2546:19;;2533:33;2575:32;2533:33;2575:32;:::i;:::-;2626:7;2616:17;;;2120:519;;;;;;;;:::o;2644:258::-;;;2773:2;2761:9;2752:7;2748:23;2744:32;2741:2;;;2794:6;2786;2779:22;2741:2;-1:-1:-1;;2822:23:10;;;2892:2;2877:18;;;2864:32;;-1:-1:-1;2731:171:10:o;2907:433::-;;;3039:2;3027:9;3018:7;3014:23;3010:32;3007:2;;;3060:6;3052;3045:22;3007:2;3105:9;3092:23;3138:18;3130:6;3127:30;3124:2;;;3175:6;3167;3160:22;3124:2;3219:61;3272:7;3263:6;3252:9;3248:22;3219:61;:::i;:::-;3299:8;;3193:87;;-1:-1:-1;2997:343:10;-1:-1:-1;;;;2997:343:10:o;3739:587::-;;;;3918:2;3906:9;3897:7;3893:23;3889:32;3886:2;;;3939:6;3931;3924:22;3886:2;3980:9;3967:23;3957:33;;4040:2;4029:9;4025:18;4012:32;4053:33;4080:5;4053:33;:::i;:::-;4105:5;-1:-1:-1;4161:2:10;4146:18;;4133:32;4188:18;4177:30;;4174:2;;;4225:6;4217;4210:22;4174:2;4253:67;4312:7;4303:6;4292:9;4288:22;4253:67;:::i;:::-;4243:77;;;3876:450;;;;;:::o;4331:656::-;;;;;4527:3;4515:9;4506:7;4502:23;4498:33;4495:2;;;4549:6;4541;4534:22;4495:2;4590:9;4577:23;4567:33;;4650:2;4639:9;4635:18;4622:32;4663:33;4690:5;4663:33;:::i;:::-;4715:5;-1:-1:-1;4767:2:10;4752:18;;4739:32;;-1:-1:-1;4822:2:10;4807:18;;4794:32;4849:18;4838:30;;4835:2;;;4886:6;4878;4871:22;4835:2;4914:67;4973:7;4964:6;4953:9;4949:22;4914:67;:::i;:::-;4904:77;;;4485:502;;;;;;;:::o;4992:472::-;;;;;5163:3;5151:9;5142:7;5138:23;5134:33;5131:2;;;5185:6;5177;5170:22;5131:2;5226:9;5213:23;5203:33;;5286:2;5275:9;5271:18;5258:32;5299:33;5326:5;5299:33;:::i;:::-;5121:343;;5351:5;;-1:-1:-1;;;;5403:2:10;5388:18;;5375:32;;5454:2;5439:18;5426:32;;5121:343::o;5469:501::-;;;;5618:2;5606:9;5597:7;5593:23;5589:32;5586:2;;;5639:6;5631;5624:22;5586:2;5680:9;5667:23;5657:33;;5741:2;5730:9;5726:18;5713:32;5768:18;5760:6;5757:30;5754:2;;;5805:6;5797;5790:22;5754:2;5849:61;5902:7;5893:6;5882:9;5878:22;5849:61;:::i;:::-;5576:394;;5929:8;;-1:-1:-1;5823:87:10;;-1:-1:-1;;;;5576:394:10:o;6238:255::-;;;6378:2;6366:9;6357:7;6353:23;6349:32;6346:2;;;6399:6;6391;6384:22;6346:2;-1:-1:-1;;6427:16:10;;6483:2;6468:18;;;6462:25;6427:16;;6462:25;;-1:-1:-1;6336:157:10:o;6498:326::-;;;;6644:2;6632:9;6623:7;6619:23;6615:32;6612:2;;;6665:6;6657;6650:22;6612:2;-1:-1:-1;;6693:23:10;;;6763:2;6748:18;;6735:32;;-1:-1:-1;6814:2:10;6799:18;;;6786:32;;6602:222;-1:-1:-1;6602:222:10:o;6829:491::-;;;;6982:2;6970:9;6961:7;6957:23;6953:32;6950:2;;;7003:6;6995;6988:22;6950:2;7040:9;7034:16;7090:10;7083:5;7079:22;7072:5;7069:33;7059:2;;7121:6;7113;7106:22;7059:2;7199;7184:18;;7178:25;7149:5;;-1:-1:-1;7212:32:10;7178:25;7212:32;:::i;:::-;7263:7;7253:17;;;7310:2;7299:9;7295:18;7289:25;7279:35;;6940:380;;;;;:::o;7325:536::-;;7406:5;7400:12;7433:6;7428:3;7421:19;7458:3;7470:162;7484:6;7481:1;7478:13;7470:162;;;7546:4;7602:13;;;7598:22;;7592:29;7574:11;;;7570:20;;7563:59;7499:12;7470:162;;;7650:6;7647:1;7644:13;7641:2;;;7716:3;7709:4;7700:6;7695:3;7691:16;7687:27;7680:40;7641:2;-1:-1:-1;7775:2:10;7763:15;7780:66;7759:88;7750:98;;;;7850:4;7746:109;;7376:485;-1:-1:-1;;7376:485:10:o;7866:814::-;;7958:5;7952:12;7983:1;8015:2;8004:9;8000:18;8032:1;8027:223;;;;8264:1;8259:415;;;;7993:681;;8027:223;8083:4;8079:1;8068:9;8064:17;8060:28;8055:3;8048:41;8140:66;8129:9;8125:82;8118:4;8113:3;8109:14;8102:106;8237:2;8232:3;8228:12;8221:19;;8027:223;;8259:415;8309:1;8298:9;8294:17;8336:6;8331:3;8324:19;8371:37;8402:5;8371:37;:::i;:::-;8430:1;8444:178;8458:6;8455:1;8452:13;8444:178;;;8555:7;8549:14;8542:4;8538:1;8533:3;8529:11;8525:22;8518:46;8605:2;8596:7;8592:16;8581:27;;8480:4;8477:1;8473:12;8468:17;;8444:178;;;8646:11;;8659:4;8642:22;;-1:-1:-1;;;7993:681:10;;;;7925:755;;;;:::o;8685:611::-;8920:19;;;8964:2;8955:12;;8948:28;;;;9001:2;8992:12;;8985:28;;;;9059:42;9047:55;9104:28;9043:90;9038:2;9029:12;;9022:112;9176:14;9169:22;9193:66;9165:95;9159:3;9150:13;;9143:118;9286:3;9277:13;;8910:386::o;9301:226::-;9477:42;9465:55;;;;9447:74;;9435:2;9420:18;;9402:125::o;9532:187::-;9697:14;;9690:22;9672:41;;9660:2;9645:18;;9627:92::o;9724:177::-;9870:25;;;9858:2;9843:18;;9825:76::o;9906:376::-;10116:25;;;10189:42;10177:55;;;;10172:2;10157:18;;10150:83;10264:2;10249:18;;10242:34;10104:2;10089:18;;10071:211::o;10287:368::-;10489:25;;;10545:2;10530:18;;10523:34;;;;10605:42;10593:55;10588:2;10573:18;;10566:83;10477:2;10462:18;;10444:211::o;10660:219::-;;10807:2;10796:9;10789:21;10827:46;10869:2;10858:9;10854:18;10846:6;10827:46;:::i;10884:224::-;;11028:2;11017:9;11010:21;11048:54;11098:2;11087:9;11083:18;11075:6;11048:54;:::i;11364:494::-;11589:3;11574:19;;11623:1;11612:13;;11602:2;;11629:9;11602:2;11649:25;;;11722:42;11710:55;;;;11705:2;11690:18;;11683:83;11797:2;11782:18;;11775:34;;;;11840:2;11825:18;;;11818:34;11556:302;:::o;11863:452::-;;12022:2;12011:9;12004:21;12061:6;12056:2;12045:9;12041:18;12034:34;12118:6;12110;12105:2;12094:9;12090:18;12077:48;12145:22;;;12169:2;12141:31;;;12134:45;;;;12231:2;12219:15;;;12236:66;12215:88;12200:104;12196:113;;11994:321;-1:-1:-1;11994:321:10:o;12546:410::-;12748:2;12730:21;;;12787:2;12767:18;;;12760:30;12826:34;12821:2;12806:18;;12799:62;12897:16;12892:2;12877:18;;12870:44;12946:3;12931:19;;12720:236::o;12961:347::-;13163:2;13145:21;;;13202:2;13182:18;;;13175:30;13241:25;13236:2;13221:18;;13214:53;13299:2;13284:18;;13135:173::o;13313:543::-;13515:2;13497:21;;;13554:2;13534:18;;;13527:30;13593:34;13588:2;13573:18;;13566:62;13664:34;13659:2;13644:18;;13637:62;13736:34;13730:3;13715:19;;13708:63;13808:5;13802:3;13787:19;;13780:34;13846:3;13831:19;;13487:369::o;13861:353::-;14063:2;14045:21;;;14102:2;14082:18;;;14075:30;14141:31;14136:2;14121:18;;14114:59;14205:2;14190:18;;14035:179::o;14219:338::-;14421:2;14403:21;;;14460:2;14440:18;;;14433:30;14499:16;14494:2;14479:18;;14472:44;14548:2;14533:18;;14393:164::o;14562:351::-;14764:2;14746:21;;;14803:2;14783:18;;;14776:30;14842:29;14837:2;14822:18;;14815:57;14904:2;14889:18;;14736:177::o;14918:355::-;15120:2;15102:21;;;15159:2;15139:18;;;15132:30;15198:33;15193:2;15178:18;;15171:61;15264:2;15249:18;;15092:181::o;15278:347::-;15480:2;15462:21;;;15519:2;15499:18;;;15492:30;15558:25;15553:2;15538:18;;15531:53;15616:2;15601:18;;15452:173::o;15630:347::-;15832:2;15814:21;;;15871:2;15851:18;;;15844:30;15910:25;15905:2;15890:18;;15883:53;15968:2;15953:18;;15804:173::o;15982:345::-;16184:2;16166:21;;;16223:2;16203:18;;;16196:30;16262:23;16257:2;16242:18;;16235:51;16318:2;16303:18;;16156:171::o;16332:353::-;16534:2;16516:21;;;16573:2;16553:18;;;16546:30;16612:31;16607:2;16592:18;;16585:59;16676:2;16661:18;;16506:179::o;16690:397::-;16892:2;16874:21;;;16931:2;16911:18;;;16904:30;16970:34;16965:2;16950:18;;16943:62;17041:3;17036:2;17021:18;;17014:31;17077:3;17062:19;;16864:223::o;17092:409::-;17294:2;17276:21;;;17333:2;17313:18;;;17306:30;17372:34;17367:2;17352:18;;17345:62;17443:15;17438:2;17423:18;;17416:43;17491:3;17476:19;;17266:235::o;17506:493::-;17708:2;17690:21;;;17747:2;17727:18;;;17720:30;17786:34;17781:2;17766:18;;17759:62;17857:34;17852:2;17837:18;;17830:62;17929:27;17923:3;17908:19;;17901:56;17989:3;17974:19;;17680:319::o;18004:350::-;18206:2;18188:21;;;18245:2;18225:18;;;18218:30;18284:28;18279:2;18264:18;;18257:56;18345:2;18330:18;;18178:176::o;18541:295::-;;18713:6;18702:9;18695:25;18756:2;18751;18740:9;18736:18;18729:30;18776:54;18826:2;18815:9;18811:18;18803:6;18776:54;:::i;18841:248::-;19015:25;;;19071:2;19056:18;;19049:34;19003:2;18988:18;;18970:119::o;19094:391::-;19325:25;;;19381:2;19366:18;;19359:34;;;;19424:2;19409:18;;19402:34;19467:2;19452:18;;19445:34;19312:3;19297:19;;19279:206::o;19490:128::-;;19557:17;;;19607:4;19591:21;;;19547:71::o;19623:156::-;19711:42;19704:5;19700:54;19693:5;19690:65;19680:2;;19769:1;19766;19759:12;19680:2;19670:109;:::o;19784:120::-;19872:5;19865:13;19858:21;19851:5;19848:32;19838:2;;19894:1;19891;19884:12", + "source": "// SPDX-License-Identifier: MIT\n\n/**\n * @authors: [@ferittuncer]\n * @reviewers: [@unknownunknown1*, @hbarcelos*, @MerlinEgalite*]\n * @auditors: []\n * @bounties: []\n * @deployments: []\n */\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./IRealitio_v2_0.sol\";\nimport \"../RealitioArbitratorWithAppealsBase.sol\";\n\n/**\n * @title Realitio_v2_0_ArbitratorWithAppeals\n * @dev A Realitio arbitrator implementation that uses Realitio v2.0 and Kleros. It notifies Realitio contract for arbitration requests and creates corresponding dispute on Kleros. Transmits Kleros ruling to Realitio contract. Maintains crowdfunded appeals and notifies Kleros contract. Provides a function to submit evidence for Kleros dispute.\n * There is a conversion between Kleros ruling and Realitio answer and there is a need for shifting by 1. This is because ruling 0 in Kleros signals tie or no-ruling but in Realitio 0 is a valid answer. For reviewers this should be a focus as it's quite easy to get confused. Any mistakes on this conversion will render this contract useless.\n * NOTE: This contract trusts the Kleros arbitrator and Realitio.\n */\ncontract Realitio_v2_0_ArbitratorWithAppeals is RealitioArbitratorWithAppealsBase {\n /** @dev Constructor.\n * @param _realitio The address of the Realitio contract.\n * @param _metadata The metadata required for RealitioArbitrator.\n * @param _arbitrator The address of the ERC792 arbitrator.\n * @param _arbitratorExtraData The extra data used to raise a dispute in the ERC792 arbitrator.\n */\n constructor(\n address _realitio,\n string memory _metadata,\n IArbitrator _arbitrator,\n bytes memory _arbitratorExtraData\n ) RealitioArbitratorWithAppealsBase(_realitio, _metadata, _arbitrator, _arbitratorExtraData) {}\n\n /** @dev Compute winner and report the answer to a specified question from the ERC792 arbitrator to the Realitio v2.0 contract. TRUSTED.\n * @param _questionID The ID of the question.\n * @param _lastHistoryHash The history hash given with the last answer to the question in the Realitio contract.\n * @param _lastAnswerOrCommitmentID The last answer given, or its commitment ID if it was a commitment, to the question in the Realitio contract.\n * @param _lastBond The bond paid for the last answer to the question in the Realitio contract.\n * @param _lastAnswerer The last answerer to the question in the Realitio contract.\n * @param _isCommitment Whether the last answer to the question in the Realitio contract used commit or reveal or not. True if it did, false otherwise.\n */\n function computeWinnerAndReportAnswer(\n bytes32 _questionID,\n bytes32 _lastHistoryHash,\n bytes32 _lastAnswerOrCommitmentID,\n uint256 _lastBond,\n address _lastAnswerer,\n bool _isCommitment\n ) external {\n ArbitrationRequest storage arbitrationRequest = arbitrationRequests[uint256(_questionID)];\n require(arbitrationRequest.status == Status.Ruled, \"The status should be Ruled.\");\n require(IRealitio_v2_0(realitio).getHistoryHash(_questionID) == keccak256(abi.encodePacked(_lastHistoryHash, _lastAnswerOrCommitmentID, _lastBond, _lastAnswerer, _isCommitment)), \"The hash of the history parameters supplied does not match the one stored in the Realitio contract.\"); // This is normally Realitio's responsibility to check but it does not, so we do instead. This is fixed in v2.1.\n\n IRealitio_v2_0(realitio).submitAnswerByArbitrator(_questionID, bytes32(arbitrationRequest.answer - 1), computeWinner(arbitrationRequest, _lastAnswerOrCommitmentID, _lastBond, _lastAnswerer, _isCommitment));\n }\n\n /** @dev Computes the Realitio answerer, of a specified question, that should win. This function is needed to avoid the \"stack too deep error\". TRUSTED.\n * @param _arbitrationRequest Arbitration request to compute it's winner.\n * @param _lastAnswerOrCommitmentID The last answer given, or its commitment ID if it was a commitment, to the question in the Realitio contract.\n * @param _lastBond The bond paid for the last answer to the question in the Realitio contract.\n * @param _lastAnswerer The last answerer to the question in the Realitio contract.\n * @param _isCommitment Whether the last answer to the question in the Realitio contract used commit or reveal or not. True if it did, false otherwise.\n * @return winner The computed winner.\n */\n function computeWinner(\n ArbitrationRequest storage _arbitrationRequest,\n bytes32 _lastAnswerOrCommitmentID,\n uint256 _lastBond,\n address _lastAnswerer,\n bool _isCommitment\n ) internal view returns (address winner) {\n bytes32 lastAnswer;\n bool isAnswered;\n if (_lastBond == 0) {\n // If the question hasn't been answered, nobody is ever right.\n isAnswered = false;\n } else if (_isCommitment) {\n (uint32 revealTS, bool isRevealed, bytes32 revealedAnswer) = IRealitio_v2_0(realitio).commitments(_lastAnswerOrCommitmentID);\n if (isRevealed) {\n lastAnswer = revealedAnswer;\n isAnswered = true;\n } else {\n require(revealTS <= uint32(block.timestamp), \"Arbitration cannot be done until the last answerer has had time to reveal its commitment.\");\n isAnswered = false;\n }\n } else {\n lastAnswer = _lastAnswerOrCommitmentID;\n isAnswered = true;\n }\n\n return isAnswered && lastAnswer == bytes32(_arbitrationRequest.answer - 1) ? _lastAnswerer : _arbitrationRequest.disputer;\n }\n}\n", + "sourcePath": "/home/f/repos/realitio-arbitrator-with-appeals/contracts/v2.0/Realitio_v2_0_ArbitratorWithAppeals.sol", + "ast": { + "absolutePath": "/home/f/repos/realitio-arbitrator-with-appeals/contracts/v2.0/Realitio_v2_0_ArbitratorWithAppeals.sol", + "exportedSymbols": { + "CappedMath": [ + 1858 + ], + "IArbitrable": [ + 1644 + ], + "IArbitrator": [ + 1736 + ], + "IDisputeResolver": [ + 1622 + ], + "IEvidence": [ + 1770 + ], + "IRealitioArbitrator": [ + 24 + ], + "IRealitioBase": [ + 38 + ], + "IRealitio_v2_0": [ + 1271 + ], + "RealitioArbitratorWithAppealsBase": [ + 1234 + ], + "Realitio_v2_0_ArbitratorWithAppeals": [ + 1476 + ] + }, + "id": 1477, + "license": "MIT", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1273, + "literals": [ + "solidity", + "^", + "0.7", + ".0" + ], + "nodeType": "PragmaDirective", + "src": "194:23:4" + }, + { + "id": 1274, + "literals": [ + "abicoder", + "v2" + ], + "nodeType": "PragmaDirective", + "src": "218:19:4" + }, + { + "absolutePath": "/home/f/repos/realitio-arbitrator-with-appeals/contracts/v2.0/IRealitio_v2_0.sol", + "file": "./IRealitio_v2_0.sol", + "id": 1275, + "nodeType": "ImportDirective", + "scope": 1477, + "sourceUnit": 1272, + "src": "239:30:4", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/home/f/repos/realitio-arbitrator-with-appeals/contracts/RealitioArbitratorWithAppealsBase.sol", + "file": "../RealitioArbitratorWithAppealsBase.sol", + "id": 1276, + "nodeType": "ImportDirective", + "scope": 1477, + "sourceUnit": 1235, + "src": "270:50:4", + "symbolAliases": [], + "unitAlias": "" + }, + { + "abstract": false, + "baseContracts": [ + { + "baseName": { + "id": 1278, + "name": "RealitioArbitratorWithAppealsBase", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 1234, + "src": "1183:33:4", + "typeDescriptions": { + "typeIdentifier": "t_contract$_RealitioArbitratorWithAppealsBase_$1234", + "typeString": "contract RealitioArbitratorWithAppealsBase" + } + }, + "id": 1279, + "nodeType": "InheritanceSpecifier", + "src": "1183:33:4" + } + ], + "contractDependencies": [ + 24, + 1234, + 1622, + 1644, + 1770 + ], + "contractKind": "contract", + "documentation": { + "id": 1277, + "nodeType": "StructuredDocumentation", + "src": "322:812:4", + "text": " @title Realitio_v2_0_ArbitratorWithAppeals\n @dev A Realitio arbitrator implementation that uses Realitio v2.0 and Kleros. It notifies Realitio contract for arbitration requests and creates corresponding dispute on Kleros. Transmits Kleros ruling to Realitio contract. Maintains crowdfunded appeals and notifies Kleros contract. Provides a function to submit evidence for Kleros dispute.\n There is a conversion between Kleros ruling and Realitio answer and there is a need for shifting by 1. This is because ruling 0 in Kleros signals tie or no-ruling but in Realitio 0 is a valid answer. For reviewers this should be a focus as it's quite easy to get confused. Any mistakes on this conversion will render this contract useless.\n NOTE: This contract trusts the Kleros arbitrator and Realitio." + }, + "fullyImplemented": true, + "id": 1476, + "linearizedBaseContracts": [ + 1476, + 1234, + 24, + 1622, + 1770, + 1644 + ], + "name": "Realitio_v2_0_ArbitratorWithAppeals", + "nodeType": "ContractDefinition", + "nodes": [ + { + "body": { + "id": 1297, + "nodeType": "Block", + "src": "1802:2:4", + "statements": [] + }, + "documentation": { + "id": 1280, + "nodeType": "StructuredDocumentation", + "src": "1223:329:4", + "text": "@dev Constructor.\n @param _realitio The address of the Realitio contract.\n @param _metadata The metadata required for RealitioArbitrator.\n @param _arbitrator The address of the ERC792 arbitrator.\n @param _arbitratorExtraData The extra data used to raise a dispute in the ERC792 arbitrator." + }, + "id": 1298, + "implemented": true, + "kind": "constructor", + "modifiers": [ + { + "arguments": [ + { + "id": 1291, + "name": "_realitio", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1282, + "src": "1745:9:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 1292, + "name": "_metadata", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1284, + "src": "1756:9:4", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + }, + { + "id": 1293, + "name": "_arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1286, + "src": "1767:11:4", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IArbitrator_$1736", + "typeString": "contract IArbitrator" + } + }, + { + "id": 1294, + "name": "_arbitratorExtraData", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1288, + "src": "1780:20:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "id": 1295, + "modifierName": { + "id": 1290, + "name": "RealitioArbitratorWithAppealsBase", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1234, + "src": "1711:33:4", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_RealitioArbitratorWithAppealsBase_$1234_$", + "typeString": "type(contract RealitioArbitratorWithAppealsBase)" + } + }, + "nodeType": "ModifierInvocation", + "src": "1711:90:4" + } + ], + "name": "", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1289, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1282, + "mutability": "mutable", + "name": "_realitio", + "nodeType": "VariableDeclaration", + "scope": 1298, + "src": "1578:17:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 1281, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1578:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1284, + "mutability": "mutable", + "name": "_metadata", + "nodeType": "VariableDeclaration", + "scope": 1298, + "src": "1605:23:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 1283, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "1605:6:4", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1286, + "mutability": "mutable", + "name": "_arbitrator", + "nodeType": "VariableDeclaration", + "scope": 1298, + "src": "1638:23:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IArbitrator_$1736", + "typeString": "contract IArbitrator" + }, + "typeName": { + "id": 1285, + "name": "IArbitrator", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 1736, + "src": "1638:11:4", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IArbitrator_$1736", + "typeString": "contract IArbitrator" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1288, + "mutability": "mutable", + "name": "_arbitratorExtraData", + "nodeType": "VariableDeclaration", + "scope": 1298, + "src": "1671:33:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 1287, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "1671:5:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "1568:142:4" + }, + "returnParameters": { + "id": 1296, + "nodeType": "ParameterList", + "parameters": [], + "src": "1802:0:4" + }, + "scope": 1476, + "src": "1557:247:4", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + }, + { + "body": { + "id": 1374, + "nodeType": "Block", + "src": "2871:817:4", + "statements": [ + { + "assignments": [ + 1315 + ], + "declarations": [ + { + "constant": false, + "id": 1315, + "mutability": "mutable", + "name": "arbitrationRequest", + "nodeType": "VariableDeclaration", + "scope": 1374, + "src": "2881:45:4", + "stateVariable": false, + "storageLocation": "storage", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ArbitrationRequest_$107_storage_ptr", + "typeString": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest" + }, + "typeName": { + "id": 1314, + "name": "ArbitrationRequest", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 107, + "src": "2881:18:4", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ArbitrationRequest_$107_storage_ptr", + "typeString": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest" + } + }, + "visibility": "internal" + } + ], + "id": 1322, + "initialValue": { + "baseExpression": { + "id": 1316, + "name": "arbitrationRequests", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 131, + "src": "2929:19:4", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint256_$_t_struct$_ArbitrationRequest_$107_storage_$", + "typeString": "mapping(uint256 => struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage ref)" + } + }, + "id": 1321, + "indexExpression": { + "arguments": [ + { + "id": 1319, + "name": "_questionID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1301, + "src": "2957:11:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 1318, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "2949:7:4", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + }, + "typeName": { + "id": 1317, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2949:7:4", + "typeDescriptions": {} + } + }, + "id": 1320, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "2949:20:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "2929:41:4", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ArbitrationRequest_$107_storage", + "typeString": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage ref" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "2881:89:4" + }, + { + "expression": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_enum$_Status_$95", + "typeString": "enum RealitioArbitratorWithAppealsBase.Status" + }, + "id": 1328, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 1324, + "name": "arbitrationRequest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1315, + "src": "2988:18:4", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ArbitrationRequest_$107_storage_ptr", + "typeString": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage pointer" + } + }, + "id": 1325, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "status", + "nodeType": "MemberAccess", + "referencedDeclaration": 97, + "src": "2988:25:4", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Status_$95", + "typeString": "enum RealitioArbitratorWithAppealsBase.Status" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "expression": { + "id": 1326, + "name": "Status", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 95, + "src": "3017:6:4", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Status_$95_$", + "typeString": "type(enum RealitioArbitratorWithAppealsBase.Status)" + } + }, + "id": 1327, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "Ruled", + "nodeType": "MemberAccess", + "src": "3017:12:4", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Status_$95", + "typeString": "enum RealitioArbitratorWithAppealsBase.Status" + } + }, + "src": "2988:41:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "546865207374617475732073686f756c642062652052756c65642e", + "id": 1329, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3031:29:4", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_7b12e68595b54b95620c01e48f1dc5573a4c5ef17b89e01ed1eb1d416d772095", + "typeString": "literal_string \"The status should be Ruled.\"" + }, + "value": "The status should be Ruled." + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_7b12e68595b54b95620c01e48f1dc5573a4c5ef17b89e01ed1eb1d416d772095", + "typeString": "literal_string \"The status should be Ruled.\"" + } + ], + "id": 1323, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 4294967278, + 4294967278 + ], + "referencedDeclaration": 4294967278, + "src": "2980:7:4", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 1330, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "2980:81:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1331, + "nodeType": "ExpressionStatement", + "src": "2980:81:4" + }, + { + "expression": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 1349, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "arguments": [ + { + "id": 1337, + "name": "_questionID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1301, + "src": "3119:11:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "arguments": [ + { + "id": 1334, + "name": "realitio", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 56, + "src": "3094:8:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 1333, + "name": "IRealitio_v2_0", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1271, + "src": "3079:14:4", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_IRealitio_v2_0_$1271_$", + "typeString": "type(contract IRealitio_v2_0)" + } + }, + "id": 1335, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3079:24:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_contract$_IRealitio_v2_0_$1271", + "typeString": "contract IRealitio_v2_0" + } + }, + "id": 1336, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "getHistoryHash", + "nodeType": "MemberAccess", + "referencedDeclaration": 1258, + "src": "3079:39:4", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$_t_bytes32_$returns$_t_bytes32_$", + "typeString": "function (bytes32) view external returns (bytes32)" + } + }, + "id": 1338, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3079:52:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "arguments": [ + { + "arguments": [ + { + "id": 1342, + "name": "_lastHistoryHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1303, + "src": "3162:16:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1343, + "name": "_lastAnswerOrCommitmentID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1305, + "src": "3180:25:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1344, + "name": "_lastBond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1307, + "src": "3207:9:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 1345, + "name": "_lastAnswerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1309, + "src": "3218:13:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 1346, + "name": "_isCommitment", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1311, + "src": "3233:13:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "expression": { + "id": 1340, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967295, + "src": "3145:3:4", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 1341, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "src": "3145:16:4", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 1347, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3145:102:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 1339, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967288, + "src": "3135:9:4", + "typeDescriptions": { + "typeIdentifier": "t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) pure returns (bytes32)" + } + }, + "id": 1348, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3135:113:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "3079:169:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "5468652068617368206f662074686520686973746f727920706172616d657465727320737570706c69656420646f6573206e6f74206d6174636820746865206f6e652073746f72656420696e20746865205265616c6974696f20636f6e74726163742e", + "id": 1350, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3250:101:4", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_281e1d87b180850f34e67af4ee84b890763a546671bbe4c68d9b7e0f4b9d0bd4", + "typeString": "literal_string \"The hash of the history parameters supplied does not match the one stored in the Realitio contract.\"" + }, + "value": "The hash of the history parameters supplied does not match the one stored in the Realitio contract." + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_281e1d87b180850f34e67af4ee84b890763a546671bbe4c68d9b7e0f4b9d0bd4", + "typeString": "literal_string \"The hash of the history parameters supplied does not match the one stored in the Realitio contract.\"" + } + ], + "id": 1332, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 4294967278, + 4294967278 + ], + "referencedDeclaration": 4294967278, + "src": "3071:7:4", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 1351, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3071:281:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1352, + "nodeType": "ExpressionStatement", + "src": "3071:281:4" + }, + { + "expression": { + "arguments": [ + { + "id": 1357, + "name": "_questionID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1301, + "src": "3526:11:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1363, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 1360, + "name": "arbitrationRequest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1315, + "src": "3547:18:4", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ArbitrationRequest_$107_storage_ptr", + "typeString": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage pointer" + } + }, + "id": 1361, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "answer", + "nodeType": "MemberAccess", + "referencedDeclaration": 103, + "src": "3547:25:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "hexValue": "31", + "id": 1362, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3575:1:4", + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "3547:29:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 1359, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "3539:7:4", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": { + "id": 1358, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3539:7:4", + "typeDescriptions": {} + } + }, + "id": 1364, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3539:38:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "arguments": [ + { + "id": 1366, + "name": "arbitrationRequest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1315, + "src": "3593:18:4", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ArbitrationRequest_$107_storage_ptr", + "typeString": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage pointer" + } + }, + { + "id": 1367, + "name": "_lastAnswerOrCommitmentID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1305, + "src": "3613:25:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1368, + "name": "_lastBond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1307, + "src": "3640:9:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 1369, + "name": "_lastAnswerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1309, + "src": "3651:13:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 1370, + "name": "_isCommitment", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1311, + "src": "3666:13:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_struct$_ArbitrationRequest_$107_storage_ptr", + "typeString": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage pointer" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 1365, + "name": "computeWinner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1475, + "src": "3579:13:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_struct$_ArbitrationRequest_$107_storage_ptr_$_t_bytes32_$_t_uint256_$_t_address_$_t_bool_$returns$_t_address_$", + "typeString": "function (struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage pointer,bytes32,uint256,address,bool) view returns (address)" + } + }, + "id": 1371, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3579:101:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "expression": { + "arguments": [ + { + "id": 1354, + "name": "realitio", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 56, + "src": "3491:8:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 1353, + "name": "IRealitio_v2_0", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1271, + "src": "3476:14:4", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_IRealitio_v2_0_$1271_$", + "typeString": "type(contract IRealitio_v2_0)" + } + }, + "id": 1355, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3476:24:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_contract$_IRealitio_v2_0_$1271", + "typeString": "contract IRealitio_v2_0" + } + }, + "id": 1356, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "submitAnswerByArbitrator", + "nodeType": "MemberAccess", + "referencedDeclaration": 1250, + "src": "3476:49:4", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_bytes32_$_t_bytes32_$_t_address_$returns$__$", + "typeString": "function (bytes32,bytes32,address) external" + } + }, + "id": 1372, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3476:205:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1373, + "nodeType": "ExpressionStatement", + "src": "3476:205:4" + } + ] + }, + "documentation": { + "id": 1299, + "nodeType": "StructuredDocumentation", + "src": "1810:811:4", + "text": "@dev Compute winner and report the answer to a specified question from the ERC792 arbitrator to the Realitio v2.0 contract. TRUSTED.\n @param _questionID The ID of the question.\n @param _lastHistoryHash The history hash given with the last answer to the question in the Realitio contract.\n @param _lastAnswerOrCommitmentID The last answer given, or its commitment ID if it was a commitment, to the question in the Realitio contract.\n @param _lastBond The bond paid for the last answer to the question in the Realitio contract.\n @param _lastAnswerer The last answerer to the question in the Realitio contract.\n @param _isCommitment Whether the last answer to the question in the Realitio contract used commit or reveal or not. True if it did, false otherwise." + }, + "functionSelector": "d35c82cb", + "id": 1375, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "computeWinnerAndReportAnswer", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1312, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1301, + "mutability": "mutable", + "name": "_questionID", + "nodeType": "VariableDeclaration", + "scope": 1375, + "src": "2673:19:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1300, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2673:7:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1303, + "mutability": "mutable", + "name": "_lastHistoryHash", + "nodeType": "VariableDeclaration", + "scope": 1375, + "src": "2702:24:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1302, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2702:7:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1305, + "mutability": "mutable", + "name": "_lastAnswerOrCommitmentID", + "nodeType": "VariableDeclaration", + "scope": 1375, + "src": "2736:33:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1304, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2736:7:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1307, + "mutability": "mutable", + "name": "_lastBond", + "nodeType": "VariableDeclaration", + "scope": 1375, + "src": "2779:17:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1306, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2779:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1309, + "mutability": "mutable", + "name": "_lastAnswerer", + "nodeType": "VariableDeclaration", + "scope": 1375, + "src": "2806:21:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 1308, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2806:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1311, + "mutability": "mutable", + "name": "_isCommitment", + "nodeType": "VariableDeclaration", + "scope": 1375, + "src": "2837:18:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 1310, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2837:4:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "2663:198:4" + }, + "returnParameters": { + "id": 1313, + "nodeType": "ParameterList", + "parameters": [], + "src": "2871:0:4" + }, + "scope": 1476, + "src": "2626:1062:4", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "body": { + "id": 1474, + "nodeType": "Block", + "src": "4733:949:4", + "statements": [ + { + "assignments": [ + 1392 + ], + "declarations": [ + { + "constant": false, + "id": 1392, + "mutability": "mutable", + "name": "lastAnswer", + "nodeType": "VariableDeclaration", + "scope": 1474, + "src": "4743:18:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1391, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "4743:7:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 1393, + "nodeType": "VariableDeclarationStatement", + "src": "4743:18:4" + }, + { + "assignments": [ + 1395 + ], + "declarations": [ + { + "constant": false, + "id": 1395, + "mutability": "mutable", + "name": "isAnswered", + "nodeType": "VariableDeclaration", + "scope": 1474, + "src": "4771:15:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 1394, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "4771:4:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "id": 1396, + "nodeType": "VariableDeclarationStatement", + "src": "4771:15:4" + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1399, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1397, + "name": "_lastBond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1382, + "src": "4800:9:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "hexValue": "30", + "id": 1398, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4813:1:4", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "4800:14:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "condition": { + "id": 1405, + "name": "_isCommitment", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1386, + "src": "4944:13:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 1455, + "nodeType": "Block", + "src": "5450:94:4", + "statements": [ + { + "expression": { + "id": 1449, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1447, + "name": "lastAnswer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1392, + "src": "5464:10:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "id": 1448, + "name": "_lastAnswerOrCommitmentID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1380, + "src": "5477:25:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "5464:38:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 1450, + "nodeType": "ExpressionStatement", + "src": "5464:38:4" + }, + { + "expression": { + "id": 1453, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1451, + "name": "isAnswered", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1395, + "src": "5516:10:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "hexValue": "74727565", + "id": 1452, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5529:4:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "5516:17:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1454, + "nodeType": "ExpressionStatement", + "src": "5516:17:4" + } + ] + }, + "id": 1456, + "nodeType": "IfStatement", + "src": "4940:604:4", + "trueBody": { + "id": 1446, + "nodeType": "Block", + "src": "4959:485:4", + "statements": [ + { + "assignments": [ + 1407, + 1409, + 1411 + ], + "declarations": [ + { + "constant": false, + "id": 1407, + "mutability": "mutable", + "name": "revealTS", + "nodeType": "VariableDeclaration", + "scope": 1446, + "src": "4974:15:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 1406, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "4974:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1409, + "mutability": "mutable", + "name": "isRevealed", + "nodeType": "VariableDeclaration", + "scope": 1446, + "src": "4991:15:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 1408, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "4991:4:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1411, + "mutability": "mutable", + "name": "revealedAnswer", + "nodeType": "VariableDeclaration", + "scope": 1446, + "src": "5008:22:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1410, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "5008:7:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 1418, + "initialValue": { + "arguments": [ + { + "id": 1416, + "name": "_lastAnswerOrCommitmentID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1380, + "src": "5071:25:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "arguments": [ + { + "id": 1413, + "name": "realitio", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 56, + "src": "5049:8:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 1412, + "name": "IRealitio_v2_0", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1271, + "src": "5034:14:4", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_IRealitio_v2_0_$1271_$", + "typeString": "type(contract IRealitio_v2_0)" + } + }, + "id": 1414, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5034:24:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_contract$_IRealitio_v2_0_$1271", + "typeString": "contract IRealitio_v2_0" + } + }, + "id": 1415, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "commitments", + "nodeType": "MemberAccess", + "referencedDeclaration": 1270, + "src": "5034:36:4", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$_t_bytes32_$returns$_t_uint32_$_t_bool_$_t_bytes32_$", + "typeString": "function (bytes32) view external returns (uint32,bool,bytes32)" + } + }, + "id": 1417, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5034:63:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint32_$_t_bool_$_t_bytes32_$", + "typeString": "tuple(uint32,bool,bytes32)" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "4973:124:4" + }, + { + "condition": { + "id": 1419, + "name": "isRevealed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1409, + "src": "5115:10:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 1444, + "nodeType": "Block", + "src": "5228:206:4", + "statements": [ + { + "expression": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 1436, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1430, + "name": "revealTS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1407, + "src": "5254:8:4", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "arguments": [ + { + "expression": { + "id": 1433, + "name": "block", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967292, + "src": "5273:5:4", + "typeDescriptions": { + "typeIdentifier": "t_magic_block", + "typeString": "block" + } + }, + "id": 1434, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "timestamp", + "nodeType": "MemberAccess", + "src": "5273:15:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 1432, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "5266:6:4", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint32_$", + "typeString": "type(uint32)" + }, + "typeName": { + "id": 1431, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "5266:6:4", + "typeDescriptions": {} + } + }, + "id": 1435, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5266:23:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "5254:35:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "4172626974726174696f6e2063616e6e6f7420626520646f6e6520756e74696c20746865206c61737420616e73776572657220686173206861642074696d6520746f2072657665616c2069747320636f6d6d69746d656e742e", + "id": 1437, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5291:91:4", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_d686c78ed011130263da78637058c22087c97502c2e1ecdc794fbd91e85f16cc", + "typeString": "literal_string \"Arbitration cannot be done until the last answerer has had time to reveal its commitment.\"" + }, + "value": "Arbitration cannot be done until the last answerer has had time to reveal its commitment." + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_d686c78ed011130263da78637058c22087c97502c2e1ecdc794fbd91e85f16cc", + "typeString": "literal_string \"Arbitration cannot be done until the last answerer has had time to reveal its commitment.\"" + } + ], + "id": 1429, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 4294967278, + 4294967278 + ], + "referencedDeclaration": 4294967278, + "src": "5246:7:4", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 1438, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5246:137:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1439, + "nodeType": "ExpressionStatement", + "src": "5246:137:4" + }, + { + "expression": { + "id": 1442, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1440, + "name": "isAnswered", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1395, + "src": "5401:10:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "hexValue": "66616c7365", + "id": 1441, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5414:5:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "src": "5401:18:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1443, + "nodeType": "ExpressionStatement", + "src": "5401:18:4" + } + ] + }, + "id": 1445, + "nodeType": "IfStatement", + "src": "5111:323:4", + "trueBody": { + "id": 1428, + "nodeType": "Block", + "src": "5127:95:4", + "statements": [ + { + "expression": { + "id": 1422, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1420, + "name": "lastAnswer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1392, + "src": "5145:10:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "id": 1421, + "name": "revealedAnswer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1411, + "src": "5158:14:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "5145:27:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 1423, + "nodeType": "ExpressionStatement", + "src": "5145:27:4" + }, + { + "expression": { + "id": 1426, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1424, + "name": "isAnswered", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1395, + "src": "5190:10:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "hexValue": "74727565", + "id": 1425, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5203:4:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "5190:17:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1427, + "nodeType": "ExpressionStatement", + "src": "5190:17:4" + } + ] + } + } + ] + } + }, + "id": 1457, + "nodeType": "IfStatement", + "src": "4796:748:4", + "trueBody": { + "id": 1404, + "nodeType": "Block", + "src": "4816:118:4", + "statements": [ + { + "expression": { + "id": 1402, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1400, + "name": "isAnswered", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1395, + "src": "4905:10:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "hexValue": "66616c7365", + "id": 1401, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4918:5:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "src": "4905:18:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1403, + "nodeType": "ExpressionStatement", + "src": "4905:18:4" + } + ] + } + }, + { + "expression": { + "condition": { + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 1468, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1458, + "name": "isAnswered", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1395, + "src": "5561:10:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 1467, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1459, + "name": "lastAnswer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1392, + "src": "5575:10:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1465, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 1462, + "name": "_arbitrationRequest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1378, + "src": "5597:19:4", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ArbitrationRequest_$107_storage_ptr", + "typeString": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage pointer" + } + }, + "id": 1463, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "answer", + "nodeType": "MemberAccess", + "referencedDeclaration": 103, + "src": "5597:26:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "hexValue": "31", + "id": 1464, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5626:1:4", + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "5597:30:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 1461, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "5589:7:4", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": { + "id": 1460, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "5589:7:4", + "typeDescriptions": {} + } + }, + "id": 1466, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5589:39:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "5575:53:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "5561:67:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "expression": { + "id": 1470, + "name": "_arbitrationRequest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1378, + "src": "5647:19:4", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ArbitrationRequest_$107_storage_ptr", + "typeString": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage pointer" + } + }, + "id": 1471, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "disputer", + "nodeType": "MemberAccess", + "referencedDeclaration": 99, + "src": "5647:28:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 1472, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "5561:114:4", + "trueExpression": { + "id": 1469, + "name": "_lastAnswerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1384, + "src": "5631:13:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "functionReturnParameters": 1390, + "id": 1473, + "nodeType": "Return", + "src": "5554:121:4" + } + ] + }, + "documentation": { + "id": 1376, + "nodeType": "StructuredDocumentation", + "src": "3694:781:4", + "text": "@dev Computes the Realitio answerer, of a specified question, that should win. This function is needed to avoid the \"stack too deep error\". TRUSTED.\n @param _arbitrationRequest Arbitration request to compute it's winner.\n @param _lastAnswerOrCommitmentID The last answer given, or its commitment ID if it was a commitment, to the question in the Realitio contract.\n @param _lastBond The bond paid for the last answer to the question in the Realitio contract.\n @param _lastAnswerer The last answerer to the question in the Realitio contract.\n @param _isCommitment Whether the last answer to the question in the Realitio contract used commit or reveal or not. True if it did, false otherwise.\n @return winner The computed winner." + }, + "id": 1475, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "computeWinner", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1387, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1378, + "mutability": "mutable", + "name": "_arbitrationRequest", + "nodeType": "VariableDeclaration", + "scope": 1475, + "src": "4512:46:4", + "stateVariable": false, + "storageLocation": "storage", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ArbitrationRequest_$107_storage_ptr", + "typeString": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest" + }, + "typeName": { + "id": 1377, + "name": "ArbitrationRequest", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 107, + "src": "4512:18:4", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ArbitrationRequest_$107_storage_ptr", + "typeString": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1380, + "mutability": "mutable", + "name": "_lastAnswerOrCommitmentID", + "nodeType": "VariableDeclaration", + "scope": 1475, + "src": "4568:33:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1379, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "4568:7:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1382, + "mutability": "mutable", + "name": "_lastBond", + "nodeType": "VariableDeclaration", + "scope": 1475, + "src": "4611:17:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1381, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4611:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1384, + "mutability": "mutable", + "name": "_lastAnswerer", + "nodeType": "VariableDeclaration", + "scope": 1475, + "src": "4638:21:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 1383, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4638:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1386, + "mutability": "mutable", + "name": "_isCommitment", + "nodeType": "VariableDeclaration", + "scope": 1475, + "src": "4669:18:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 1385, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "4669:4:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "4502:191:4" + }, + "returnParameters": { + "id": 1390, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1389, + "mutability": "mutable", + "name": "winner", + "nodeType": "VariableDeclaration", + "scope": 1475, + "src": "4717:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 1388, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4717:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "4716:16:4" + }, + "scope": 1476, + "src": "4480:1202:4", + "stateMutability": "view", + "virtual": false, + "visibility": "internal" + } + ], + "scope": 1477, + "src": "1135:4549:4" + } + ], + "src": "194:5491:4" + }, + "legacyAST": { + "attributes": { + "absolutePath": "/home/f/repos/realitio-arbitrator-with-appeals/contracts/v2.0/Realitio_v2_0_ArbitratorWithAppeals.sol", + "exportedSymbols": { + "CappedMath": [ + 1858 + ], + "IArbitrable": [ + 1644 + ], + "IArbitrator": [ + 1736 + ], + "IDisputeResolver": [ + 1622 + ], + "IEvidence": [ + 1770 + ], + "IRealitioArbitrator": [ + 24 + ], + "IRealitioBase": [ + 38 + ], + "IRealitio_v2_0": [ + 1271 + ], + "RealitioArbitratorWithAppealsBase": [ + 1234 + ], + "Realitio_v2_0_ArbitratorWithAppeals": [ + 1476 + ] + }, + "license": "MIT" + }, + "children": [ + { + "attributes": { + "literals": [ + "solidity", + "^", + "0.7", + ".0" + ] + }, + "id": 1273, + "name": "PragmaDirective", + "src": "194:23:4" + }, + { + "attributes": { + "literals": [ + "abicoder", + "v2" + ] + }, + "id": 1274, + "name": "PragmaDirective", + "src": "218:19:4" + }, + { + "attributes": { + "SourceUnit": 1272, + "absolutePath": "/home/f/repos/realitio-arbitrator-with-appeals/contracts/v2.0/IRealitio_v2_0.sol", + "file": "./IRealitio_v2_0.sol", + "scope": 1477, + "symbolAliases": [ + null + ], + "unitAlias": "" + }, + "id": 1275, + "name": "ImportDirective", + "src": "239:30:4" + }, + { + "attributes": { + "SourceUnit": 1235, + "absolutePath": "/home/f/repos/realitio-arbitrator-with-appeals/contracts/RealitioArbitratorWithAppealsBase.sol", + "file": "../RealitioArbitratorWithAppealsBase.sol", + "scope": 1477, + "symbolAliases": [ + null + ], + "unitAlias": "" + }, + "id": 1276, + "name": "ImportDirective", + "src": "270:50:4" + }, + { + "attributes": { + "abstract": false, + "contractDependencies": [ + 24, + 1234, + 1622, + 1644, + 1770 + ], + "contractKind": "contract", + "fullyImplemented": true, + "linearizedBaseContracts": [ + 1476, + 1234, + 24, + 1622, + 1770, + 1644 + ], + "name": "Realitio_v2_0_ArbitratorWithAppeals", + "scope": 1477 + }, + "children": [ + { + "attributes": { + "text": " @title Realitio_v2_0_ArbitratorWithAppeals\n @dev A Realitio arbitrator implementation that uses Realitio v2.0 and Kleros. It notifies Realitio contract for arbitration requests and creates corresponding dispute on Kleros. Transmits Kleros ruling to Realitio contract. Maintains crowdfunded appeals and notifies Kleros contract. Provides a function to submit evidence for Kleros dispute.\n There is a conversion between Kleros ruling and Realitio answer and there is a need for shifting by 1. This is because ruling 0 in Kleros signals tie or no-ruling but in Realitio 0 is a valid answer. For reviewers this should be a focus as it's quite easy to get confused. Any mistakes on this conversion will render this contract useless.\n NOTE: This contract trusts the Kleros arbitrator and Realitio." + }, + "id": 1277, + "name": "StructuredDocumentation", + "src": "322:812:4" + }, + { + "attributes": {}, + "children": [ + { + "attributes": { + "name": "RealitioArbitratorWithAppealsBase", + "referencedDeclaration": 1234, + "type": "contract RealitioArbitratorWithAppealsBase" + }, + "id": 1278, + "name": "UserDefinedTypeName", + "src": "1183:33:4" + } + ], + "id": 1279, + "name": "InheritanceSpecifier", + "src": "1183:33:4" + }, + { + "attributes": { + "implemented": true, + "isConstructor": true, + "kind": "constructor", + "name": "", + "scope": 1476, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + }, + "children": [ + { + "attributes": { + "text": "@dev Constructor.\n @param _realitio The address of the Realitio contract.\n @param _metadata The metadata required for RealitioArbitrator.\n @param _arbitrator The address of the ERC792 arbitrator.\n @param _arbitratorExtraData The extra data used to raise a dispute in the ERC792 arbitrator." + }, + "id": 1280, + "name": "StructuredDocumentation", + "src": "1223:329:4" + }, + { + "children": [ + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "_realitio", + "scope": 1298, + "stateVariable": false, + "storageLocation": "default", + "type": "address", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "address", + "stateMutability": "nonpayable", + "type": "address" + }, + "id": 1281, + "name": "ElementaryTypeName", + "src": "1578:7:4" + } + ], + "id": 1282, + "name": "VariableDeclaration", + "src": "1578:17:4" + }, + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "_metadata", + "scope": 1298, + "stateVariable": false, + "storageLocation": "memory", + "type": "string", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "string", + "type": "string" + }, + "id": 1283, + "name": "ElementaryTypeName", + "src": "1605:6:4" + } + ], + "id": 1284, + "name": "VariableDeclaration", + "src": "1605:23:4" + }, + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "_arbitrator", + "scope": 1298, + "stateVariable": false, + "storageLocation": "default", + "type": "contract IArbitrator", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "IArbitrator", + "referencedDeclaration": 1736, + "type": "contract IArbitrator" + }, + "id": 1285, + "name": "UserDefinedTypeName", + "src": "1638:11:4" + } + ], + "id": 1286, + "name": "VariableDeclaration", + "src": "1638:23:4" + }, + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "_arbitratorExtraData", + "scope": 1298, + "stateVariable": false, + "storageLocation": "memory", + "type": "bytes", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "bytes", + "type": "bytes" + }, + "id": 1287, + "name": "ElementaryTypeName", + "src": "1671:5:4" + } + ], + "id": 1288, + "name": "VariableDeclaration", + "src": "1671:33:4" + } + ], + "id": 1289, + "name": "ParameterList", + "src": "1568:142:4" + }, + { + "attributes": { + "parameters": [ + null + ] + }, + "children": [], + "id": 1296, + "name": "ParameterList", + "src": "1802:0:4" + }, + { + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1234, + "type": "type(contract RealitioArbitratorWithAppealsBase)", + "value": "RealitioArbitratorWithAppealsBase" + }, + "id": 1290, + "name": "Identifier", + "src": "1711:33:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1282, + "type": "address", + "value": "_realitio" + }, + "id": 1291, + "name": "Identifier", + "src": "1745:9:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1284, + "type": "string memory", + "value": "_metadata" + }, + "id": 1292, + "name": "Identifier", + "src": "1756:9:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1286, + "type": "contract IArbitrator", + "value": "_arbitrator" + }, + "id": 1293, + "name": "Identifier", + "src": "1767:11:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1288, + "type": "bytes memory", + "value": "_arbitratorExtraData" + }, + "id": 1294, + "name": "Identifier", + "src": "1780:20:4" + } + ], + "id": 1295, + "name": "ModifierInvocation", + "src": "1711:90:4" + }, + { + "attributes": { + "statements": [ + null + ] + }, + "children": [], + "id": 1297, + "name": "Block", + "src": "1802:2:4" + } + ], + "id": 1298, + "name": "FunctionDefinition", + "src": "1557:247:4" + }, + { + "attributes": { + "functionSelector": "d35c82cb", + "implemented": true, + "isConstructor": false, + "kind": "function", + "modifiers": [ + null + ], + "name": "computeWinnerAndReportAnswer", + "scope": 1476, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + "children": [ + { + "attributes": { + "text": "@dev Compute winner and report the answer to a specified question from the ERC792 arbitrator to the Realitio v2.0 contract. TRUSTED.\n @param _questionID The ID of the question.\n @param _lastHistoryHash The history hash given with the last answer to the question in the Realitio contract.\n @param _lastAnswerOrCommitmentID The last answer given, or its commitment ID if it was a commitment, to the question in the Realitio contract.\n @param _lastBond The bond paid for the last answer to the question in the Realitio contract.\n @param _lastAnswerer The last answerer to the question in the Realitio contract.\n @param _isCommitment Whether the last answer to the question in the Realitio contract used commit or reveal or not. True if it did, false otherwise." + }, + "id": 1299, + "name": "StructuredDocumentation", + "src": "1810:811:4" + }, + { + "children": [ + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "_questionID", + "scope": 1375, + "stateVariable": false, + "storageLocation": "default", + "type": "bytes32", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "bytes32", + "type": "bytes32" + }, + "id": 1300, + "name": "ElementaryTypeName", + "src": "2673:7:4" + } + ], + "id": 1301, + "name": "VariableDeclaration", + "src": "2673:19:4" + }, + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "_lastHistoryHash", + "scope": 1375, + "stateVariable": false, + "storageLocation": "default", + "type": "bytes32", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "bytes32", + "type": "bytes32" + }, + "id": 1302, + "name": "ElementaryTypeName", + "src": "2702:7:4" + } + ], + "id": 1303, + "name": "VariableDeclaration", + "src": "2702:24:4" + }, + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "_lastAnswerOrCommitmentID", + "scope": 1375, + "stateVariable": false, + "storageLocation": "default", + "type": "bytes32", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "bytes32", + "type": "bytes32" + }, + "id": 1304, + "name": "ElementaryTypeName", + "src": "2736:7:4" + } + ], + "id": 1305, + "name": "VariableDeclaration", + "src": "2736:33:4" + }, + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "_lastBond", + "scope": 1375, + "stateVariable": false, + "storageLocation": "default", + "type": "uint256", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "uint256", + "type": "uint256" + }, + "id": 1306, + "name": "ElementaryTypeName", + "src": "2779:7:4" + } + ], + "id": 1307, + "name": "VariableDeclaration", + "src": "2779:17:4" + }, + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "_lastAnswerer", + "scope": 1375, + "stateVariable": false, + "storageLocation": "default", + "type": "address", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "address", + "stateMutability": "nonpayable", + "type": "address" + }, + "id": 1308, + "name": "ElementaryTypeName", + "src": "2806:7:4" + } + ], + "id": 1309, + "name": "VariableDeclaration", + "src": "2806:21:4" + }, + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "_isCommitment", + "scope": 1375, + "stateVariable": false, + "storageLocation": "default", + "type": "bool", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "bool", + "type": "bool" + }, + "id": 1310, + "name": "ElementaryTypeName", + "src": "2837:4:4" + } + ], + "id": 1311, + "name": "VariableDeclaration", + "src": "2837:18:4" + } + ], + "id": 1312, + "name": "ParameterList", + "src": "2663:198:4" + }, + { + "attributes": { + "parameters": [ + null + ] + }, + "children": [], + "id": 1313, + "name": "ParameterList", + "src": "2871:0:4" + }, + { + "children": [ + { + "attributes": { + "assignments": [ + 1315 + ] + }, + "children": [ + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "arbitrationRequest", + "scope": 1374, + "stateVariable": false, + "storageLocation": "storage", + "type": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "ArbitrationRequest", + "referencedDeclaration": 107, + "type": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest" + }, + "id": 1314, + "name": "UserDefinedTypeName", + "src": "2881:18:4" + } + ], + "id": 1315, + "name": "VariableDeclaration", + "src": "2881:45:4" + }, + { + "attributes": { + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "type": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage ref" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 131, + "type": "mapping(uint256 => struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage ref)", + "value": "arbitrationRequests" + }, + "id": 1316, + "name": "Identifier", + "src": "2929:19:4" + }, + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": [ + null + ], + "tryCall": false, + "type": "uint256", + "type_conversion": true + }, + "children": [ + { + "attributes": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "type": "type(uint256)" + }, + "children": [ + { + "attributes": { + "name": "uint256" + }, + "id": 1317, + "name": "ElementaryTypeName", + "src": "2949:7:4" + } + ], + "id": 1318, + "name": "ElementaryTypeNameExpression", + "src": "2949:7:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1301, + "type": "bytes32", + "value": "_questionID" + }, + "id": 1319, + "name": "Identifier", + "src": "2957:11:4" + } + ], + "id": 1320, + "name": "FunctionCall", + "src": "2949:20:4" + } + ], + "id": 1321, + "name": "IndexAccess", + "src": "2929:41:4" + } + ], + "id": 1322, + "name": "VariableDeclarationStatement", + "src": "2881:89:4" + }, + { + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": [ + null + ], + "tryCall": false, + "type": "tuple()", + "type_conversion": false + }, + "children": [ + { + "attributes": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_7b12e68595b54b95620c01e48f1dc5573a4c5ef17b89e01ed1eb1d416d772095", + "typeString": "literal_string \"The status should be Ruled.\"" + } + ], + "overloadedDeclarations": [ + 4294967278, + 4294967278 + ], + "referencedDeclaration": 4294967278, + "type": "function (bool,string memory) pure", + "value": "require" + }, + "id": 1323, + "name": "Identifier", + "src": "2980:7:4" + }, + { + "attributes": { + "commonType": { + "typeIdentifier": "t_enum$_Status_$95", + "typeString": "enum RealitioArbitratorWithAppealsBase.Status" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "==", + "type": "bool" + }, + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "status", + "referencedDeclaration": 97, + "type": "enum RealitioArbitratorWithAppealsBase.Status" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1315, + "type": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage pointer", + "value": "arbitrationRequest" + }, + "id": 1324, + "name": "Identifier", + "src": "2988:18:4" + } + ], + "id": 1325, + "name": "MemberAccess", + "src": "2988:25:4" + }, + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "member_name": "Ruled", + "type": "enum RealitioArbitratorWithAppealsBase.Status" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 95, + "type": "type(enum RealitioArbitratorWithAppealsBase.Status)", + "value": "Status" + }, + "id": 1326, + "name": "Identifier", + "src": "3017:6:4" + } + ], + "id": 1327, + "name": "MemberAccess", + "src": "3017:12:4" + } + ], + "id": 1328, + "name": "BinaryOperation", + "src": "2988:41:4" + }, + { + "attributes": { + "hexvalue": "546865207374617475732073686f756c642062652052756c65642e", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "token": "string", + "type": "literal_string \"The status should be Ruled.\"", + "value": "The status should be Ruled." + }, + "id": 1329, + "name": "Literal", + "src": "3031:29:4" + } + ], + "id": 1330, + "name": "FunctionCall", + "src": "2980:81:4" + } + ], + "id": 1331, + "name": "ExpressionStatement", + "src": "2980:81:4" + }, + { + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": [ + null + ], + "tryCall": false, + "type": "tuple()", + "type_conversion": false + }, + "children": [ + { + "attributes": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_281e1d87b180850f34e67af4ee84b890763a546671bbe4c68d9b7e0f4b9d0bd4", + "typeString": "literal_string \"The hash of the history parameters supplied does not match the one stored in the Realitio contract.\"" + } + ], + "overloadedDeclarations": [ + 4294967278, + 4294967278 + ], + "referencedDeclaration": 4294967278, + "type": "function (bool,string memory) pure", + "value": "require" + }, + "id": 1332, + "name": "Identifier", + "src": "3071:7:4" + }, + { + "attributes": { + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "==", + "type": "bool" + }, + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": [ + null + ], + "tryCall": false, + "type": "bytes32", + "type_conversion": false + }, + "children": [ + { + "attributes": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "member_name": "getHistoryHash", + "referencedDeclaration": 1258, + "type": "function (bytes32) view external returns (bytes32)" + }, + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": [ + null + ], + "tryCall": false, + "type": "contract IRealitio_v2_0", + "type_conversion": true + }, + "children": [ + { + "attributes": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1271, + "type": "type(contract IRealitio_v2_0)", + "value": "IRealitio_v2_0" + }, + "id": 1333, + "name": "Identifier", + "src": "3079:14:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 56, + "type": "address", + "value": "realitio" + }, + "id": 1334, + "name": "Identifier", + "src": "3094:8:4" + } + ], + "id": 1335, + "name": "FunctionCall", + "src": "3079:24:4" + } + ], + "id": 1336, + "name": "MemberAccess", + "src": "3079:39:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1301, + "type": "bytes32", + "value": "_questionID" + }, + "id": 1337, + "name": "Identifier", + "src": "3119:11:4" + } + ], + "id": 1338, + "name": "FunctionCall", + "src": "3079:52:4" + }, + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": [ + null + ], + "tryCall": false, + "type": "bytes32", + "type_conversion": false + }, + "children": [ + { + "attributes": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 4294967288, + "type": "function (bytes memory) pure returns (bytes32)", + "value": "keccak256" + }, + "id": 1339, + "name": "Identifier", + "src": "3135:9:4" + }, + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": [ + null + ], + "tryCall": false, + "type": "bytes memory", + "type_conversion": false + }, + "children": [ + { + "attributes": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "member_name": "encodePacked", + "type": "function () pure returns (bytes memory)" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 4294967295, + "type": "abi", + "value": "abi" + }, + "id": 1340, + "name": "Identifier", + "src": "3145:3:4" + } + ], + "id": 1341, + "name": "MemberAccess", + "src": "3145:16:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1303, + "type": "bytes32", + "value": "_lastHistoryHash" + }, + "id": 1342, + "name": "Identifier", + "src": "3162:16:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1305, + "type": "bytes32", + "value": "_lastAnswerOrCommitmentID" + }, + "id": 1343, + "name": "Identifier", + "src": "3180:25:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1307, + "type": "uint256", + "value": "_lastBond" + }, + "id": 1344, + "name": "Identifier", + "src": "3207:9:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1309, + "type": "address", + "value": "_lastAnswerer" + }, + "id": 1345, + "name": "Identifier", + "src": "3218:13:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1311, + "type": "bool", + "value": "_isCommitment" + }, + "id": 1346, + "name": "Identifier", + "src": "3233:13:4" + } + ], + "id": 1347, + "name": "FunctionCall", + "src": "3145:102:4" + } + ], + "id": 1348, + "name": "FunctionCall", + "src": "3135:113:4" + } + ], + "id": 1349, + "name": "BinaryOperation", + "src": "3079:169:4" + }, + { + "attributes": { + "hexvalue": "5468652068617368206f662074686520686973746f727920706172616d657465727320737570706c69656420646f6573206e6f74206d6174636820746865206f6e652073746f72656420696e20746865205265616c6974696f20636f6e74726163742e", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "token": "string", + "type": "literal_string \"The hash of the history parameters supplied does not match the one stored in the Realitio contract.\"", + "value": "The hash of the history parameters supplied does not match the one stored in the Realitio contract." + }, + "id": 1350, + "name": "Literal", + "src": "3250:101:4" + } + ], + "id": 1351, + "name": "FunctionCall", + "src": "3071:281:4" + } + ], + "id": 1352, + "name": "ExpressionStatement", + "src": "3071:281:4" + }, + { + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": [ + null + ], + "tryCall": false, + "type": "tuple()", + "type_conversion": false + }, + "children": [ + { + "attributes": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "member_name": "submitAnswerByArbitrator", + "referencedDeclaration": 1250, + "type": "function (bytes32,bytes32,address) external" + }, + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": [ + null + ], + "tryCall": false, + "type": "contract IRealitio_v2_0", + "type_conversion": true + }, + "children": [ + { + "attributes": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1271, + "type": "type(contract IRealitio_v2_0)", + "value": "IRealitio_v2_0" + }, + "id": 1353, + "name": "Identifier", + "src": "3476:14:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 56, + "type": "address", + "value": "realitio" + }, + "id": 1354, + "name": "Identifier", + "src": "3491:8:4" + } + ], + "id": 1355, + "name": "FunctionCall", + "src": "3476:24:4" + } + ], + "id": 1356, + "name": "MemberAccess", + "src": "3476:49:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1301, + "type": "bytes32", + "value": "_questionID" + }, + "id": 1357, + "name": "Identifier", + "src": "3526:11:4" + }, + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": [ + null + ], + "tryCall": false, + "type": "bytes32", + "type_conversion": true + }, + "children": [ + { + "attributes": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "type": "type(bytes32)" + }, + "children": [ + { + "attributes": { + "name": "bytes32" + }, + "id": 1358, + "name": "ElementaryTypeName", + "src": "3539:7:4" + } + ], + "id": 1359, + "name": "ElementaryTypeNameExpression", + "src": "3539:7:4" + }, + { + "attributes": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "-", + "type": "uint256" + }, + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "answer", + "referencedDeclaration": 103, + "type": "uint256" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1315, + "type": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage pointer", + "value": "arbitrationRequest" + }, + "id": 1360, + "name": "Identifier", + "src": "3547:18:4" + } + ], + "id": 1361, + "name": "MemberAccess", + "src": "3547:25:4" + }, + { + "attributes": { + "hexvalue": "31", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "token": "number", + "type": "int_const 1", + "value": "1" + }, + "id": 1362, + "name": "Literal", + "src": "3575:1:4" + } + ], + "id": 1363, + "name": "BinaryOperation", + "src": "3547:29:4" + } + ], + "id": 1364, + "name": "FunctionCall", + "src": "3539:38:4" + }, + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": [ + null + ], + "tryCall": false, + "type": "address", + "type_conversion": false + }, + "children": [ + { + "attributes": { + "argumentTypes": [ + { + "typeIdentifier": "t_struct$_ArbitrationRequest_$107_storage_ptr", + "typeString": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage pointer" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1475, + "type": "function (struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage pointer,bytes32,uint256,address,bool) view returns (address)", + "value": "computeWinner" + }, + "id": 1365, + "name": "Identifier", + "src": "3579:13:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1315, + "type": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage pointer", + "value": "arbitrationRequest" + }, + "id": 1366, + "name": "Identifier", + "src": "3593:18:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1305, + "type": "bytes32", + "value": "_lastAnswerOrCommitmentID" + }, + "id": 1367, + "name": "Identifier", + "src": "3613:25:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1307, + "type": "uint256", + "value": "_lastBond" + }, + "id": 1368, + "name": "Identifier", + "src": "3640:9:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1309, + "type": "address", + "value": "_lastAnswerer" + }, + "id": 1369, + "name": "Identifier", + "src": "3651:13:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1311, + "type": "bool", + "value": "_isCommitment" + }, + "id": 1370, + "name": "Identifier", + "src": "3666:13:4" + } + ], + "id": 1371, + "name": "FunctionCall", + "src": "3579:101:4" + } + ], + "id": 1372, + "name": "FunctionCall", + "src": "3476:205:4" + } + ], + "id": 1373, + "name": "ExpressionStatement", + "src": "3476:205:4" + } + ], + "id": 1374, + "name": "Block", + "src": "2871:817:4" + } + ], + "id": 1375, + "name": "FunctionDefinition", + "src": "2626:1062:4" + }, + { + "attributes": { + "implemented": true, + "isConstructor": false, + "kind": "function", + "modifiers": [ + null + ], + "name": "computeWinner", + "scope": 1476, + "stateMutability": "view", + "virtual": false, + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "text": "@dev Computes the Realitio answerer, of a specified question, that should win. This function is needed to avoid the \"stack too deep error\". TRUSTED.\n @param _arbitrationRequest Arbitration request to compute it's winner.\n @param _lastAnswerOrCommitmentID The last answer given, or its commitment ID if it was a commitment, to the question in the Realitio contract.\n @param _lastBond The bond paid for the last answer to the question in the Realitio contract.\n @param _lastAnswerer The last answerer to the question in the Realitio contract.\n @param _isCommitment Whether the last answer to the question in the Realitio contract used commit or reveal or not. True if it did, false otherwise.\n @return winner The computed winner." + }, + "id": 1376, + "name": "StructuredDocumentation", + "src": "3694:781:4" + }, + { + "children": [ + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "_arbitrationRequest", + "scope": 1475, + "stateVariable": false, + "storageLocation": "storage", + "type": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "ArbitrationRequest", + "referencedDeclaration": 107, + "type": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest" + }, + "id": 1377, + "name": "UserDefinedTypeName", + "src": "4512:18:4" + } + ], + "id": 1378, + "name": "VariableDeclaration", + "src": "4512:46:4" + }, + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "_lastAnswerOrCommitmentID", + "scope": 1475, + "stateVariable": false, + "storageLocation": "default", + "type": "bytes32", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "bytes32", + "type": "bytes32" + }, + "id": 1379, + "name": "ElementaryTypeName", + "src": "4568:7:4" + } + ], + "id": 1380, + "name": "VariableDeclaration", + "src": "4568:33:4" + }, + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "_lastBond", + "scope": 1475, + "stateVariable": false, + "storageLocation": "default", + "type": "uint256", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "uint256", + "type": "uint256" + }, + "id": 1381, + "name": "ElementaryTypeName", + "src": "4611:7:4" + } + ], + "id": 1382, + "name": "VariableDeclaration", + "src": "4611:17:4" + }, + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "_lastAnswerer", + "scope": 1475, + "stateVariable": false, + "storageLocation": "default", + "type": "address", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "address", + "stateMutability": "nonpayable", + "type": "address" + }, + "id": 1383, + "name": "ElementaryTypeName", + "src": "4638:7:4" + } + ], + "id": 1384, + "name": "VariableDeclaration", + "src": "4638:21:4" + }, + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "_isCommitment", + "scope": 1475, + "stateVariable": false, + "storageLocation": "default", + "type": "bool", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "bool", + "type": "bool" + }, + "id": 1385, + "name": "ElementaryTypeName", + "src": "4669:4:4" + } + ], + "id": 1386, + "name": "VariableDeclaration", + "src": "4669:18:4" + } + ], + "id": 1387, + "name": "ParameterList", + "src": "4502:191:4" + }, + { + "children": [ + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "winner", + "scope": 1475, + "stateVariable": false, + "storageLocation": "default", + "type": "address", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "address", + "stateMutability": "nonpayable", + "type": "address" + }, + "id": 1388, + "name": "ElementaryTypeName", + "src": "4717:7:4" + } + ], + "id": 1389, + "name": "VariableDeclaration", + "src": "4717:14:4" + } + ], + "id": 1390, + "name": "ParameterList", + "src": "4716:16:4" + }, + { + "children": [ + { + "attributes": { + "assignments": [ + 1392 + ] + }, + "children": [ + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "lastAnswer", + "scope": 1474, + "stateVariable": false, + "storageLocation": "default", + "type": "bytes32", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "bytes32", + "type": "bytes32" + }, + "id": 1391, + "name": "ElementaryTypeName", + "src": "4743:7:4" + } + ], + "id": 1392, + "name": "VariableDeclaration", + "src": "4743:18:4" + } + ], + "id": 1393, + "name": "VariableDeclarationStatement", + "src": "4743:18:4" + }, + { + "attributes": { + "assignments": [ + 1395 + ] + }, + "children": [ + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "isAnswered", + "scope": 1474, + "stateVariable": false, + "storageLocation": "default", + "type": "bool", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "bool", + "type": "bool" + }, + "id": 1394, + "name": "ElementaryTypeName", + "src": "4771:4:4" + } + ], + "id": 1395, + "name": "VariableDeclaration", + "src": "4771:15:4" + } + ], + "id": 1396, + "name": "VariableDeclarationStatement", + "src": "4771:15:4" + }, + { + "children": [ + { + "attributes": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "==", + "type": "bool" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1382, + "type": "uint256", + "value": "_lastBond" + }, + "id": 1397, + "name": "Identifier", + "src": "4800:9:4" + }, + { + "attributes": { + "hexvalue": "30", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "token": "number", + "type": "int_const 0", + "value": "0" + }, + "id": 1398, + "name": "Literal", + "src": "4813:1:4" + } + ], + "id": 1399, + "name": "BinaryOperation", + "src": "4800:14:4" + }, + { + "children": [ + { + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "bool" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1395, + "type": "bool", + "value": "isAnswered" + }, + "id": 1400, + "name": "Identifier", + "src": "4905:10:4" + }, + { + "attributes": { + "hexvalue": "66616c7365", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "token": "bool", + "type": "bool", + "value": "false" + }, + "id": 1401, + "name": "Literal", + "src": "4918:5:4" + } + ], + "id": 1402, + "name": "Assignment", + "src": "4905:18:4" + } + ], + "id": 1403, + "name": "ExpressionStatement", + "src": "4905:18:4" + } + ], + "id": 1404, + "name": "Block", + "src": "4816:118:4" + }, + { + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1386, + "type": "bool", + "value": "_isCommitment" + }, + "id": 1405, + "name": "Identifier", + "src": "4944:13:4" + }, + { + "children": [ + { + "attributes": { + "assignments": [ + 1407, + 1409, + 1411 + ] + }, + "children": [ + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "revealTS", + "scope": 1446, + "stateVariable": false, + "storageLocation": "default", + "type": "uint32", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "uint32", + "type": "uint32" + }, + "id": 1406, + "name": "ElementaryTypeName", + "src": "4974:6:4" + } + ], + "id": 1407, + "name": "VariableDeclaration", + "src": "4974:15:4" + }, + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "isRevealed", + "scope": 1446, + "stateVariable": false, + "storageLocation": "default", + "type": "bool", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "bool", + "type": "bool" + }, + "id": 1408, + "name": "ElementaryTypeName", + "src": "4991:4:4" + } + ], + "id": 1409, + "name": "VariableDeclaration", + "src": "4991:15:4" + }, + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "revealedAnswer", + "scope": 1446, + "stateVariable": false, + "storageLocation": "default", + "type": "bytes32", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "bytes32", + "type": "bytes32" + }, + "id": 1410, + "name": "ElementaryTypeName", + "src": "5008:7:4" + } + ], + "id": 1411, + "name": "VariableDeclaration", + "src": "5008:22:4" + }, + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": [ + null + ], + "tryCall": false, + "type": "tuple(uint32,bool,bytes32)", + "type_conversion": false + }, + "children": [ + { + "attributes": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "member_name": "commitments", + "referencedDeclaration": 1270, + "type": "function (bytes32) view external returns (uint32,bool,bytes32)" + }, + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": [ + null + ], + "tryCall": false, + "type": "contract IRealitio_v2_0", + "type_conversion": true + }, + "children": [ + { + "attributes": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1271, + "type": "type(contract IRealitio_v2_0)", + "value": "IRealitio_v2_0" + }, + "id": 1412, + "name": "Identifier", + "src": "5034:14:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 56, + "type": "address", + "value": "realitio" + }, + "id": 1413, + "name": "Identifier", + "src": "5049:8:4" + } + ], + "id": 1414, + "name": "FunctionCall", + "src": "5034:24:4" + } + ], + "id": 1415, + "name": "MemberAccess", + "src": "5034:36:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1380, + "type": "bytes32", + "value": "_lastAnswerOrCommitmentID" + }, + "id": 1416, + "name": "Identifier", + "src": "5071:25:4" + } + ], + "id": 1417, + "name": "FunctionCall", + "src": "5034:63:4" + } + ], + "id": 1418, + "name": "VariableDeclarationStatement", + "src": "4973:124:4" + }, + { + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1409, + "type": "bool", + "value": "isRevealed" + }, + "id": 1419, + "name": "Identifier", + "src": "5115:10:4" + }, + { + "children": [ + { + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "bytes32" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1392, + "type": "bytes32", + "value": "lastAnswer" + }, + "id": 1420, + "name": "Identifier", + "src": "5145:10:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1411, + "type": "bytes32", + "value": "revealedAnswer" + }, + "id": 1421, + "name": "Identifier", + "src": "5158:14:4" + } + ], + "id": 1422, + "name": "Assignment", + "src": "5145:27:4" + } + ], + "id": 1423, + "name": "ExpressionStatement", + "src": "5145:27:4" + }, + { + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "bool" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1395, + "type": "bool", + "value": "isAnswered" + }, + "id": 1424, + "name": "Identifier", + "src": "5190:10:4" + }, + { + "attributes": { + "hexvalue": "74727565", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "token": "bool", + "type": "bool", + "value": "true" + }, + "id": 1425, + "name": "Literal", + "src": "5203:4:4" + } + ], + "id": 1426, + "name": "Assignment", + "src": "5190:17:4" + } + ], + "id": 1427, + "name": "ExpressionStatement", + "src": "5190:17:4" + } + ], + "id": 1428, + "name": "Block", + "src": "5127:95:4" + }, + { + "children": [ + { + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": [ + null + ], + "tryCall": false, + "type": "tuple()", + "type_conversion": false + }, + "children": [ + { + "attributes": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_d686c78ed011130263da78637058c22087c97502c2e1ecdc794fbd91e85f16cc", + "typeString": "literal_string \"Arbitration cannot be done until the last answerer has had time to reveal its commitment.\"" + } + ], + "overloadedDeclarations": [ + 4294967278, + 4294967278 + ], + "referencedDeclaration": 4294967278, + "type": "function (bool,string memory) pure", + "value": "require" + }, + "id": 1429, + "name": "Identifier", + "src": "5246:7:4" + }, + { + "attributes": { + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "<=", + "type": "bool" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1407, + "type": "uint32", + "value": "revealTS" + }, + "id": 1430, + "name": "Identifier", + "src": "5254:8:4" + }, + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": [ + null + ], + "tryCall": false, + "type": "uint32", + "type_conversion": true + }, + "children": [ + { + "attributes": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "type": "type(uint32)" + }, + "children": [ + { + "attributes": { + "name": "uint32" + }, + "id": 1431, + "name": "ElementaryTypeName", + "src": "5266:6:4" + } + ], + "id": 1432, + "name": "ElementaryTypeNameExpression", + "src": "5266:6:4" + }, + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "member_name": "timestamp", + "type": "uint256" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 4294967292, + "type": "block", + "value": "block" + }, + "id": 1433, + "name": "Identifier", + "src": "5273:5:4" + } + ], + "id": 1434, + "name": "MemberAccess", + "src": "5273:15:4" + } + ], + "id": 1435, + "name": "FunctionCall", + "src": "5266:23:4" + } + ], + "id": 1436, + "name": "BinaryOperation", + "src": "5254:35:4" + }, + { + "attributes": { + "hexvalue": "4172626974726174696f6e2063616e6e6f7420626520646f6e6520756e74696c20746865206c61737420616e73776572657220686173206861642074696d6520746f2072657665616c2069747320636f6d6d69746d656e742e", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "token": "string", + "type": "literal_string \"Arbitration cannot be done until the last answerer has had time to reveal its commitment.\"", + "value": "Arbitration cannot be done until the last answerer has had time to reveal its commitment." + }, + "id": 1437, + "name": "Literal", + "src": "5291:91:4" + } + ], + "id": 1438, + "name": "FunctionCall", + "src": "5246:137:4" + } + ], + "id": 1439, + "name": "ExpressionStatement", + "src": "5246:137:4" + }, + { + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "bool" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1395, + "type": "bool", + "value": "isAnswered" + }, + "id": 1440, + "name": "Identifier", + "src": "5401:10:4" + }, + { + "attributes": { + "hexvalue": "66616c7365", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "token": "bool", + "type": "bool", + "value": "false" + }, + "id": 1441, + "name": "Literal", + "src": "5414:5:4" + } + ], + "id": 1442, + "name": "Assignment", + "src": "5401:18:4" + } + ], + "id": 1443, + "name": "ExpressionStatement", + "src": "5401:18:4" + } + ], + "id": 1444, + "name": "Block", + "src": "5228:206:4" + } + ], + "id": 1445, + "name": "IfStatement", + "src": "5111:323:4" + } + ], + "id": 1446, + "name": "Block", + "src": "4959:485:4" + }, + { + "children": [ + { + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "bytes32" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1392, + "type": "bytes32", + "value": "lastAnswer" + }, + "id": 1447, + "name": "Identifier", + "src": "5464:10:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1380, + "type": "bytes32", + "value": "_lastAnswerOrCommitmentID" + }, + "id": 1448, + "name": "Identifier", + "src": "5477:25:4" + } + ], + "id": 1449, + "name": "Assignment", + "src": "5464:38:4" + } + ], + "id": 1450, + "name": "ExpressionStatement", + "src": "5464:38:4" + }, + { + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "bool" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1395, + "type": "bool", + "value": "isAnswered" + }, + "id": 1451, + "name": "Identifier", + "src": "5516:10:4" + }, + { + "attributes": { + "hexvalue": "74727565", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "token": "bool", + "type": "bool", + "value": "true" + }, + "id": 1452, + "name": "Literal", + "src": "5529:4:4" + } + ], + "id": 1453, + "name": "Assignment", + "src": "5516:17:4" + } + ], + "id": 1454, + "name": "ExpressionStatement", + "src": "5516:17:4" + } + ], + "id": 1455, + "name": "Block", + "src": "5450:94:4" + } + ], + "id": 1456, + "name": "IfStatement", + "src": "4940:604:4" + } + ], + "id": 1457, + "name": "IfStatement", + "src": "4796:748:4" + }, + { + "attributes": { + "functionReturnParameters": 1390 + }, + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "type": "address" + }, + "children": [ + { + "attributes": { + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "&&", + "type": "bool" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1395, + "type": "bool", + "value": "isAnswered" + }, + "id": 1458, + "name": "Identifier", + "src": "5561:10:4" + }, + { + "attributes": { + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "==", + "type": "bool" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1392, + "type": "bytes32", + "value": "lastAnswer" + }, + "id": 1459, + "name": "Identifier", + "src": "5575:10:4" + }, + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": [ + null + ], + "tryCall": false, + "type": "bytes32", + "type_conversion": true + }, + "children": [ + { + "attributes": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "type": "type(bytes32)" + }, + "children": [ + { + "attributes": { + "name": "bytes32" + }, + "id": 1460, + "name": "ElementaryTypeName", + "src": "5589:7:4" + } + ], + "id": 1461, + "name": "ElementaryTypeNameExpression", + "src": "5589:7:4" + }, + { + "attributes": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "-", + "type": "uint256" + }, + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "answer", + "referencedDeclaration": 103, + "type": "uint256" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1378, + "type": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage pointer", + "value": "_arbitrationRequest" + }, + "id": 1462, + "name": "Identifier", + "src": "5597:19:4" + } + ], + "id": 1463, + "name": "MemberAccess", + "src": "5597:26:4" + }, + { + "attributes": { + "hexvalue": "31", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "token": "number", + "type": "int_const 1", + "value": "1" + }, + "id": 1464, + "name": "Literal", + "src": "5626:1:4" + } + ], + "id": 1465, + "name": "BinaryOperation", + "src": "5597:30:4" + } + ], + "id": 1466, + "name": "FunctionCall", + "src": "5589:39:4" + } + ], + "id": 1467, + "name": "BinaryOperation", + "src": "5575:53:4" + } + ], + "id": 1468, + "name": "BinaryOperation", + "src": "5561:67:4" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1384, + "type": "address", + "value": "_lastAnswerer" + }, + "id": 1469, + "name": "Identifier", + "src": "5631:13:4" + }, + { + "attributes": { + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "disputer", + "referencedDeclaration": 99, + "type": "address" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1378, + "type": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage pointer", + "value": "_arbitrationRequest" + }, + "id": 1470, + "name": "Identifier", + "src": "5647:19:4" + } + ], + "id": 1471, + "name": "MemberAccess", + "src": "5647:28:4" + } + ], + "id": 1472, + "name": "Conditional", + "src": "5561:114:4" + } + ], + "id": 1473, + "name": "Return", + "src": "5554:121:4" + } + ], + "id": 1474, + "name": "Block", + "src": "4733:949:4" + } + ], + "id": 1475, + "name": "FunctionDefinition", + "src": "4480:1202:4" + } + ], + "id": 1476, + "name": "ContractDefinition", + "src": "1135:4549:4" + } + ], + "id": 1477, + "name": "SourceUnit", + "src": "194:5491:4" + }, + "compiler": { + "name": "solc", + "version": "0.7.6+commit.7338295f.Emscripten.clang" + }, + "networks": {}, + "schemaVersion": "3.4.0", + "updatedAt": "2021-05-24T04:56:06.516Z", + "devdoc": { + "details": "A Realitio arbitrator implementation that uses Realitio v2.0 and Kleros. It notifies Realitio contract for arbitration requests and creates corresponding dispute on Kleros. Transmits Kleros ruling to Realitio contract. Maintains crowdfunded appeals and notifies Kleros contract. Provides a function to submit evidence for Kleros dispute. There is a conversion between Kleros ruling and Realitio answer and there is a need for shifting by 1. This is because ruling 0 in Kleros signals tie or no-ruling but in Realitio 0 is a valid answer. For reviewers this should be a focus as it's quite easy to get confused. Any mistakes on this conversion will render this contract useless. NOTE: This contract trusts the Kleros arbitrator and Realitio.", + "kind": "dev", + "methods": { + "changeGovernor(address)": { + "params": { + "_governor": "The address of the new governor." + } + }, + "changeMetaEvidence(string)": { + "details": "Updates the meta evidence used for disputes. This function needs to be executed at least once before requesting arbitration, because we don't emit MetaEvidence during construction.", + "params": { + "_metaEvidence": "URI to the new meta evidence file." + } + }, + "changeMultipliers(uint256,uint256,uint256)": { + "details": "Changes the proportion of appeal fees that must be paid by winner and loser and changes the appeal period portion for losers.", + "params": { + "_loserAppealPeriodMultiplier": "The new loser appeal period multiplier respect to DENOMINATOR.", + "_loserStakeMultiplier": "The new loser stake multiplier value respect to DENOMINATOR.", + "_winnerStakeMultiplier": "The new winner stake multiplier value respect to DENOMINATOR." + } + }, + "computeWinnerAndReportAnswer(bytes32,bytes32,bytes32,uint256,address,bool)": { + "details": "Compute winner and report the answer to a specified question from the ERC792 arbitrator to the Realitio v2.0 contract. TRUSTED.", + "params": { + "_isCommitment": "Whether the last answer to the question in the Realitio contract used commit or reveal or not. True if it did, false otherwise.", + "_lastAnswerOrCommitmentID": "The last answer given, or its commitment ID if it was a commitment, to the question in the Realitio contract.", + "_lastAnswerer": "The last answerer to the question in the Realitio contract.", + "_lastBond": "The bond paid for the last answer to the question in the Realitio contract.", + "_lastHistoryHash": "The history hash given with the last answer to the question in the Realitio contract.", + "_questionID": "The ID of the question." + } + }, + "constructor": { + "details": "Constructor.", + "params": { + "_arbitrator": "The address of the ERC792 arbitrator.", + "_arbitratorExtraData": "The extra data used to raise a dispute in the ERC792 arbitrator.", + "_metadata": "The metadata required for RealitioArbitrator.", + "_realitio": "The address of the Realitio contract." + } + }, + "fundAppeal(uint256,uint256)": { + "details": "TRUSTED. Manages crowdfunded appeals contributions and calls appeal function of the Kleros arbitrator to appeal a dispute. Note that we don’t need to check that msg.value is enough to pay arbitration fees as it’s the responsibility of the arbitrator contract.", + "params": { + "_questionID": "Identifier of the Realitio question, casted to uint. This also serves as the local identifier in this contract.", + "_ruling": "The ruling option to which the caller wants to contribute to." + }, + "returns": { + "fullyFunded": "True if the ruling option got fully funded as a result of this contribution." + } + }, + "getDisputeFee(bytes32)": { + "details": "Returns arbitration fee by calling arbitrationCost function in the arbitrator contract.", + "returns": { + "fee": "Arbitration that needs to be paid." + } + }, + "getMultipliers()": { + "details": "Calculate history has for givenReturns multipliers for appeals.", + "returns": { + "_denominator": "Multiplier denominator in basis points. Required for achieving floating-point-like behavior.", + "_loserAppealPeriodMultiplier": "Losers appeal period multiplier. The loser is given less time to fund its appeal to defend against last minute appeal funding attacks.", + "_loserStakeMultiplier": "Losers stake multiplier.", + "_winnerStakeMultiplier": "Winners stake multiplier." + } + }, + "getTotalWithdrawableAmount(uint256,address,uint256[])": { + "details": "Returns the sum of withdrawable amount.", + "params": { + "_contributedTo": "Ruling options to look for potential withdrawals.", + "_contributor": "The contributor for which to query.", + "_questionID": "Identifier of the Realitio question, casted to uint. This also serves as the local identifier in this contract." + }, + "returns": { + "sum": "The total amount available to withdraw." + } + }, + "numberOfRulingOptions(uint256)": { + "details": "Returns number of possible ruling options. Valid rulings are [0, count].", + "returns": { + "count": "The number of ruling options." + } + }, + "requestArbitration(bytes32,uint256)": { + "details": "Request arbitration from Kleros for given _questionID.", + "params": { + "_maxPrevious": "If specified, reverts if a bond higher than this was submitted after you sent your transaction.", + "_questionID": "The question identifier in Realitio contract." + }, + "returns": { + "disputeID": "ID of the resulting dispute on arbitrator." + } + }, + "rule(uint256,uint256)": { + "details": "Receives ruling from Kleros and enforces it.", + "params": { + "_disputeID": "ID of Kleros dispute.", + "_ruling": "Ruling that is given by Kleros. This needs to be converted to Realitio answer before reporting the answer by shifting by 1." + } + }, + "submitEvidence(uint256,string)": { + "details": "Allows to submit evidence for a given dispute.", + "params": { + "_evidenceURI": "Link to evidence.", + "_questionID": "Realitio question identifier." + } + }, + "withdrawFeesAndRewards(uint256,address,uint256,uint256)": { + "details": "Allows to withdraw any reimbursable fees or rewards after the dispute gets solved.", + "params": { + "_contributor": "The address whose rewards to withdraw.", + "_questionID": "Identifier of the Realitio question, casted to uint. This also serves as the local identifier in this contract.", + "_roundNumber": "The number of the round caller wants to withdraw from.", + "_ruling": "Ruling that received contribution from contributor." + }, + "returns": { + "amount": "The amount available to withdraw for given question, contributor, round number and ruling option." + } + }, + "withdrawFeesAndRewardsForAllRounds(uint256,address,uint256[])": { + "details": "Allows to withdraw any rewards or reimbursable fees after the dispute gets resolved. For multiple rulings options and for all rounds at once. This function has O(m*n) time complexity where m is number of rounds and n is the number of ruling options contributed by given user. It is safe to assume m is always less than 10 as appeal cost growth order is O(m^2).", + "params": { + "_contributedTo": "Rulings that received contributions from contributor.", + "_contributor": "The address whose rewards to withdraw.", + "_questionID": "Identifier of the Realitio question, casted to uint. This also serves as the local identifier in this contract." + } + }, + "withdrawFeesAndRewardsForMultipleRulings(uint256,address,uint256,uint256[])": { + "details": "Allows to withdraw any reimbursable fees or rewards after the dispute gets solved. For multiple ruling options at once. This function has O(n) time complexity where n is number of ruling options contributed by given user. It is safe to assume n is always less than 3 as it does not make sense to contribute to different ruling options in the same round, so it will rarely be greater than 1.", + "params": { + "_contributedTo": "Rulings that received contributions from contributor.", + "_contributor": "The address whose rewards to withdraw.", + "_questionID": "Identifier of the Realitio question, casted to uint. This also serves as the local identifier in this contract.", + "_roundNumber": "The number of the round caller wants to withdraw from." + } + } + }, + "title": "Realitio_v2_0_ArbitratorWithAppeals", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "changeGovernor(address)": { + "notice": "Changes the address of the governor." + } + }, + "version": 1 + } +} \ No newline at end of file diff --git a/lib/assets/contracts/Realitio_v2_1.json b/lib/assets/contracts/Realitio_v2_1.json new file mode 100644 index 0000000..cc452eb --- /dev/null +++ b/lib/assets/contracts/Realitio_v2_1.json @@ -0,0 +1,59728 @@ +{ + "contractName": "Realitio_v2_1", + "abi": [ + { + "constant": false, + "inputs": [], + "name": "withdraw", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + } + ], + "name": "template_hashes", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "name": "question_claims", + "outputs": [ + { + "name": "payee", + "type": "address" + }, + { + "name": "last_bond", + "type": "uint256" + }, + { + "name": "queued_funds", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + } + ], + "name": "arbitrator_question_fees", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "name": "commitments", + "outputs": [ + { + "name": "reveal_ts", + "type": "uint32" + }, + { + "name": "is_revealed", + "type": "bool" + }, + { + "name": "revealed_answer", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "name": "questions", + "outputs": [ + { + "name": "content_hash", + "type": "bytes32" + }, + { + "name": "arbitrator", + "type": "address" + }, + { + "name": "opening_ts", + "type": "uint32" + }, + { + "name": "timeout", + "type": "uint32" + }, + { + "name": "finalize_ts", + "type": "uint32" + }, + { + "name": "is_pending_arbitration", + "type": "bool" + }, + { + "name": "bounty", + "type": "uint256" + }, + { + "name": "best_answer", + "type": "bytes32" + }, + { + "name": "history_hash", + "type": "bytes32" + }, + { + "name": "bond", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + } + ], + "name": "templates", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "arbitrator", + "type": "address" + }, + { + "indexed": false, + "name": "amount", + "type": "uint256" + } + ], + "name": "LogSetQuestionFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "template_id", + "type": "uint256" + }, + { + "indexed": true, + "name": "user", + "type": "address" + }, + { + "indexed": false, + "name": "question_text", + "type": "string" + } + ], + "name": "LogNewTemplate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "question_id", + "type": "bytes32" + }, + { + "indexed": true, + "name": "user", + "type": "address" + }, + { + "indexed": false, + "name": "template_id", + "type": "uint256" + }, + { + "indexed": false, + "name": "question", + "type": "string" + }, + { + "indexed": true, + "name": "content_hash", + "type": "bytes32" + }, + { + "indexed": false, + "name": "arbitrator", + "type": "address" + }, + { + "indexed": false, + "name": "timeout", + "type": "uint32" + }, + { + "indexed": false, + "name": "opening_ts", + "type": "uint32" + }, + { + "indexed": false, + "name": "nonce", + "type": "uint256" + }, + { + "indexed": false, + "name": "created", + "type": "uint256" + } + ], + "name": "LogNewQuestion", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "question_id", + "type": "bytes32" + }, + { + "indexed": false, + "name": "bounty_added", + "type": "uint256" + }, + { + "indexed": false, + "name": "bounty", + "type": "uint256" + }, + { + "indexed": true, + "name": "user", + "type": "address" + } + ], + "name": "LogFundAnswerBounty", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "answer", + "type": "bytes32" + }, + { + "indexed": true, + "name": "question_id", + "type": "bytes32" + }, + { + "indexed": false, + "name": "history_hash", + "type": "bytes32" + }, + { + "indexed": true, + "name": "user", + "type": "address" + }, + { + "indexed": false, + "name": "bond", + "type": "uint256" + }, + { + "indexed": false, + "name": "ts", + "type": "uint256" + }, + { + "indexed": false, + "name": "is_commitment", + "type": "bool" + } + ], + "name": "LogNewAnswer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "question_id", + "type": "bytes32" + }, + { + "indexed": true, + "name": "user", + "type": "address" + }, + { + "indexed": true, + "name": "answer_hash", + "type": "bytes32" + }, + { + "indexed": false, + "name": "answer", + "type": "bytes32" + }, + { + "indexed": false, + "name": "nonce", + "type": "uint256" + }, + { + "indexed": false, + "name": "bond", + "type": "uint256" + } + ], + "name": "LogAnswerReveal", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "question_id", + "type": "bytes32" + }, + { + "indexed": true, + "name": "user", + "type": "address" + } + ], + "name": "LogNotifyOfArbitrationRequest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "question_id", + "type": "bytes32" + } + ], + "name": "LogCancelArbitration", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "question_id", + "type": "bytes32" + }, + { + "indexed": true, + "name": "answer", + "type": "bytes32" + } + ], + "name": "LogFinalize", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "question_id", + "type": "bytes32" + }, + { + "indexed": true, + "name": "user", + "type": "address" + }, + { + "indexed": false, + "name": "amount", + "type": "uint256" + } + ], + "name": "LogClaim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "user", + "type": "address" + }, + { + "indexed": false, + "name": "amount", + "type": "uint256" + } + ], + "name": "LogWithdraw", + "type": "event" + }, + { + "constant": false, + "inputs": [ + { + "name": "fee", + "type": "uint256" + } + ], + "name": "setQuestionFee", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "content", + "type": "string" + } + ], + "name": "createTemplate", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "content", + "type": "string" + }, + { + "name": "question", + "type": "string" + }, + { + "name": "arbitrator", + "type": "address" + }, + { + "name": "timeout", + "type": "uint32" + }, + { + "name": "opening_ts", + "type": "uint32" + }, + { + "name": "nonce", + "type": "uint256" + } + ], + "name": "createTemplateAndAskQuestion", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "template_id", + "type": "uint256" + }, + { + "name": "question", + "type": "string" + }, + { + "name": "arbitrator", + "type": "address" + }, + { + "name": "timeout", + "type": "uint32" + }, + { + "name": "opening_ts", + "type": "uint32" + }, + { + "name": "nonce", + "type": "uint256" + } + ], + "name": "askQuestion", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + } + ], + "name": "fundAnswerBounty", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + }, + { + "name": "answer", + "type": "bytes32" + }, + { + "name": "max_previous", + "type": "uint256" + } + ], + "name": "submitAnswer", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + }, + { + "name": "answer", + "type": "bytes32" + }, + { + "name": "max_previous", + "type": "uint256" + }, + { + "name": "answerer", + "type": "address" + } + ], + "name": "submitAnswerFor", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + }, + { + "name": "answer_hash", + "type": "bytes32" + }, + { + "name": "max_previous", + "type": "uint256" + }, + { + "name": "_answerer", + "type": "address" + } + ], + "name": "submitAnswerCommitment", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + }, + { + "name": "answer", + "type": "bytes32" + }, + { + "name": "nonce", + "type": "uint256" + }, + { + "name": "bond", + "type": "uint256" + } + ], + "name": "submitAnswerReveal", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + }, + { + "name": "requester", + "type": "address" + }, + { + "name": "max_previous", + "type": "uint256" + } + ], + "name": "notifyOfArbitrationRequest", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + } + ], + "name": "cancelArbitration", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + }, + { + "name": "answer", + "type": "bytes32" + }, + { + "name": "answerer", + "type": "address" + } + ], + "name": "submitAnswerByArbitrator", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + }, + { + "name": "answer", + "type": "bytes32" + }, + { + "name": "payee_if_wrong", + "type": "address" + }, + { + "name": "last_history_hash", + "type": "bytes32" + }, + { + "name": "last_answer_or_commitment_id", + "type": "bytes32" + }, + { + "name": "last_answerer", + "type": "address" + } + ], + "name": "assignWinnerAndSubmitAnswerByArbitrator", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + } + ], + "name": "isFinalized", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + } + ], + "name": "getFinalAnswer", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + } + ], + "name": "resultFor", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + }, + { + "name": "content_hash", + "type": "bytes32" + }, + { + "name": "arbitrator", + "type": "address" + }, + { + "name": "min_timeout", + "type": "uint32" + }, + { + "name": "min_bond", + "type": "uint256" + } + ], + "name": "getFinalAnswerIfMatches", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + }, + { + "name": "history_hashes", + "type": "bytes32[]" + }, + { + "name": "addrs", + "type": "address[]" + }, + { + "name": "bonds", + "type": "uint256[]" + }, + { + "name": "answers", + "type": "bytes32[]" + } + ], + "name": "claimWinnings", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "question_ids", + "type": "bytes32[]" + }, + { + "name": "lengths", + "type": "uint256[]" + }, + { + "name": "hist_hashes", + "type": "bytes32[]" + }, + { + "name": "addrs", + "type": "address[]" + }, + { + "name": "bonds", + "type": "uint256[]" + }, + { + "name": "answers", + "type": "bytes32[]" + } + ], + "name": "claimMultipleAndWithdrawBalance", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + } + ], + "name": "getContentHash", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + } + ], + "name": "getArbitrator", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + } + ], + "name": "getOpeningTS", + "outputs": [ + { + "name": "", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + } + ], + "name": "getTimeout", + "outputs": [ + { + "name": "", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + } + ], + "name": "getFinalizeTS", + "outputs": [ + { + "name": "", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + } + ], + "name": "isPendingArbitration", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + } + ], + "name": "getBounty", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + } + ], + "name": "getBestAnswer", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + } + ], + "name": "getHistoryHash", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "question_id", + "type": "bytes32" + } + ], + "name": "getBond", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x608060405260006001553480156200001657600080fd5b506200008d606060405190810160405280603f81526020017f7b227469746c65223a20222573222c202274797065223a2022626f6f6c222c2081526020017f2263617465676f7279223a20222573222c20226c616e67223a20222573227d0081525062000308640100000000026401000000009004565b506200012a608060405190810160405280604f81526020017f7b227469746c65223a20222573222c202274797065223a202275696e74222c2081526020017f22646563696d616c73223a2031382c202263617465676f7279223a202225732281526020017f2c20226c616e67223a20222573227d000000000000000000000000000000000081525062000308640100000000026401000000009004565b50620001c7608060405190810160405280605a81526020017f7b227469746c65223a20222573222c202274797065223a202273696e676c652d81526020017f73656c656374222c20226f7574636f6d6573223a205b25735d2c20226361746581526020017f676f7279223a20222573222c20226c616e67223a20222573227d00000000000081525062000308640100000000026401000000009004565b5062000264608060405190810160405280605c81526020017f7b227469746c65223a20222573222c202274797065223a20226d756c7469706c81526020017f652d73656c656374222c20226f7574636f6d6573223a205b25735d2c2022636181526020017f7465676f7279223a20222573222c20226c616e67223a20222573227d0000000081525062000308640100000000026401000000009004565b5062000301608060405190810160405280604381526020017f7b227469746c65223a20222573222c202274797065223a20226461746574696d81526020017f65222c202263617465676f7279223a20222573222c20226c616e67223a20222581526020017f73227d000000000000000000000000000000000000000000000000000000000081525062000308640100000000026401000000009004565b50620004ca565b60015460008181526002602090815260408083204390555184519293928592918201918291908401908083835b60208310620003565780518252601f19909201916020918201910162000335565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040526040518082805190602001908083835b60208310620003bb5780518252601f1990920191602091820191016200039a565b51815160209384036101000a6000190180199092169116179052604080519290940182900382206000888152600383528581209190915581835289518383015289513397508896507fb87fb721c0a557bb8dff89a86796466931d82ba530a66a239263eb8735ade2e4958b955084939084019290860191908190849084905b83811015620004545781810151838201526020016200043a565b50505050905090810190601f168015620004825780820380516001836020036101000a031916815260200191505b509250505060405180910390a3620004aa81600164010000000062003739620004b382021704565b60015592915050565b600082820183811015620004c357fe5b9392505050565b6140a980620004da6000396000f3006080604052600436106101b35763ffffffff60e060020a6000350416631101a0fd81146101b8578063111ec138146102bf57806312a203c3146102dc5780632417395c146103215780632518904c1461033957806326d6c97b1461036d57806328828b1e146103855780633ccfd60b146104f75780634dc266b41461050c5780634df6ca2a1461052d5780634e60f8831461054557806351577ea91461055d578063590158a71461057557806359245ff3146105b55780636fa42742146105c057806370a08231146105e1578063762c38fd1461060257806377f325df146106785780637f8d429e1461068957806382ffa9f7146106b5578063839df945146106cd57806383bf46091461070a5780638d552d4614610763578063924532fb1461077b57806395addb90146107935780639e63fa6a1461080f5780639f1025c614610840578063a1130d0414610858578063a462fb7b14610907578063acae8f4e1461091f578063bc52565214610937578063d09cc57e14610907578063d44e293c1461094f578063d7cff98614610984578063ebbdd2b0146109a1578063f6a94ecb146109b9578063fe92049d146109e0575b600080fd5b3480156101c457600080fd5b506040805160206004602480358281013584810280870186019097528086526102bd96843596369660449591949091019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750610a079650505050505050565b005b6102bd600435602435604435600160a060020a0360643516610d62565b3480156102e857600080fd5b5061030f600435602435600160a060020a036044351663ffffffff60643516608435611145565b60408051918252519081900360200190f35b34801561032d57600080fd5b5061030f600435611382565b34801561034557600080fd5b50610351600435611397565b60408051600160a060020a039092168252519081900360200190f35b34801561037957600080fd5b5061030f6004356113b5565b34801561039157600080fd5b50604080516020600480358082013583810280860185019096528085526102bd95369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a9989019892975090820195509350839250850190849080828437509497506113ca9650505050505050565b34801561050357600080fd5b506102bd6115de565b34801561051857600080fd5b506102bd600435602435604435606435611659565b34801561053957600080fd5b506102bd600435611af9565b34801561055157600080fd5b5061030f600435611b48565b34801561056957600080fd5b5061030f600435611b5a565b34801561058157600080fd5b5061058d600435611b6c565b60408051600160a060020a039094168452602084019290925282820152519081900360600190f35b6102bd600435611b97565b3480156105cc57600080fd5b5061030f600160a060020a0360043516611df4565b3480156105ed57600080fd5b5061030f600160a060020a0360043516611e06565b60408051602060046024803582810135601f810185900485028601850190965285855261030f95833595369560449491939091019190819084018382808284375094975050508335600160a060020a03169450505050602081013563ffffffff9081169160408101359091169060600135611e18565b6102bd60043560243560443561213c565b34801561069557600080fd5b506106a16004356124be565b604080519115158252519081900360200190f35b3480156106c157600080fd5b5061030f60043561251b565b3480156106d957600080fd5b506106e5600435612530565b6040805163ffffffff9094168452911515602084015282820152519081900360600190f35b34801561071657600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261030f94369492936024939284019190819084018382808284375094975061255d9650505050505050565b34801561076f57600080fd5b5061030f6004356126f7565b34801561078757600080fd5b506106a160043561270d565b34801561079f57600080fd5b506107ab600435612725565b604080519a8b52600160a060020a0390991660208b015263ffffffff9788168a8a015295871660608a015293909516608088015290151560a087015260c086015260e085019290925261010084019190915261012083015251908190036101400190f35b34801561081b57600080fd5b50610827600435612790565b6040805163ffffffff9092168252519081900360200190f35b34801561084c57600080fd5b506108276004356127b2565b6040805160206004803580820135601f810184900484028501840190955284845261030f94369492936024939284019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375094975050508335600160a060020a03169450505050602081013563ffffffff90811691604081013590911690606001356127d4565b34801561091357600080fd5b5061030f6004356127fc565b34801561092b57600080fd5b50610827600435612876565b34801561094357600080fd5b5061030f600435612898565b34801561095b57600080fd5b506102bd600435602435600160a060020a03604435811690606435906084359060a435166128aa565b6102bd600435602435604435600160a060020a03606435166129d2565b3480156109ad57600080fd5b506102bd600435612ddb565b3480156109c557600080fd5b506102bd600435600160a060020a0360243516604435612f91565b3480156109ec57600080fd5b506102bd600435602435600160a060020a0360443516613355565b60008060008060008060008b610a1c816124be565b1515610a72576040805160e560020a62461bcd02815260206004820152601a60248201527f7175657374696f6e206d7573742062652066696e616c697a6564000000000000604482015290519081900360640190fd5b8b51600010610af1576040805160e560020a62461bcd02815260206004820152603060248201527f6174206c65617374206f6e6520686973746f7279206861736820656e7472792060448201527f6d7573742062652070726f766964656400000000000000000000000000000000606482015290519081900360840190fd5b60008d815260056020818152604080842080546001820154600290920154600494859052928620948501549490930154600160a060020a039093169c509a509850909650945092505b8b51831015610c8557610bac858d85815181101515610b5557fe5b906020019060200201518b86815181101515610b6d57fe5b906020019060200201518d87815181101515610b8557fe5b906020019060200201518f88815181101515610b9d57fe5b90602001906020020151613523565b9150610bbe868863ffffffff61373916565b9550610c158d85888b8f88815181101515610bd557fe5b906020019060200201518f89815181101515610bed57fe5b906020019060200201518f8a815181101515610c0557fe5b9060200190602002015189613753565b8b519099509096508a9084908110610c2957fe5b602090810290910181015160008f815260049092526040909120600601549097508714610c6057610c5d8760288104613883565b96505b8b83815181101515610c6e57fe5b602090810290910101519450600190920191610b3a565b8415610cf057600160a060020a03881615610caa57610ca58d8988613895565b600095505b60008d8152600560205260409020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038a1617815560018101889055600201869055610d3f565b610d0a8d89610d05898b63ffffffff61373916565b613895565b60008d8152600560205260408120805473ffffffffffffffffffffffffffffffffffffffff1916815560018101829055600201555b5050506000998a5250600460205260409098206005019790975550505050505050565b600084815260046020526040812060010154859190819060c060020a900463ffffffff168110610dca576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613f9e833981519152604482015290519081900360640190fd5b60008381526004602052604090206002015460ff1615610e36576040805160e560020a62461bcd0281526020600482015260286024820152600080516020613ffe8339815191526044820152600080516020613fbe833981519152606482015290519081900360840190fd5b60008381526004602052604090206001015460e060020a900463ffffffff169150811580610e6f57504263ffffffff168263ffffffff16115b1515610ec7576040805160e560020a62461bcd02815260206004820152602a602482015260008051602061401e833981519152604482015260008051602061405e833981519152606482015290519081900360840190fd5b5060008281526004602052604090206001015460a060020a900463ffffffff16801580610f0057504263ffffffff168163ffffffff1611155b1515610f44576040805160e560020a62461bcd02815260206004820152601d602482015260008051602061403e833981519152604482015290519081900360640190fd5b8660003411610f9d576040805160e560020a62461bcd02815260206004820152601560248201527f626f6e64206d75737420626520706f7369746976650000000000000000000000604482015290519081900360640190fd5b600081815260046020526040902060060154610fc090600263ffffffff61391616565b34101561103d576040805160e560020a62461bcd02815260206004820152602a60248201527f626f6e64206d75737420626520646f75626c65206174206c656173742070726560448201527f76696f757320626f6e6400000000000000000000000000000000000000000000606482015290519081900360840190fd5b8786600081111561109f5760008281526004602052604090206006015481101561109f576040805160e560020a62461bcd02815260206004820152601d6024820152600080516020613fde833981519152604482015290519081900360640190fd5b600160a060020a03871615156110ff576040805160e560020a62461bcd02815260206004820152601960248201527f616e737765726572206d757374206265206e6f6e2d7a65726f00000000000000604482015290519081900360640190fd5b61110d8a8a89346000613941565b60008a815260046020526040902060010154611139908b908b9060c060020a900463ffffffff16613ab9565b50505050505050505050565b600085611151816124be565b15156111a7576040805160e560020a62461bcd02815260206004820152601a60248201527f7175657374696f6e206d7573742062652066696e616c697a6564000000000000604482015290519081900360640190fd5b600087815260046020526040902054861461120c576040805160e560020a62461bcd02815260206004820152601760248201527f636f6e74656e742068617368206d757374206d61746368000000000000000000604482015290519081900360640190fd5b600087815260046020526040902060010154600160a060020a03868116911614611280576040805160e560020a62461bcd02815260206004820152601560248201527f61726269747261746f72206d757374206d617463680000000000000000000000604482015290519081900360640190fd5b60008781526004602052604090206001015463ffffffff60c060020a909104811690851611156112fa576040805160e560020a62461bcd02815260206004820152601b60248201527f74696d656f7574206d757374206265206c6f6e6720656e6f7567680000000000604482015290519081900360640190fd5b600087815260046020526040902060060154831115611363576040805160e560020a62461bcd02815260206004820152601860248201527f626f6e64206d757374206265206869676820656e6f7567680000000000000000604482015290519081900360640190fd5b6000878152600460208190526040909120015491505095945050505050565b60009081526004602052604090206003015490565b600090815260046020526040902060010154600160a060020a031690565b60009081526004602052604090206006015490565b60008080806060808080845b8e518910156115c5578e898151811015156113ed57fe5b9060200190602002015196508d8981518110151561140757fe5b9060200190602002015195508560405190808252806020026020018201604052801561143d578160200160208202803883390190505b5094508560405190808252806020026020018201604052801561146a578160200160208202803883390190505b50935085604051908082528060200260200182016040528015611497578160200160208202803883390190505b509250856040519080825280602002602001820160405280156114c4578160200160208202803883390190505b509150600090505b858110156115ad578c888151811015156114e257fe5b9060200190602002015185828151811015156114fa57fe5b602090810290910101528b518c908990811061151257fe5b90602001906020020151848281518110151561152a57fe5b600160a060020a039092166020928302909101909101528a518b908990811061154f57fe5b90602001906020020151838281518110151561156757fe5b6020908102909101015289518a908990811061157f57fe5b90602001906020020151828281518110151561159757fe5b60209081029091010152600197880197016114cc565b6115ba8786868686610a07565b6001909801976113d6565b6115cd6115de565b505050505050505050505050505050565b33600081815260208190526040808220805490839055905190929183156108fc02918491818181858888f1935050505015801561161f573d6000803e3d6000fd5b5060408051828152905133917f4ce7033d118120e254016dccf195288400b28fc8936425acd5f17ce2df3ab708919081900360200190a250565b600084815260046020526040812060010154819086908290819060c060020a900463ffffffff1681106116c4576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613f9e833981519152604482015290519081900360640190fd5b60008381526004602052604090206001015460e060020a900463ffffffff1691508115806116fd57504263ffffffff168263ffffffff16115b1515611779576040805160e560020a62461bcd02815260206004820152602960248201527f66696e616c697a6174696f6e206465616c696e65206d757374206e6f7420686160448201527f7665207061737365640000000000000000000000000000000000000000000000606482015290519081900360840190fd5b5060008281526004602052604090206001015460a060020a900463ffffffff168015806117b257504263ffffffff168163ffffffff1611155b15156117f6576040805160e560020a62461bcd02815260206004820152601d602482015260008051602061403e833981519152604482015290519081900360640190fd5b6040805160208082018b90528183018a9052825180830384018152606090920192839052815191929182918401908083835b602083106118475780518252601f199092019160209182019101611828565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209450888587604051602001808460001916600019168152602001836000191660001916815260200182815260200193505050506040516020818303038152906040526040518082805190602001908083835b602083106118e55780518252601f1990920191602091820191016118c6565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120600081815260069092529290205491975050640100000000900460ff161591506119a99050576040805160e560020a62461bcd02815260206004820152602a60248201527f636f6d6d69746d656e74206d757374206e6f742068617665206265656e20726560448201527f7665616c65642079657400000000000000000000000000000000000000000000606482015290519081900360840190fd5b60008481526006602052604090205463ffffffff428116911611611a3c576040805160e560020a62461bcd028152602060048201526024808201527f72657665616c20646561646c696e65206d757374206e6f74206861766520706160448201527f7373656400000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6000848152600660208181526040808420600181018d9055805464ff0000000019166401000000001790558c845260049091529091200154861415611aa757600089815260046020526040902060010154611aa7908a908a9060c060020a900463ffffffff16613ab9565b60408051898152602081018990528082018890529051869133918c917fa7b2d313bc7a062e30b2c3b811aa4c9faf09755a6b4ea3bf42deff920944332f919081900360600190a4505050505050505050565b336000818152600760209081526040918290208490558151928352820183905280517fdca703d022171824d3d639b33c1525fd2338120b4cfb89507c0b59596893acda9281900390910190a150565b60036020526000908152604090205481565b60009081526004602052604090205490565b600560205260009081526040902080546001820154600290920154600160a060020a03909116919083565b600081815260046020526040812060010154829190819060c060020a900463ffffffff168110611bff576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613f9e833981519152604482015290519081900360640190fd5b60008381526004602052604090206002015460ff1615611c6b576040805160e560020a62461bcd0281526020600482015260286024820152600080516020613ffe8339815191526044820152600080516020613fbe833981519152606482015290519081900360840190fd5b60008381526004602052604090206001015460e060020a900463ffffffff169150811580611ca457504263ffffffff168263ffffffff16115b1515611cfc576040805160e560020a62461bcd02815260206004820152602a602482015260008051602061401e833981519152604482015260008051602061405e833981519152606482015290519081900360840190fd5b5060008281526004602052604090206001015460a060020a900463ffffffff16801580611d3557504263ffffffff168163ffffffff1611155b1515611d79576040805160e560020a62461bcd02815260206004820152601d602482015260008051602061403e833981519152604482015290519081900360640190fd5b600084815260046020526040902060030154611d9b903463ffffffff61373916565b6000858152600460209081526040918290206003018390558151348152908101929092528051339287927f54d68405b79f2aa4fd4e8db7b67844ad254cf8f208aac476c2894134a9deab6692918290030190a350505050565b60076020526000908152604090205481565b60006020819052908152604090205481565b600086815260026020526040812054819081908110611e81576040805160e560020a62461bcd02815260206004820152601360248201527f74656d706c617465206d75737420657869737400000000000000000000000000604482015290519081900360640190fd5b888589604051602001808481526020018363ffffffff1663ffffffff1660e060020a02815260040182805190602001908083835b60208310611ed45780518252601f199092019160209182019101611eb5565b6001836020036101000a03801982511681845116808217855250505050505090500193505050506040516020818303038152906040526040518082805190602001908083835b60208310611f395780518252601f199092019160209182019101611f1a565b51815160209384036101000a600019018019909216911617905260408051929094018290038220828201819052600160a060020a038e166c010000000000000000000000009081028487015263ffffffff8e1660e060020a02605485015233026058840152606c8084018c905285518085039091018152608c9093019485905282519098509195509293508392850191508083835b60208310611fed5780518252601f199092019160209182019101611fce565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902090506120298183898989613b30565b816000191633600160a060020a031682600019167ffe2dac156a3890636ce13f65f4fdf41dcaee11526e4a5374531572d92194796c8c8c8c8c8c8c42604051808881526020018060200187600160a060020a0316600160a060020a031681526020018663ffffffff1663ffffffff1681526020018563ffffffff1663ffffffff168152602001848152602001838152602001828103825288818151815260200191508051906020019080838360005b838110156120f05781810151838201526020016120d8565b50505050905090810190601f16801561211d5780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390a498975050505050505050565b600083815260046020526040812060010154849190819060c060020a900463ffffffff1681106121a4576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613f9e833981519152604482015290519081900360640190fd5b60008381526004602052604090206002015460ff1615612210576040805160e560020a62461bcd0281526020600482015260286024820152600080516020613ffe8339815191526044820152600080516020613fbe833981519152606482015290519081900360840190fd5b60008381526004602052604090206001015460e060020a900463ffffffff16915081158061224957504263ffffffff168263ffffffff16115b15156122a1576040805160e560020a62461bcd02815260206004820152602a602482015260008051602061401e833981519152604482015260008051602061405e833981519152606482015290519081900360840190fd5b5060008281526004602052604090206001015460a060020a900463ffffffff168015806122da57504263ffffffff168163ffffffff1611155b151561231e576040805160e560020a62461bcd02815260206004820152601d602482015260008051602061403e833981519152604482015290519081900360640190fd5b8560003411612377576040805160e560020a62461bcd02815260206004820152601560248201527f626f6e64206d75737420626520706f7369746976650000000000000000000000604482015290519081900360640190fd5b60008181526004602052604090206006015461239a90600263ffffffff61391616565b341015612417576040805160e560020a62461bcd02815260206004820152602a60248201527f626f6e64206d75737420626520646f75626c65206174206c656173742070726560448201527f76696f757320626f6e6400000000000000000000000000000000000000000000606482015290519081900360840190fd5b8685600081111561247957600082815260046020526040902060060154811015612479576040805160e560020a62461bcd02815260206004820152601d6024820152600080516020613fde833981519152604482015290519081900360640190fd5b612487898933346000613941565b6000898152600460205260409020600101546124b3908a908a9060c060020a900463ffffffff16613ab9565b505050505050505050565b6000818152600460205260408120600181015460029091015460e060020a90910463ffffffff169060ff161580156124fc5750600063ffffffff8216115b801561251457504263ffffffff168163ffffffff1611155b9392505050565b60009081526004602052604090206005015490565b6006602052600090815260409020805460019091015463ffffffff821691640100000000900460ff169083565b60015460008181526002602090815260408083204390555184519293928592918201918291908401908083835b602083106125a95780518252601f19909201916020918201910161258a565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040526040518082805190602001908083835b6020831061260c5780518252601f1990920191602091820191016125ed565b51815160209384036101000a6000190180199092169116179052604080519290940182900382206000888152600383528581209190915581835289518383015289513397508896507fb87fb721c0a557bb8dff89a86796466931d82ba530a66a239263eb8735ade2e4958b955084939084019290860191908190849084905b838110156126a357818101518382015260200161268b565b50505050905090810190601f1680156126d05780820380516001836020036101000a031916815260200191505b509250505060405180910390a36126ee81600163ffffffff61373916565b60015592915050565b6000908152600460208190526040909120015490565b60009081526004602052604090206002015460ff1690565b600460208190526000918252604090912080546001820154600283015460038401549484015460058501546006909501549395600160a060020a0384169563ffffffff60a060020a860481169660c060020a870482169660e060020a90049091169460ff169391908a565b60009081526004602052604090206001015460a060020a900463ffffffff1690565b60009081526004602052604090206001015460c060020a900463ffffffff1690565b6000806127e08861255d565b90506127f0818888888888611e18565b98975050505050505050565b600081612808816124be565b151561285e576040805160e560020a62461bcd02815260206004820152601a60248201527f7175657374696f6e206d7573742062652066696e616c697a6564000000000000604482015290519081900360640190fd5b50506000908152600460208190526040909120015490565b60009081526004602052604090206001015460e060020a900463ffffffff1690565b60026020526000908152604090205481565b6000868152600460205260408120600581015460069091015482916128d3918790879087613523565b91508180156128f95750600084815260066020526040902054640100000000900460ff16155b156129995760008481526006602052604090205463ffffffff428116911610612992576040805160e560020a62461bcd02815260206004820152603760248201527f596f75206d757374207761697420666f72207468652072657665616c2064656160448201527f646c696e65206265666f72652066696e616c697a696e67000000000000000000606482015290519081900360840190fd5b50846129bd565b6000888152600460208190526040909120015487146129b857856129ba565b825b90505b6129c8888883613355565b5050505050505050565b600084815260046020526040812060010154819086908290819060c060020a900463ffffffff168110612a3d576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613f9e833981519152604482015290519081900360640190fd5b60008381526004602052604090206002015460ff1615612aa9576040805160e560020a62461bcd0281526020600482015260286024820152600080516020613ffe8339815191526044820152600080516020613fbe833981519152606482015290519081900360840190fd5b60008381526004602052604090206001015460e060020a900463ffffffff169150811580612ae257504263ffffffff168263ffffffff16115b1515612b3a576040805160e560020a62461bcd02815260206004820152602a602482015260008051602061401e833981519152604482015260008051602061405e833981519152606482015290519081900360840190fd5b5060008281526004602052604090206001015460a060020a900463ffffffff16801580612b7357504263ffffffff168163ffffffff1611155b1515612bb7576040805160e560020a62461bcd02815260206004820152601d602482015260008051602061403e833981519152604482015290519081900360640190fd5b8860003411612c10576040805160e560020a62461bcd02815260206004820152601560248201527f626f6e64206d75737420626520706f7369746976650000000000000000000000604482015290519081900360640190fd5b600081815260046020526040902060060154612c3390600263ffffffff61391616565b341015612cb0576040805160e560020a62461bcd02815260206004820152602a60248201527f626f6e64206d75737420626520646f75626c65206174206c656173742070726560448201527f76696f757320626f6e6400000000000000000000000000000000000000000000606482015290519081900360840190fd5b89886000811115612d1257600082815260046020526040902060060154811015612d12576040805160e560020a62461bcd02815260206004820152601d6024820152600080516020613fde833981519152604482015290519081900360640190fd5b6040805160208082018f90528183018e90523460608084019190915283518084039091018152608090920192839052815191929182918401908083835b60208310612d6e5780518252601f199092019160209182019101612d4f565b5181516020939093036101000a600019018019909116921691909117905260405192018290039091209a50505050600160a060020a03891615612db15788612db3565b335b9650612dbf8c89613e91565b612dcd8c8989346001613941565b505050505050505050505050565b6000818152600460205260409020600101548190600160a060020a03163314612e4e576040805160e560020a62461bcd02815260206004820152601d60248201527f6d73672e73656e646572206d7573742062652061726269747261746f72000000604482015290519081900360640190fd5b600082815260046020526040902060020154829060ff161515612ee0576040805160e560020a62461bcd028152602060048201526024808201527f7175657374696f6e206d7573742062652070656e64696e67206172626974726160448201527f74696f6e00000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600083815260046020526040902060028101805460ff1916905560010154612f1b9063ffffffff4281169160c060020a9004811690613f8516565b600084815260046020526040808220600101805463ffffffff9490941660e060020a027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90941693909317909255905184917f71bf7c2b9df0b8818e7eb6746a5bf69699ebbab041f3795f9ed58e469afa9a3a91a2505050565b6000838152600460205260409020600101548390600160a060020a03163314613004576040805160e560020a62461bcd02815260206004820152601d60248201527f6d73672e73656e646572206d7573742062652061726269747261746f72000000604482015290519081900360640190fd5b600084815260046020526040812060010154859190819060c060020a900463ffffffff16811061306c576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613f9e833981519152604482015290519081900360640190fd5b60008381526004602052604090206002015460ff16156130d8576040805160e560020a62461bcd0281526020600482015260286024820152600080516020613ffe8339815191526044820152600080516020613fbe833981519152606482015290519081900360840190fd5b60008381526004602052604090206001015460e060020a900463ffffffff16915081158061311157504263ffffffff168263ffffffff16115b1515613169576040805160e560020a62461bcd02815260206004820152602a602482015260008051602061401e833981519152604482015260008051602061405e833981519152606482015290519081900360840190fd5b5060008281526004602052604090206001015460a060020a900463ffffffff168015806131a257504263ffffffff168163ffffffff1611155b15156131e6576040805160e560020a62461bcd02815260206004820152601d602482015260008051602061403e833981519152604482015290519081900360640190fd5b8685600081111561324857600082815260046020526040902060060154811015613248576040805160e560020a62461bcd02815260206004820152601d6024820152600080516020613fde833981519152604482015290519081900360640190fd5b600089815260046020526040812060060154116132fb576040805160e560020a62461bcd02815260206004820152604260248201527f5175657374696f6e206d75737420616c7265616479206861766520616e20616e60448201527f73776572207768656e206172626974726174696f6e206973207265717565737460648201527f6564000000000000000000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b600089815260046020526040808220600201805460ff1916600117905551600160a060020a038a16918b917f75d7939999bc902187c4aed400872883e445145f1983539166f783fa040b47629190a3505050505050505050565b6000838152600460205260409020600101548390600160a060020a031633146133c8576040805160e560020a62461bcd02815260206004820152601d60248201527f6d73672e73656e646572206d7573742062652061726269747261746f72000000604482015290519081900360640190fd5b600084815260046020526040902060020154849060ff16151561345a576040805160e560020a62461bcd028152602060048201526024808201527f7175657374696f6e206d7573742062652070656e64696e67206172626974726160448201527f74696f6e00000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a03831615156134ba576040805160e560020a62461bcd02815260206004820152601960248201527f616e737765726572206d7573742062652070726f766964656400000000000000604482015290519081900360640190fd5b604051849086907f18d760beffe3717270cd90d9d920ec1a48c194e9ad7bba23eb1c92d3eb974f9790600090a36000858152600460205260408120600201805460ff191690556135109086908690869080613941565b61351c85856000613ab9565b5050505050565b604080516020808201879052818301869052606082018590526c01000000000000000000000000600160a060020a0385160260808301527f01000000000000000000000000000000000000000000000000000000000000006094830152825160758184030181526095909201928390528151600093918291908401908083835b602083106135c25780518252601f1990920191602091820191016135a3565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912089141592506135ff91505057506001613730565b604080516020808201889052818301879052606082018690526c01000000000000000000000000600160a060020a0386160260808301526000609483015282516075818403018152609590920192839052815191929182918401908083835b6020831061367d5780518252601f19909201916020918201910161365e565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912089141592506136ba91505057506000613730565b6040805160e560020a62461bcd02815260206004820152603660248201527f486973746f727920696e7075742070726f766964656420646964206e6f74206d60448201527f6174636820746865206578706563746564206861736800000000000000000000606482015290519081900360840190fd5b95945050505050565b60008282018381101561374857fe5b8091505b5092915050565b60008060008084156137d357600086815260066020526040902054869250640100000000900460ff1615156137ab576000828152600660205260408120805464ffffffffff1916815560010155899350889250613874565b6000828152600660205260408120600181018054825464ffffffffff19169092559190915595505b858b141561386d57600160a060020a038916151561382c5760008c8152600460205260409020600301549798508897613813908b9063ffffffff61373916565b60008d815260046020526040812060030155995061386d565b600160a060020a03888116908a161461386d57868a101561384d578961384f565b865b90506138668c8a610d058d8563ffffffff61388316565b8798508099505b8989935093505b50509850989650505050505050565b60008282111561388f57fe5b50900390565b600160a060020a0382166000908152602081905260409020546138be908263ffffffff61373916565b600160a060020a038316600081815260208181526040918290209390935580518481529051919286927f9c121aff33b50c1a53fef034ebec5f83da2d5a5187048f9c76c397ba27c1a1a69281900390910190a3505050565b600080831515613929576000915061374c565b5082820282848281151561393957fe5b041461374857fe5b600085815260046020908152604080832060050154815180840191909152808201889052606081018690526c01000000000000000000000000600160a060020a0388160260808201527f010000000000000000000000000000000000000000000000000000000000000085151502609482015281516075818303018152609590910191829052805190928291908401908083835b602083106139f45780518252601f1990920191602091820191016139d5565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902090506000831115613a415760008681526004602052604090206006018390555b600086815260046020908152604091829020600501839055815187815290810183905280820185905242606082015283151560808201529051600160a060020a0386169188917fe47ca4ebbbc2990134d1168821f38c5e177f3d5ee564bffeadeaa351905e62219181900360a00190a3505050505050565b600083815260046020819052604090912001829055613ae263ffffffff428116908390613f8516565b600093845260046020526040909320600101805463ffffffff9490941660e060020a027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909416939093179092555050565b6000858152600460205260408120600101548190879060c060020a900463ffffffff1615613ba8576040805160e560020a62461bcd02815260206004820152601760248201527f7175657374696f6e206d757374206e6f74206578697374000000000000000000604482015290519081900360640190fd5b600063ffffffff861611613c06576040805160e560020a62461bcd02815260206004820152601860248201527f74696d656f7574206d75737420626520706f7369746976650000000000000000604482015290519081900360640190fd5b6301e1338063ffffffff861610613c8d576040805160e560020a62461bcd02815260206004820152602260248201527f74696d656f7574206d757374206265206c657373207468616e2033363520646160448201527f7973000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a0386161515613ced576040805160e560020a62461bcd02815260206004820152601660248201527f61726269747261746f72206d7573742062652073657400000000000000000000604482015290519081900360640190fd5b34925033600160a060020a03871614613dee57600160a060020a038616600090815260076020526040902054915081831015613d98576040805160e560020a62461bcd028152602060048201526024808201527f4554482070726f7669646564206d75737420636f766572207175657374696f6e60448201527f2066656500000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b613da8838363ffffffff61388316565b600160a060020a038716600090815260208190526040902054909350613dd4908363ffffffff61373916565b600160a060020a0387166000908152602081905260409020555b505060009586526004602052604090952093845560018401805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03949094169390931777ffffffff0000000000000000000000000000000000000000191660a060020a63ffffffff92831602177fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff1660c060020a929091169190910217905560030155565b60008181526006602052604081205463ffffffff1615613f21576040805160e560020a62461bcd02815260206004820152602160248201527f636f6d6d69746d656e74206d757374206e6f7420616c7265616479206578697360448201527f7400000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60008381526004602052604090206001015460089060c060020a900463ffffffff16049050613f5a63ffffffff428116908390613f8516565b600092835260066020526040909220805463ffffffff191663ffffffff909316929092179091555050565b600082820163ffffffff808516908216101561374857fe007175657374696f6e206d757374206578697374000000000000000000000000006974726174696f6e000000000000000000000000000000000000000000000000626f6e64206d75737420657863656564206d61785f70726576696f75730000007175657374696f6e206d757374206e6f742062652070656e64696e672061726266696e616c697a6174696f6e20646561646c696e65206d757374206e6f7420686f70656e696e672064617465206d7573742068617665207061737365640000006176652070617373656400000000000000000000000000000000000000000000a165627a7a723058202747a6b32b6d0488200dcab734406fc66af369ae01fb10c2507ed73f6148ca480029", + "deployedBytecode": "0x6080604052600436106101b35763ffffffff60e060020a6000350416631101a0fd81146101b8578063111ec138146102bf57806312a203c3146102dc5780632417395c146103215780632518904c1461033957806326d6c97b1461036d57806328828b1e146103855780633ccfd60b146104f75780634dc266b41461050c5780634df6ca2a1461052d5780634e60f8831461054557806351577ea91461055d578063590158a71461057557806359245ff3146105b55780636fa42742146105c057806370a08231146105e1578063762c38fd1461060257806377f325df146106785780637f8d429e1461068957806382ffa9f7146106b5578063839df945146106cd57806383bf46091461070a5780638d552d4614610763578063924532fb1461077b57806395addb90146107935780639e63fa6a1461080f5780639f1025c614610840578063a1130d0414610858578063a462fb7b14610907578063acae8f4e1461091f578063bc52565214610937578063d09cc57e14610907578063d44e293c1461094f578063d7cff98614610984578063ebbdd2b0146109a1578063f6a94ecb146109b9578063fe92049d146109e0575b600080fd5b3480156101c457600080fd5b506040805160206004602480358281013584810280870186019097528086526102bd96843596369660449591949091019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750610a079650505050505050565b005b6102bd600435602435604435600160a060020a0360643516610d62565b3480156102e857600080fd5b5061030f600435602435600160a060020a036044351663ffffffff60643516608435611145565b60408051918252519081900360200190f35b34801561032d57600080fd5b5061030f600435611382565b34801561034557600080fd5b50610351600435611397565b60408051600160a060020a039092168252519081900360200190f35b34801561037957600080fd5b5061030f6004356113b5565b34801561039157600080fd5b50604080516020600480358082013583810280860185019096528085526102bd95369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a9989019892975090820195509350839250850190849080828437509497506113ca9650505050505050565b34801561050357600080fd5b506102bd6115de565b34801561051857600080fd5b506102bd600435602435604435606435611659565b34801561053957600080fd5b506102bd600435611af9565b34801561055157600080fd5b5061030f600435611b48565b34801561056957600080fd5b5061030f600435611b5a565b34801561058157600080fd5b5061058d600435611b6c565b60408051600160a060020a039094168452602084019290925282820152519081900360600190f35b6102bd600435611b97565b3480156105cc57600080fd5b5061030f600160a060020a0360043516611df4565b3480156105ed57600080fd5b5061030f600160a060020a0360043516611e06565b60408051602060046024803582810135601f810185900485028601850190965285855261030f95833595369560449491939091019190819084018382808284375094975050508335600160a060020a03169450505050602081013563ffffffff9081169160408101359091169060600135611e18565b6102bd60043560243560443561213c565b34801561069557600080fd5b506106a16004356124be565b604080519115158252519081900360200190f35b3480156106c157600080fd5b5061030f60043561251b565b3480156106d957600080fd5b506106e5600435612530565b6040805163ffffffff9094168452911515602084015282820152519081900360600190f35b34801561071657600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261030f94369492936024939284019190819084018382808284375094975061255d9650505050505050565b34801561076f57600080fd5b5061030f6004356126f7565b34801561078757600080fd5b506106a160043561270d565b34801561079f57600080fd5b506107ab600435612725565b604080519a8b52600160a060020a0390991660208b015263ffffffff9788168a8a015295871660608a015293909516608088015290151560a087015260c086015260e085019290925261010084019190915261012083015251908190036101400190f35b34801561081b57600080fd5b50610827600435612790565b6040805163ffffffff9092168252519081900360200190f35b34801561084c57600080fd5b506108276004356127b2565b6040805160206004803580820135601f810184900484028501840190955284845261030f94369492936024939284019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375094975050508335600160a060020a03169450505050602081013563ffffffff90811691604081013590911690606001356127d4565b34801561091357600080fd5b5061030f6004356127fc565b34801561092b57600080fd5b50610827600435612876565b34801561094357600080fd5b5061030f600435612898565b34801561095b57600080fd5b506102bd600435602435600160a060020a03604435811690606435906084359060a435166128aa565b6102bd600435602435604435600160a060020a03606435166129d2565b3480156109ad57600080fd5b506102bd600435612ddb565b3480156109c557600080fd5b506102bd600435600160a060020a0360243516604435612f91565b3480156109ec57600080fd5b506102bd600435602435600160a060020a0360443516613355565b60008060008060008060008b610a1c816124be565b1515610a72576040805160e560020a62461bcd02815260206004820152601a60248201527f7175657374696f6e206d7573742062652066696e616c697a6564000000000000604482015290519081900360640190fd5b8b51600010610af1576040805160e560020a62461bcd02815260206004820152603060248201527f6174206c65617374206f6e6520686973746f7279206861736820656e7472792060448201527f6d7573742062652070726f766964656400000000000000000000000000000000606482015290519081900360840190fd5b60008d815260056020818152604080842080546001820154600290920154600494859052928620948501549490930154600160a060020a039093169c509a509850909650945092505b8b51831015610c8557610bac858d85815181101515610b5557fe5b906020019060200201518b86815181101515610b6d57fe5b906020019060200201518d87815181101515610b8557fe5b906020019060200201518f88815181101515610b9d57fe5b90602001906020020151613523565b9150610bbe868863ffffffff61373916565b9550610c158d85888b8f88815181101515610bd557fe5b906020019060200201518f89815181101515610bed57fe5b906020019060200201518f8a815181101515610c0557fe5b9060200190602002015189613753565b8b519099509096508a9084908110610c2957fe5b602090810290910181015160008f815260049092526040909120600601549097508714610c6057610c5d8760288104613883565b96505b8b83815181101515610c6e57fe5b602090810290910101519450600190920191610b3a565b8415610cf057600160a060020a03881615610caa57610ca58d8988613895565b600095505b60008d8152600560205260409020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038a1617815560018101889055600201869055610d3f565b610d0a8d89610d05898b63ffffffff61373916565b613895565b60008d8152600560205260408120805473ffffffffffffffffffffffffffffffffffffffff1916815560018101829055600201555b5050506000998a5250600460205260409098206005019790975550505050505050565b600084815260046020526040812060010154859190819060c060020a900463ffffffff168110610dca576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613f9e833981519152604482015290519081900360640190fd5b60008381526004602052604090206002015460ff1615610e36576040805160e560020a62461bcd0281526020600482015260286024820152600080516020613ffe8339815191526044820152600080516020613fbe833981519152606482015290519081900360840190fd5b60008381526004602052604090206001015460e060020a900463ffffffff169150811580610e6f57504263ffffffff168263ffffffff16115b1515610ec7576040805160e560020a62461bcd02815260206004820152602a602482015260008051602061401e833981519152604482015260008051602061405e833981519152606482015290519081900360840190fd5b5060008281526004602052604090206001015460a060020a900463ffffffff16801580610f0057504263ffffffff168163ffffffff1611155b1515610f44576040805160e560020a62461bcd02815260206004820152601d602482015260008051602061403e833981519152604482015290519081900360640190fd5b8660003411610f9d576040805160e560020a62461bcd02815260206004820152601560248201527f626f6e64206d75737420626520706f7369746976650000000000000000000000604482015290519081900360640190fd5b600081815260046020526040902060060154610fc090600263ffffffff61391616565b34101561103d576040805160e560020a62461bcd02815260206004820152602a60248201527f626f6e64206d75737420626520646f75626c65206174206c656173742070726560448201527f76696f757320626f6e6400000000000000000000000000000000000000000000606482015290519081900360840190fd5b8786600081111561109f5760008281526004602052604090206006015481101561109f576040805160e560020a62461bcd02815260206004820152601d6024820152600080516020613fde833981519152604482015290519081900360640190fd5b600160a060020a03871615156110ff576040805160e560020a62461bcd02815260206004820152601960248201527f616e737765726572206d757374206265206e6f6e2d7a65726f00000000000000604482015290519081900360640190fd5b61110d8a8a89346000613941565b60008a815260046020526040902060010154611139908b908b9060c060020a900463ffffffff16613ab9565b50505050505050505050565b600085611151816124be565b15156111a7576040805160e560020a62461bcd02815260206004820152601a60248201527f7175657374696f6e206d7573742062652066696e616c697a6564000000000000604482015290519081900360640190fd5b600087815260046020526040902054861461120c576040805160e560020a62461bcd02815260206004820152601760248201527f636f6e74656e742068617368206d757374206d61746368000000000000000000604482015290519081900360640190fd5b600087815260046020526040902060010154600160a060020a03868116911614611280576040805160e560020a62461bcd02815260206004820152601560248201527f61726269747261746f72206d757374206d617463680000000000000000000000604482015290519081900360640190fd5b60008781526004602052604090206001015463ffffffff60c060020a909104811690851611156112fa576040805160e560020a62461bcd02815260206004820152601b60248201527f74696d656f7574206d757374206265206c6f6e6720656e6f7567680000000000604482015290519081900360640190fd5b600087815260046020526040902060060154831115611363576040805160e560020a62461bcd02815260206004820152601860248201527f626f6e64206d757374206265206869676820656e6f7567680000000000000000604482015290519081900360640190fd5b6000878152600460208190526040909120015491505095945050505050565b60009081526004602052604090206003015490565b600090815260046020526040902060010154600160a060020a031690565b60009081526004602052604090206006015490565b60008080806060808080845b8e518910156115c5578e898151811015156113ed57fe5b9060200190602002015196508d8981518110151561140757fe5b9060200190602002015195508560405190808252806020026020018201604052801561143d578160200160208202803883390190505b5094508560405190808252806020026020018201604052801561146a578160200160208202803883390190505b50935085604051908082528060200260200182016040528015611497578160200160208202803883390190505b509250856040519080825280602002602001820160405280156114c4578160200160208202803883390190505b509150600090505b858110156115ad578c888151811015156114e257fe5b9060200190602002015185828151811015156114fa57fe5b602090810290910101528b518c908990811061151257fe5b90602001906020020151848281518110151561152a57fe5b600160a060020a039092166020928302909101909101528a518b908990811061154f57fe5b90602001906020020151838281518110151561156757fe5b6020908102909101015289518a908990811061157f57fe5b90602001906020020151828281518110151561159757fe5b60209081029091010152600197880197016114cc565b6115ba8786868686610a07565b6001909801976113d6565b6115cd6115de565b505050505050505050505050505050565b33600081815260208190526040808220805490839055905190929183156108fc02918491818181858888f1935050505015801561161f573d6000803e3d6000fd5b5060408051828152905133917f4ce7033d118120e254016dccf195288400b28fc8936425acd5f17ce2df3ab708919081900360200190a250565b600084815260046020526040812060010154819086908290819060c060020a900463ffffffff1681106116c4576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613f9e833981519152604482015290519081900360640190fd5b60008381526004602052604090206001015460e060020a900463ffffffff1691508115806116fd57504263ffffffff168263ffffffff16115b1515611779576040805160e560020a62461bcd02815260206004820152602960248201527f66696e616c697a6174696f6e206465616c696e65206d757374206e6f7420686160448201527f7665207061737365640000000000000000000000000000000000000000000000606482015290519081900360840190fd5b5060008281526004602052604090206001015460a060020a900463ffffffff168015806117b257504263ffffffff168163ffffffff1611155b15156117f6576040805160e560020a62461bcd02815260206004820152601d602482015260008051602061403e833981519152604482015290519081900360640190fd5b6040805160208082018b90528183018a9052825180830384018152606090920192839052815191929182918401908083835b602083106118475780518252601f199092019160209182019101611828565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209450888587604051602001808460001916600019168152602001836000191660001916815260200182815260200193505050506040516020818303038152906040526040518082805190602001908083835b602083106118e55780518252601f1990920191602091820191016118c6565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120600081815260069092529290205491975050640100000000900460ff161591506119a99050576040805160e560020a62461bcd02815260206004820152602a60248201527f636f6d6d69746d656e74206d757374206e6f742068617665206265656e20726560448201527f7665616c65642079657400000000000000000000000000000000000000000000606482015290519081900360840190fd5b60008481526006602052604090205463ffffffff428116911611611a3c576040805160e560020a62461bcd028152602060048201526024808201527f72657665616c20646561646c696e65206d757374206e6f74206861766520706160448201527f7373656400000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6000848152600660208181526040808420600181018d9055805464ff0000000019166401000000001790558c845260049091529091200154861415611aa757600089815260046020526040902060010154611aa7908a908a9060c060020a900463ffffffff16613ab9565b60408051898152602081018990528082018890529051869133918c917fa7b2d313bc7a062e30b2c3b811aa4c9faf09755a6b4ea3bf42deff920944332f919081900360600190a4505050505050505050565b336000818152600760209081526040918290208490558151928352820183905280517fdca703d022171824d3d639b33c1525fd2338120b4cfb89507c0b59596893acda9281900390910190a150565b60036020526000908152604090205481565b60009081526004602052604090205490565b600560205260009081526040902080546001820154600290920154600160a060020a03909116919083565b600081815260046020526040812060010154829190819060c060020a900463ffffffff168110611bff576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613f9e833981519152604482015290519081900360640190fd5b60008381526004602052604090206002015460ff1615611c6b576040805160e560020a62461bcd0281526020600482015260286024820152600080516020613ffe8339815191526044820152600080516020613fbe833981519152606482015290519081900360840190fd5b60008381526004602052604090206001015460e060020a900463ffffffff169150811580611ca457504263ffffffff168263ffffffff16115b1515611cfc576040805160e560020a62461bcd02815260206004820152602a602482015260008051602061401e833981519152604482015260008051602061405e833981519152606482015290519081900360840190fd5b5060008281526004602052604090206001015460a060020a900463ffffffff16801580611d3557504263ffffffff168163ffffffff1611155b1515611d79576040805160e560020a62461bcd02815260206004820152601d602482015260008051602061403e833981519152604482015290519081900360640190fd5b600084815260046020526040902060030154611d9b903463ffffffff61373916565b6000858152600460209081526040918290206003018390558151348152908101929092528051339287927f54d68405b79f2aa4fd4e8db7b67844ad254cf8f208aac476c2894134a9deab6692918290030190a350505050565b60076020526000908152604090205481565b60006020819052908152604090205481565b600086815260026020526040812054819081908110611e81576040805160e560020a62461bcd02815260206004820152601360248201527f74656d706c617465206d75737420657869737400000000000000000000000000604482015290519081900360640190fd5b888589604051602001808481526020018363ffffffff1663ffffffff1660e060020a02815260040182805190602001908083835b60208310611ed45780518252601f199092019160209182019101611eb5565b6001836020036101000a03801982511681845116808217855250505050505090500193505050506040516020818303038152906040526040518082805190602001908083835b60208310611f395780518252601f199092019160209182019101611f1a565b51815160209384036101000a600019018019909216911617905260408051929094018290038220828201819052600160a060020a038e166c010000000000000000000000009081028487015263ffffffff8e1660e060020a02605485015233026058840152606c8084018c905285518085039091018152608c9093019485905282519098509195509293508392850191508083835b60208310611fed5780518252601f199092019160209182019101611fce565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902090506120298183898989613b30565b816000191633600160a060020a031682600019167ffe2dac156a3890636ce13f65f4fdf41dcaee11526e4a5374531572d92194796c8c8c8c8c8c8c42604051808881526020018060200187600160a060020a0316600160a060020a031681526020018663ffffffff1663ffffffff1681526020018563ffffffff1663ffffffff168152602001848152602001838152602001828103825288818151815260200191508051906020019080838360005b838110156120f05781810151838201526020016120d8565b50505050905090810190601f16801561211d5780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390a498975050505050505050565b600083815260046020526040812060010154849190819060c060020a900463ffffffff1681106121a4576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613f9e833981519152604482015290519081900360640190fd5b60008381526004602052604090206002015460ff1615612210576040805160e560020a62461bcd0281526020600482015260286024820152600080516020613ffe8339815191526044820152600080516020613fbe833981519152606482015290519081900360840190fd5b60008381526004602052604090206001015460e060020a900463ffffffff16915081158061224957504263ffffffff168263ffffffff16115b15156122a1576040805160e560020a62461bcd02815260206004820152602a602482015260008051602061401e833981519152604482015260008051602061405e833981519152606482015290519081900360840190fd5b5060008281526004602052604090206001015460a060020a900463ffffffff168015806122da57504263ffffffff168163ffffffff1611155b151561231e576040805160e560020a62461bcd02815260206004820152601d602482015260008051602061403e833981519152604482015290519081900360640190fd5b8560003411612377576040805160e560020a62461bcd02815260206004820152601560248201527f626f6e64206d75737420626520706f7369746976650000000000000000000000604482015290519081900360640190fd5b60008181526004602052604090206006015461239a90600263ffffffff61391616565b341015612417576040805160e560020a62461bcd02815260206004820152602a60248201527f626f6e64206d75737420626520646f75626c65206174206c656173742070726560448201527f76696f757320626f6e6400000000000000000000000000000000000000000000606482015290519081900360840190fd5b8685600081111561247957600082815260046020526040902060060154811015612479576040805160e560020a62461bcd02815260206004820152601d6024820152600080516020613fde833981519152604482015290519081900360640190fd5b612487898933346000613941565b6000898152600460205260409020600101546124b3908a908a9060c060020a900463ffffffff16613ab9565b505050505050505050565b6000818152600460205260408120600181015460029091015460e060020a90910463ffffffff169060ff161580156124fc5750600063ffffffff8216115b801561251457504263ffffffff168163ffffffff1611155b9392505050565b60009081526004602052604090206005015490565b6006602052600090815260409020805460019091015463ffffffff821691640100000000900460ff169083565b60015460008181526002602090815260408083204390555184519293928592918201918291908401908083835b602083106125a95780518252601f19909201916020918201910161258a565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040526040518082805190602001908083835b6020831061260c5780518252601f1990920191602091820191016125ed565b51815160209384036101000a6000190180199092169116179052604080519290940182900382206000888152600383528581209190915581835289518383015289513397508896507fb87fb721c0a557bb8dff89a86796466931d82ba530a66a239263eb8735ade2e4958b955084939084019290860191908190849084905b838110156126a357818101518382015260200161268b565b50505050905090810190601f1680156126d05780820380516001836020036101000a031916815260200191505b509250505060405180910390a36126ee81600163ffffffff61373916565b60015592915050565b6000908152600460208190526040909120015490565b60009081526004602052604090206002015460ff1690565b600460208190526000918252604090912080546001820154600283015460038401549484015460058501546006909501549395600160a060020a0384169563ffffffff60a060020a860481169660c060020a870482169660e060020a90049091169460ff169391908a565b60009081526004602052604090206001015460a060020a900463ffffffff1690565b60009081526004602052604090206001015460c060020a900463ffffffff1690565b6000806127e08861255d565b90506127f0818888888888611e18565b98975050505050505050565b600081612808816124be565b151561285e576040805160e560020a62461bcd02815260206004820152601a60248201527f7175657374696f6e206d7573742062652066696e616c697a6564000000000000604482015290519081900360640190fd5b50506000908152600460208190526040909120015490565b60009081526004602052604090206001015460e060020a900463ffffffff1690565b60026020526000908152604090205481565b6000868152600460205260408120600581015460069091015482916128d3918790879087613523565b91508180156128f95750600084815260066020526040902054640100000000900460ff16155b156129995760008481526006602052604090205463ffffffff428116911610612992576040805160e560020a62461bcd02815260206004820152603760248201527f596f75206d757374207761697420666f72207468652072657665616c2064656160448201527f646c696e65206265666f72652066696e616c697a696e67000000000000000000606482015290519081900360840190fd5b50846129bd565b6000888152600460208190526040909120015487146129b857856129ba565b825b90505b6129c8888883613355565b5050505050505050565b600084815260046020526040812060010154819086908290819060c060020a900463ffffffff168110612a3d576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613f9e833981519152604482015290519081900360640190fd5b60008381526004602052604090206002015460ff1615612aa9576040805160e560020a62461bcd0281526020600482015260286024820152600080516020613ffe8339815191526044820152600080516020613fbe833981519152606482015290519081900360840190fd5b60008381526004602052604090206001015460e060020a900463ffffffff169150811580612ae257504263ffffffff168263ffffffff16115b1515612b3a576040805160e560020a62461bcd02815260206004820152602a602482015260008051602061401e833981519152604482015260008051602061405e833981519152606482015290519081900360840190fd5b5060008281526004602052604090206001015460a060020a900463ffffffff16801580612b7357504263ffffffff168163ffffffff1611155b1515612bb7576040805160e560020a62461bcd02815260206004820152601d602482015260008051602061403e833981519152604482015290519081900360640190fd5b8860003411612c10576040805160e560020a62461bcd02815260206004820152601560248201527f626f6e64206d75737420626520706f7369746976650000000000000000000000604482015290519081900360640190fd5b600081815260046020526040902060060154612c3390600263ffffffff61391616565b341015612cb0576040805160e560020a62461bcd02815260206004820152602a60248201527f626f6e64206d75737420626520646f75626c65206174206c656173742070726560448201527f76696f757320626f6e6400000000000000000000000000000000000000000000606482015290519081900360840190fd5b89886000811115612d1257600082815260046020526040902060060154811015612d12576040805160e560020a62461bcd02815260206004820152601d6024820152600080516020613fde833981519152604482015290519081900360640190fd5b6040805160208082018f90528183018e90523460608084019190915283518084039091018152608090920192839052815191929182918401908083835b60208310612d6e5780518252601f199092019160209182019101612d4f565b5181516020939093036101000a600019018019909116921691909117905260405192018290039091209a50505050600160a060020a03891615612db15788612db3565b335b9650612dbf8c89613e91565b612dcd8c8989346001613941565b505050505050505050505050565b6000818152600460205260409020600101548190600160a060020a03163314612e4e576040805160e560020a62461bcd02815260206004820152601d60248201527f6d73672e73656e646572206d7573742062652061726269747261746f72000000604482015290519081900360640190fd5b600082815260046020526040902060020154829060ff161515612ee0576040805160e560020a62461bcd028152602060048201526024808201527f7175657374696f6e206d7573742062652070656e64696e67206172626974726160448201527f74696f6e00000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600083815260046020526040902060028101805460ff1916905560010154612f1b9063ffffffff4281169160c060020a9004811690613f8516565b600084815260046020526040808220600101805463ffffffff9490941660e060020a027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90941693909317909255905184917f71bf7c2b9df0b8818e7eb6746a5bf69699ebbab041f3795f9ed58e469afa9a3a91a2505050565b6000838152600460205260409020600101548390600160a060020a03163314613004576040805160e560020a62461bcd02815260206004820152601d60248201527f6d73672e73656e646572206d7573742062652061726269747261746f72000000604482015290519081900360640190fd5b600084815260046020526040812060010154859190819060c060020a900463ffffffff16811061306c576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613f9e833981519152604482015290519081900360640190fd5b60008381526004602052604090206002015460ff16156130d8576040805160e560020a62461bcd0281526020600482015260286024820152600080516020613ffe8339815191526044820152600080516020613fbe833981519152606482015290519081900360840190fd5b60008381526004602052604090206001015460e060020a900463ffffffff16915081158061311157504263ffffffff168263ffffffff16115b1515613169576040805160e560020a62461bcd02815260206004820152602a602482015260008051602061401e833981519152604482015260008051602061405e833981519152606482015290519081900360840190fd5b5060008281526004602052604090206001015460a060020a900463ffffffff168015806131a257504263ffffffff168163ffffffff1611155b15156131e6576040805160e560020a62461bcd02815260206004820152601d602482015260008051602061403e833981519152604482015290519081900360640190fd5b8685600081111561324857600082815260046020526040902060060154811015613248576040805160e560020a62461bcd02815260206004820152601d6024820152600080516020613fde833981519152604482015290519081900360640190fd5b600089815260046020526040812060060154116132fb576040805160e560020a62461bcd02815260206004820152604260248201527f5175657374696f6e206d75737420616c7265616479206861766520616e20616e60448201527f73776572207768656e206172626974726174696f6e206973207265717565737460648201527f6564000000000000000000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b600089815260046020526040808220600201805460ff1916600117905551600160a060020a038a16918b917f75d7939999bc902187c4aed400872883e445145f1983539166f783fa040b47629190a3505050505050505050565b6000838152600460205260409020600101548390600160a060020a031633146133c8576040805160e560020a62461bcd02815260206004820152601d60248201527f6d73672e73656e646572206d7573742062652061726269747261746f72000000604482015290519081900360640190fd5b600084815260046020526040902060020154849060ff16151561345a576040805160e560020a62461bcd028152602060048201526024808201527f7175657374696f6e206d7573742062652070656e64696e67206172626974726160448201527f74696f6e00000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a03831615156134ba576040805160e560020a62461bcd02815260206004820152601960248201527f616e737765726572206d7573742062652070726f766964656400000000000000604482015290519081900360640190fd5b604051849086907f18d760beffe3717270cd90d9d920ec1a48c194e9ad7bba23eb1c92d3eb974f9790600090a36000858152600460205260408120600201805460ff191690556135109086908690869080613941565b61351c85856000613ab9565b5050505050565b604080516020808201879052818301869052606082018590526c01000000000000000000000000600160a060020a0385160260808301527f01000000000000000000000000000000000000000000000000000000000000006094830152825160758184030181526095909201928390528151600093918291908401908083835b602083106135c25780518252601f1990920191602091820191016135a3565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912089141592506135ff91505057506001613730565b604080516020808201889052818301879052606082018690526c01000000000000000000000000600160a060020a0386160260808301526000609483015282516075818403018152609590920192839052815191929182918401908083835b6020831061367d5780518252601f19909201916020918201910161365e565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912089141592506136ba91505057506000613730565b6040805160e560020a62461bcd02815260206004820152603660248201527f486973746f727920696e7075742070726f766964656420646964206e6f74206d60448201527f6174636820746865206578706563746564206861736800000000000000000000606482015290519081900360840190fd5b95945050505050565b60008282018381101561374857fe5b8091505b5092915050565b60008060008084156137d357600086815260066020526040902054869250640100000000900460ff1615156137ab576000828152600660205260408120805464ffffffffff1916815560010155899350889250613874565b6000828152600660205260408120600181018054825464ffffffffff19169092559190915595505b858b141561386d57600160a060020a038916151561382c5760008c8152600460205260409020600301549798508897613813908b9063ffffffff61373916565b60008d815260046020526040812060030155995061386d565b600160a060020a03888116908a161461386d57868a101561384d578961384f565b865b90506138668c8a610d058d8563ffffffff61388316565b8798508099505b8989935093505b50509850989650505050505050565b60008282111561388f57fe5b50900390565b600160a060020a0382166000908152602081905260409020546138be908263ffffffff61373916565b600160a060020a038316600081815260208181526040918290209390935580518481529051919286927f9c121aff33b50c1a53fef034ebec5f83da2d5a5187048f9c76c397ba27c1a1a69281900390910190a3505050565b600080831515613929576000915061374c565b5082820282848281151561393957fe5b041461374857fe5b600085815260046020908152604080832060050154815180840191909152808201889052606081018690526c01000000000000000000000000600160a060020a0388160260808201527f010000000000000000000000000000000000000000000000000000000000000085151502609482015281516075818303018152609590910191829052805190928291908401908083835b602083106139f45780518252601f1990920191602091820191016139d5565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902090506000831115613a415760008681526004602052604090206006018390555b600086815260046020908152604091829020600501839055815187815290810183905280820185905242606082015283151560808201529051600160a060020a0386169188917fe47ca4ebbbc2990134d1168821f38c5e177f3d5ee564bffeadeaa351905e62219181900360a00190a3505050505050565b600083815260046020819052604090912001829055613ae263ffffffff428116908390613f8516565b600093845260046020526040909320600101805463ffffffff9490941660e060020a027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909416939093179092555050565b6000858152600460205260408120600101548190879060c060020a900463ffffffff1615613ba8576040805160e560020a62461bcd02815260206004820152601760248201527f7175657374696f6e206d757374206e6f74206578697374000000000000000000604482015290519081900360640190fd5b600063ffffffff861611613c06576040805160e560020a62461bcd02815260206004820152601860248201527f74696d656f7574206d75737420626520706f7369746976650000000000000000604482015290519081900360640190fd5b6301e1338063ffffffff861610613c8d576040805160e560020a62461bcd02815260206004820152602260248201527f74696d656f7574206d757374206265206c657373207468616e2033363520646160448201527f7973000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a0386161515613ced576040805160e560020a62461bcd02815260206004820152601660248201527f61726269747261746f72206d7573742062652073657400000000000000000000604482015290519081900360640190fd5b34925033600160a060020a03871614613dee57600160a060020a038616600090815260076020526040902054915081831015613d98576040805160e560020a62461bcd028152602060048201526024808201527f4554482070726f7669646564206d75737420636f766572207175657374696f6e60448201527f2066656500000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b613da8838363ffffffff61388316565b600160a060020a038716600090815260208190526040902054909350613dd4908363ffffffff61373916565b600160a060020a0387166000908152602081905260409020555b505060009586526004602052604090952093845560018401805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03949094169390931777ffffffff0000000000000000000000000000000000000000191660a060020a63ffffffff92831602177fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff1660c060020a929091169190910217905560030155565b60008181526006602052604081205463ffffffff1615613f21576040805160e560020a62461bcd02815260206004820152602160248201527f636f6d6d69746d656e74206d757374206e6f7420616c7265616479206578697360448201527f7400000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60008381526004602052604090206001015460089060c060020a900463ffffffff16049050613f5a63ffffffff428116908390613f8516565b600092835260066020526040909220805463ffffffff191663ffffffff909316929092179091555050565b600082820163ffffffff808516908216101561374857fe007175657374696f6e206d757374206578697374000000000000000000000000006974726174696f6e000000000000000000000000000000000000000000000000626f6e64206d75737420657863656564206d61785f70726576696f75730000007175657374696f6e206d757374206e6f742062652070656e64696e672061726266696e616c697a6174696f6e20646561646c696e65206d757374206e6f7420686f70656e696e672064617465206d7573742068617665207061737365640000006176652070617373656400000000000000000000000000000000000000000000a165627a7a723058202747a6b32b6d0488200dcab734406fc66af369ae01fb10c2507ed73f6148ca480029", + "sourceMap": "306:38979:18:-;;;3449:1;3424:26;;6220:564;8:9:-1;5:2;;;30:1;27;20:12;5:2;6220:564:18;6256:81;;;;;;;;;;;;;;;;;;;;;;;;:14;;;:81;;;:::i;:::-;;6347:97;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:14;;;:97;;;:::i;:::-;;6454:108;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:14;;;:108;;;:::i;:::-;;6572:110;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:14;;;:110;;;:::i;:::-;;6692:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:14;;;:85;;;:::i;:::-;;306:38979;;7617:348;7729:14;;7697:7;7753:13;;;:9;:13;;;;;;;;7769:12;7753:28;;7823:25;;;7697:7;;7729:14;7840:7;;7823:25;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;7823:25:18;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;7823:25:18;;;7813:36;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;7813:36:18;;;;;;;;;;;;-1:-1:-1;7791:19:18;;;:15;:19;;;;;:58;;;;7864:39;;;;;;;;;;;7883:10;;-1:-1:-1;7791:19:18;;-1:-1:-1;7864:39:18;;;;-1:-1:-1;7813:36:18;;7864:39;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;7864:39:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7930:9;:2;7937:1;7930:6;;;;;;:9;:::i;:::-;7913:14;:26;7956:2;7617:348;-1:-1:-1;;7617:348:18:o;719:129:16:-;777:7;804:5;;;822:6;;;;815:14;;;;842:1;719:129;-1:-1:-1;;;719:129:16:o;306:38979:18:-;;;;;;;", + "deployedSourceMap": "306:38979:18:-;;;;;;;;;-1:-1:-1;;;306:38979:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28277:3152;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;28277:3152:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;28277:3152:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;28277:3152:18;;;;-1:-1:-1;28277:3152:18;-1:-1:-1;28277:3152:18;;-1:-1:-1;28277:3152:18;;;;;;;;;-1:-1:-1;;28277:3152:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;28277:3152:18;;;;-1:-1:-1;28277:3152:18;-1:-1:-1;28277:3152:18;;-1:-1:-1;28277:3152:18;;;;;;;;;-1:-1:-1;;28277:3152:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;28277:3152:18;;;;-1:-1:-1;28277:3152:18;-1:-1:-1;28277:3152:18;;-1:-1:-1;28277:3152:18;;;;;;;;;-1:-1:-1;28277:3152:18;;-1:-1:-1;28277:3152:18;;-1:-1:-1;;;;;;;28277:3152:18;;;14455:500;;;;;;;;-1:-1:-1;;;;;14455:500:18;;;;;26302:657;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;26302:657:18;;;;;-1:-1:-1;;;;;26302:657:18;;;;;;;;;;;;;;;;;;;;;;;;;;;38342:127;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;38342:127:18;;;;;36955:135;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;36955:135:18;;;;;;;;;-1:-1:-1;;;;;36955:135:18;;;;;;;;;;;;;;39159:123;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;39159:123:18;;;;;35549:1003;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;35549:1003:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;35549:1003:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;35549:1003:18;;;;-1:-1:-1;35549:1003:18;-1:-1:-1;35549:1003:18;;-1:-1:-1;35549:1003:18;;;;;;;;;-1:-1:-1;;35549:1003:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;35549:1003:18;;;;-1:-1:-1;35549:1003:18;-1:-1:-1;35549:1003:18;;-1:-1:-1;35549:1003:18;;;;;;;;;-1:-1:-1;;35549:1003:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;35549:1003:18;;;;-1:-1:-1;35549:1003:18;-1:-1:-1;35549:1003:18;;-1:-1:-1;35549:1003:18;;;;;;;;;-1:-1:-1;;35549:1003:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;35549:1003:18;;;;-1:-1:-1;35549:1003:18;-1:-1:-1;35549:1003:18;;-1:-1:-1;35549:1003:18;;;;;;;;;-1:-1:-1;;35549:1003:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;35549:1003:18;;;;-1:-1:-1;35549:1003:18;-1:-1:-1;35549:1003:18;;-1:-1:-1;35549:1003:18;;;;;;;;;-1:-1:-1;35549:1003:18;;-1:-1:-1;35549:1003:18;;-1:-1:-1;;;;;;;35549:1003:18;191:196:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;191:196:1;;;;18054:905:18;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;18054:905:18;;;;;;;;;;;7058:179;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;7058:179:18;;;;;3506:50;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3506:50:18;;;;;36696:138;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;36696:138:18;;;;;3613:48;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3613:48:18;;;;;;;;;-1:-1:-1;;;;;3613:48:18;;;;;;;;;;;;;;;;;;;;;;;;;12655:294;;;;;;3722:59;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3722:59:18;-1:-1:-1;;;;;3722:59:18;;;;;56:44:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;56:44:1;-1:-1:-1;;;;;56:44:1;;;;;10145:768:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10145:768:18;;-1:-1:-1;;;10145:768:18;;-1:-1:-1;;;;;10145:768:18;;-1:-1:-1;;;;10145:768:18;;;;;;;;;;;;;;;;;;;;;;13440:410;;;;;;;;;;24515:275;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;24515:275:18;;;;;;;;;;;;;;;;;;;;;;;38894:138;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;38894:138:18;;;;;3667:49;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3667:49:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7617:348;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;7617:348:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7617:348:18;;-1:-1:-1;7617:348:18;;-1:-1:-1;;;;;;;7617:348:18;38574:136;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;38574:136:18;;;;;38012:151;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;38012:151:18;;;;;3562:45;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3562:45:18;;;;;;;;;;;;-1:-1:-1;;;;;3562:45:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37225:133;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;37225:133:18;;;;;;;;;;;;;;;;;;;;;;;;37485:128;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;37485:128:18;;;;;8839:424;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;8839:424:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8839:424:18;;;;-1:-1:-1;8839:424:18;-1:-1:-1;8839:424:18;;-1:-1:-1;8839:424:18;;;;;;;;-1:-1:-1;8839:424:18;;-1:-1:-1;;;8839:424:18;;-1:-1:-1;;;;;8839:424:18;;-1:-1:-1;;;;8839:424:18;;;;;;;;;;;;;;;;;;;;;;25005:176;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;25005:176:18;;;;;37752:135;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;37752:135:18;;;;;3456:44;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3456:44:18;;;;;23257:1079;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;23257:1079:18;;;;;-1:-1:-1;;;;;23257:1079:18;;;;;;;;;;;;;;;;16479:600;;;;;;;;-1:-1:-1;;;;;16479:600:18;;;;;21102:355;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;21102:355:18;;;;;20367:506;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;20367:506:18;;;-1:-1:-1;;;;;20367:506:18;;;;;;;22053:498;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;22053:498:18;;;;;-1:-1:-1;;;;;22053:498:18;;;;;28277:3152;28659:13;28720:17;28789:20;29074:25;29148:19;29215:9;29412:18;28447:11;5493:24;5505:11;5493;:24::i;:::-;5485:63;;;;;;;-1:-1:-1;;;;;5485:63:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;28490:21;;28514:1;-1:-1:-1;28482:86:18;;;;;-1:-1:-1;;;;;28482:86:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28675:28;;;;:15;:28;;;;;;;;:34;;;28740:38;;;28812:41;;;;;29102:9;:22;;;;;;;:35;;;;29170:34;;;;;-1:-1:-1;;;;;28675:34:18;;;;-1:-1:-1;28740:38:18;-1:-1:-1;28812:41:18;-1:-1:-1;29102:35:18;;-1:-1:-1;29170:34:18;-1:-1:-1;28675:28:18;-1:-1:-1;29234:1119:18;29250:14;:21;29246:1;:25;29234:1119;;;29433:97;29461:17;29480:14;29495:1;29480:17;;;;;;;;;;;;;;;;;;29499:7;29507:1;29499:10;;;;;;;;;;;;;;;;;;29511:5;29517:1;29511:8;;;;;;;;;;;;;;;;;;29521:5;29527:1;29521:8;;;;;;;;;;;;;;;;;;29433:27;:97::i;:::-;29412:118;-1:-1:-1;29572:27:18;:12;29589:9;29572:27;:16;:27;:::i;:::-;29557:42;;29638:147;29675:11;29688;29701:12;29715:5;29739;29745:1;29739:8;;;;;;;;;;;;;;;;;;29749:5;29755:1;29749:8;;;;;;;;;;;;;;;;;;29759:7;29767:1;29759:10;;;;;;;;;;;;;;;;;;29771:13;29638:19;:147::i;:::-;29909:8;;29614:171;;-1:-1:-1;29614:171:18;;-1:-1:-1;29909:5:18;;29915:1;;29909:8;;;;;;;;;;;;;;;;30164:22;;;;:9;:22;;;;;;;:27;;;29909:8;;-1:-1:-1;30151:40:18;;30147:143;;30223:52;30237:9;1103:2;30237:37;;30223:13;:52::i;:::-;30211:64;;30147:143;30324:14;30339:1;30324:17;;;;;;;;;;;;;;;;;;;;-1:-1:-1;29273:3:18;;;;;29234:1119;;;30368:30;;30364:992;;-1:-1:-1;;;;;30803:21:18;;;30799:137;;30844:43;30854:11;30867:5;30874:12;30844:9;:43::i;:::-;30920:1;30905:16;;30799:137;30950:28;;;;:15;:28;;;;;:42;;-1:-1:-1;;30950:42:18;-1:-1:-1;;;;;30950:42:18;;;;;-1:-1:-1;31006:38:18;;:50;;;31070:41;;:56;;;30364:992;;;31238:58;31248:11;31261:5;31268:27;:12;31285:9;31268:27;:16;:27;:::i;:::-;31238:9;:58::i;:::-;31317:28;;;;:15;:28;;;;;31310:35;;-1:-1:-1;;31310:35:18;;;;;;;;;;;;30364:992;-1:-1:-1;;;31366:22:18;;;;-1:-1:-1;31366:9:18;:22;;;;;;:35;;:55;;;;-1:-1:-1;;;;;;;28277:3152:18:o;14455:500::-;4387:18;4210:22;;;:9;:22;;;;;:30;;;:22;;4387:18;;;-1:-1:-1;;;4210:30:18;;;;-1:-1:-1;;4202:66:18;;;;;-1:-1:-1;;;;;4202:66:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;4202:66:18;;;;;;;;;;;;;;;4287:22;;;;:9;:22;;;;;:45;;;;;4286:46;4278:99;;;;;-1:-1:-1;;;;;4278:99:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;4278:99:18;;;;-1:-1:-1;;;;;;;;;;;4278:99:18;;;;;;;;;;;;;;;4408:22;;;;:9;:22;;;;;:34;;;-1:-1:-1;;;4408:34:18;;;;;-1:-1:-1;4460:25:18;;;:54;;;4510:3;4489:25;;:11;:25;;;4460:54;4452:109;;;;;;;-1:-1:-1;;;;;4452:109:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;4452:109:18;;;;-1:-1:-1;;;;;;;;;;;4452:109:18;;;;;;;;;;;;;;;-1:-1:-1;4591:22:18;;;;:9;:22;;;;;:33;;;-1:-1:-1;;;4591:33:18;;;;4642:15;;;:44;;;4682:3;4661:25;;:10;:25;;;;4642:44;4634:86;;;;;;;-1:-1:-1;;;;;4634:86:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;4634:86:18;;;;;;;;;;;;;;;14611:11;5647:1;5635:9;:13;5627:47;;;;;-1:-1:-1;;;;;5627:47:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;5707:22;;;;:9;:22;;;;;:27;;;:34;;5739:1;5707:34;:31;:34;:::i;:::-;5693:9;:49;;5685:104;;;;;-1:-1:-1;;;;;5685:104:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14667:11;14680:12;5929:1;5914:12;:16;5910:132;;;5954:22;;;;:9;:22;;;;;:27;;;:43;-1:-1:-1;5954:43:18;5946:85;;;;;-1:-1:-1;;;;;5946:85:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;5946:85:18;;;;;;;;;;;;;;;-1:-1:-1;;;;;14733:24:18;;;;14725:62;;;;;-1:-1:-1;;;;;14725:62:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;14797:68;14817:11;14830:6;14838:8;14848:9;14859:5;14797:19;:68::i;:::-;14917:22;;;;:9;:22;;;;;:30;;;14875:73;;14917:22;;14909:6;;-1:-1:-1;;;14917:30:18;;;;14875:20;:73::i;:::-;5799:1;;4731;14455:500;;;;;;;:::o;26302:657::-;26523:7;26483:11;5493:24;5505:11;5493;:24::i;:::-;5485:63;;;;;;;-1:-1:-1;;;;;5485:63:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;26566:22;;;;:9;:22;;;;;:35;26550:51;;26542:87;;;;;-1:-1:-1;;;;;26542:87:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;26661:22;;;;:9;:22;;;;;:33;;;-1:-1:-1;;;;;26647:47:18;;;26661:33;;26647:47;26639:81;;;;;-1:-1:-1;;;;;26639:81:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;26753:22;;;;:9;:22;;;;;:30;;;;-1:-1:-1;;;26753:30:18;;;;;26738:45;;;;;26730:85;;;;;-1:-1:-1;;;;;26730:85:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;26845:22;;;;:9;:22;;;;;:27;;;26833:39;;;26825:76;;;;;-1:-1:-1;;;;;26825:76:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;26918:22;;;;:9;:22;;;;;;;;:34;;;-1:-1:-1;26302:657:18;;;;;;;;:::o;38342:127::-;38407:7;38433:22;;;:9;:22;;;;;:29;;;;38342:127::o;36955:135::-;37024:7;37050:22;;;:9;:22;;;;;:33;;;-1:-1:-1;;;;;37050:33:18;;36955:135::o;39159:123::-;39222:7;39248:22;;;:9;:22;;;;;:27;;;;39159:123::o;35549:1003::-;35848:10;;;;36028:19;;;;35848:10;35887:639;35905:12;:19;35900:2;:24;35887:639;;;35960:12;35973:2;35960:16;;;;;;;;;;;;;;;;;;35946:30;;36003:7;36011:2;36003:11;;;;;;;;;;;;;;;;;;35990:24;;36064:2;36050:17;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;36050:17:18;;36028:39;;36117:2;36103:17;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;36103:17:18;;36081:39;;36170:2;36156:17;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;36156:17:18;;36134:39;;36223:2;36209:17;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;36209:17:18;;36187:39;;36272:1;36268:5;;36263:205;36279:2;36275:1;:6;36263:205;;;36314:11;36326:1;36314:14;;;;;;;;;;;;;;;;;;36306:2;36309:1;36306:5;;;;;;;;;;;;;;;;;;:22;36354:8;;:5;;36360:1;;36354:8;;;;;;;;;;;;;;36346:2;36349:1;36346:5;;;;;;;;;;-1:-1:-1;;;;;36346:16:18;;;:5;;;;;;;;;;:16;36388:8;;:5;;36394:1;;36388:8;;;;;;;;;;;;;;36380:2;36383:1;36380:5;;;;;;;;;;;;;;;;;;:16;36422:10;;:7;;36430:1;;36422:10;;;;;;;;;;;;;;36414:2;36417:1;36414:5;;;;;;;;;;;;;;;;;;:18;36450:3;;;;;36283;36263:205;;;36481:34;36495:3;36500:2;36504;36508;36512;36481:13;:34::i;:::-;35926:4;;;;;35887:639;;;36535:10;:8;:10::i;:::-;35549:1003;;;;;;;;;;;;;;;:::o;191:196:1:-;257:10;233:11;247:21;;;;;;;;;;;;;278:25;;;;313:24;;247:21;;257:10;313:24;;;;;247:21;;313:24;233:11;313:24;247:21;257:10;313:24;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;352:28:1;;;;;;;;364:10;;352:28;;;;;;;;;;191:196;:::o;18054:905:18:-;18224:19;5005:22;;;:9;:22;;;;;:30;;;18224:19;;5005:22;;18224:19;;;;-1:-1:-1;;;5005:30:18;;;;-1:-1:-1;;4997:66:18;;;;;-1:-1:-1;;;;;4997:66:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;4997:66:18;;;;;;;;;;;;;;;5094:22;;;;:9;:22;;;;;:34;;;-1:-1:-1;;;5094:34:18;;;;;-1:-1:-1;5146:25:18;;;:54;;;5196:3;5175:25;;:11;:25;;;5146:54;5138:108;;;;;;;-1:-1:-1;;;;;5138:108:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5276:22:18;;;;:9;:22;;;;;:33;;;-1:-1:-1;;;5276:33:18;;;;5327:15;;;:44;;;5367:3;5346:25;;:10;:25;;;;5327:44;5319:86;;;;;;;-1:-1:-1;;;;;5319:86:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;5319:86:18;;;;;;;;;;;;;;;18256:31;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;18256:31:18;;;;;;;;18246:42;;18256:31;;;;;18246:42;;;;18256:31;18246:42;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;18246:42:18;;;;;;;;;;;;;;;;18224:64;;18349:11;18362;18375:4;18332:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;18332:48:18;;;18322:59;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;18322:59:18;;;;;;;;;;;;;-1:-1:-1;18401:26:18;;;:11;:26;;;;;;:38;18322:59;;-1:-1:-1;;18401:38:18;;;;;18400:39;;-1:-1:-1;18392:94:18;;-1:-1:-1;18392:94:18;;;;-1:-1:-1;;;;;18392:94:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18504:26;;;;:11;:26;;;;;:36;:50;18550:3;18504:50;;:36;;:50;18496:99;;;;;-1:-1:-1;;;;;18496:99:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18606:26;;;;:11;:26;;;;;;;;:42;;;:51;;;18667:45;;-1:-1:-1;;18667:45:18;;;;;18735:22;;;18667:38;18735:22;;;;;;:27;;18727:35;;18723:139;;;18820:22;;;;:9;:22;;;;;:30;;;18778:73;;18820:22;;18812:6;;-1:-1:-1;;;18820:30:18;;;;18778:20;:73::i;:::-;18877:74;;;;;;;;;;;;;;;;;;;;18918:11;;18906:10;;18893:11;;18877:74;;;;;;;;;;18054:905;;;;;;;;;:::o;7058:179::-;7164:10;7139:36;;;;:24;:36;;;;;;;;;:42;;;7196:34;;;;;;;;;;;;;;;;;;;;;;7058:179;:::o;3506:50::-;;;;;;;;;;;;;:::o;36696:138::-;36766:7;36792:22;;;:9;:22;;;;;:35;;36696:138::o;3613:48::-;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3613:48:18;;;;;;:::o;12655:294::-;4387:18;4210:22;;;:9;:22;;;;;:30;;;:22;;4387:18;;;-1:-1:-1;;;4210:30:18;;;;-1:-1:-1;;4202:66:18;;;;;-1:-1:-1;;;;;4202:66:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;4202:66:18;;;;;;;;;;;;;;;4287:22;;;;:9;:22;;;;;:45;;;;;4286:46;4278:99;;;;;-1:-1:-1;;;;;4278:99:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;4278:99:18;;;;-1:-1:-1;;;;;;;;;;;4278:99:18;;;;;;;;;;;;;;;4408:22;;;;:9;:22;;;;;:34;;;-1:-1:-1;;;4408:34:18;;;;;-1:-1:-1;4460:25:18;;;:54;;;4510:3;4489:25;;:11;:25;;;4460:54;4452:109;;;;;;;-1:-1:-1;;;;;4452:109:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;4452:109:18;;;;-1:-1:-1;;;;;;;;;;;4452:109:18;;;;;;;;;;;;;;;-1:-1:-1;4591:22:18;;;;:9;:22;;;;;:33;;;-1:-1:-1;;;4591:33:18;;;;4642:15;;;:44;;;4682:3;4661:25;;:10;:25;;;;4642:44;4634:86;;;;;;;-1:-1:-1;;;;;4634:86:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;4634:86:18;;;;;;;;;;;;;;;12797:22;;;;:9;:22;;;;;:29;;;:44;;12831:9;12797:44;:33;:44;:::i;:::-;12765:22;;;;:9;:22;;;;;;;;;:29;;:76;;;12856:86;;12889:9;12856:86;;;;;;;;;;;12931:10;;12775:11;;12856:86;;;;;;;;;12655:294;;;;:::o;3722:59::-;;;;;;;;;;;;;:::o;56:44:1:-;;;;;;;;;;;;;;:::o;10145:768:18:-;10371:7;10399:22;;;:9;:22;;;;;;10371:7;;;;10399:26;-1:-1:-1;10391:58:18;;;;;-1:-1:-1;;;;;10391:58:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;10510:11;10523:10;10535:8;10493:51;;;;;;;;;;;;;;;-1:-1:-1;;;10493:51:18;;;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;10493:51:18;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;10493:51:18;;;10483:62;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;10483:62:18;;;;;;;;;;;;10587:70;;;;;;-1:-1:-1;;;;;10587:70:18;;;;;;;;;;;;;-1:-1:-1;;;10587:70:18;;;;;10639:10;10587:70;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;10587:70:18;;;;;;;;10577:81;;10483:62;;-1:-1:-1;10587:70:18;;-1:-1:-1;10587:70:18;;-1:-1:-1;10587:70:18;;10577:81;;;-1:-1:-1;10577:81:18;10587:70;10577:81;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;10577:81:18;;;;;;;;;;;;;;;;10555:103;;10669:72;10682:11;10695:12;10709:10;10721:7;10730:10;10669:12;:72::i;:::-;10819:12;10756:121;;;10784:10;-1:-1:-1;;;;;10756:121:18;10771:11;10756:121;;;;10796:11;10809:8;10833:10;10845:7;10854:10;10866:5;10873:3;10756:121;;;;;;;;;;;;-1:-1:-1;;;;;10756:121:18;-1:-1:-1;;;;;10756:121:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;10756:121:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10895:11;10145:768;-1:-1:-1;;;;;;;;10145:768:18:o;13440:410::-;4387:18;4210:22;;;:9;:22;;;;;:30;;;:22;;4387:18;;;-1:-1:-1;;;4210:30:18;;;;-1:-1:-1;;4202:66:18;;;;;-1:-1:-1;;;;;4202:66:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;4202:66:18;;;;;;;;;;;;;;;4287:22;;;;:9;:22;;;;;:45;;;;;4286:46;4278:99;;;;;-1:-1:-1;;;;;4278:99:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;4278:99:18;;;;-1:-1:-1;;;;;;;;;;;4278:99:18;;;;;;;;;;;;;;;4408:22;;;;:9;:22;;;;;:34;;;-1:-1:-1;;;4408:34:18;;;;;-1:-1:-1;4460:25:18;;;:54;;;4510:3;4489:25;;:11;:25;;;4460:54;4452:109;;;;;;;-1:-1:-1;;;;;4452:109:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;4452:109:18;;;;-1:-1:-1;;;;;;;;;;;4452:109:18;;;;;;;;;;;;;;;-1:-1:-1;4591:22:18;;;;:9;:22;;;;;:33;;;-1:-1:-1;;;4591:33:18;;;;4642:15;;;:44;;;4682:3;4661:25;;:10;:25;;;;4642:44;4634:86;;;;;;;-1:-1:-1;;;;;4634:86:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;4634:86:18;;;;;;;;;;;;;;;13576:11;5647:1;5635:9;:13;5627:47;;;;;-1:-1:-1;;;;;5627:47:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;5707:22;;;;:9;:22;;;;;:27;;;:34;;5739:1;5707:34;:31;:34;:::i;:::-;5693:9;:49;;5685:104;;;;;-1:-1:-1;;;;;5685:104:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13632:11;13645:12;5929:1;5914:12;:16;5910:132;;;5954:22;;;;:9;:22;;;;;:27;;;:43;-1:-1:-1;5954:43:18;5946:85;;;;;-1:-1:-1;;;;;5946:85:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;5946:85:18;;;;;;;;;;;;;;;13690:70;13710:11;13723:6;13731:10;13743:9;13754:5;13690:19;:70::i;:::-;13812:22;;;;:9;:22;;;;;:30;;;13770:73;;13812:22;;13804:6;;-1:-1:-1;;;13812:30:18;;;;13770:20;:73::i;:::-;5799:1;;4731;13440:410;;;;;;:::o;24515:275::-;24583:4;24620:22;;;:9;:22;;;;;:34;;;;24674:45;;;;;-1:-1:-1;;;24620:34:18;;;;;;24674:45;;24673:46;:76;;;;-1:-1:-1;726:1:18;24724:24;;;;24673:76;:108;;;;;24776:3;24754:26;;:11;:26;;;;24673:108;24664:119;24515:275;-1:-1:-1;;;24515:275:18:o;38894:138::-;38964:7;38990:22;;;:9;:22;;;;;:35;;;;38894:138::o;3667:49::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7617:348::-;7729:14;;7697:7;7753:13;;;:9;:13;;;;;;;;7769:12;7753:28;;7823:25;;;7697:7;;7729:14;7840:7;;7823:25;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;7823:25:18;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;7823:25:18;;;7813:36;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;7813:36:18;;;;;;;;;;;;-1:-1:-1;7791:19:18;;;:15;:19;;;;;:58;;;;7864:39;;;;;;;;;;;7883:10;;-1:-1:-1;7791:19:18;;-1:-1:-1;7864:39:18;;;;-1:-1:-1;7813:36:18;;7864:39;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;7864:39:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7930:9;:2;7937:1;7930:9;:6;:9;:::i;:::-;7913:14;:26;7956:2;7617:348;-1:-1:-1;;7617:348:18:o;38574:136::-;38643:7;38669:22;;;:9;:22;;;;;;;;:34;;;38574:136::o;38012:151::-;38088:4;38111:22;;;:9;:22;;;;;:45;;;;;;38012:151::o;3562:45::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3562:45:18;;;;-1:-1:-1;;;3562:45:18;;;;;-1:-1:-1;;;3562:45:18;;;;;-1:-1:-1;;;3562:45:18;;;;;;;;;;;;:::o;37225:133::-;37293:6;37318:22;;;:9;:22;;;;;:33;;;-1:-1:-1;;;37318:33:18;;;;;37225:133::o;37485:128::-;37551:6;37576:22;;;:9;:22;;;;;:30;;;-1:-1:-1;;;37576:30:18;;;;;37485:128::o;8839:424::-;9101:7;9120:19;9142:23;9157:7;9142:14;:23::i;:::-;9120:45;;9182:74;9194:11;9207:8;9217:10;9229:7;9238:10;9250:5;9182:11;:74::i;:::-;9175:81;8839:424;-1:-1:-1;;;;;;;;8839:424:18:o;25005:176::-;25114:7;25074:11;5493:24;5505:11;5493;:24::i;:::-;5485:63;;;;;;;-1:-1:-1;;;;;5485:63:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;25140:22:18;;;;:9;:22;;;;;;;;:34;;;25005:176::o;37752:135::-;37821:6;37846:22;;;:9;:22;;;;;:34;;;-1:-1:-1;;;37846:34:18;;;;;37752:135::o;3456:44::-;;;;;;;;;;;;;:::o;23257:1079::-;23479:18;23528:22;;;:9;:22;;;;;:35;;;;23614:27;;;;;23479:18;;23500:157;;23565:17;;23584:28;;23643:13;23500:27;:157::i;:::-;23479:178;;23883:13;:71;;;;-1:-1:-1;23901:41:18;;;;:11;:41;;;;;:53;;;;;;23900:54;23883:71;23879:389;;;23978:41;;;;:11;:41;;;;;:51;:65;24039:3;23978:65;;:51;;:65;23970:133;;;;;-1:-1:-1;;;;;23970:133:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;24125:14:18;23879:389;;;24179:44;:22;;;:9;:22;;;;;;;;:34;;:44;;24178:79;;24243:14;24178:79;;;24227:13;24178:79;24170:87;;23879:389;24277:52;24302:11;24315:6;24323:5;24277:24;:52::i;:::-;23257:1079;;;;;;;;:::o;16479:600::-;16764:21;4210:22;;;:9;:22;;;;;:30;;;16764:21;;4210:22;;16764:21;;;;-1:-1:-1;;;4210:30:18;;;;-1:-1:-1;;4202:66:18;;;;;-1:-1:-1;;;;;4202:66:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;4202:66:18;;;;;;;;;;;;;;;4287:22;;;;:9;:22;;;;;:45;;;;;4286:46;4278:99;;;;;-1:-1:-1;;;;;4278:99:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;4278:99:18;;;;-1:-1:-1;;;;;;;;;;;4278:99:18;;;;;;;;;;;;;;;4408:22;;;;:9;:22;;;;;:34;;;-1:-1:-1;;;4408:34:18;;;;;-1:-1:-1;4460:25:18;;;:54;;;4510:3;4489:25;;:11;:25;;;4460:54;4452:109;;;;;;;-1:-1:-1;;;;;4452:109:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;4452:109:18;;;;-1:-1:-1;;;;;;;;;;;4452:109:18;;;;;;;;;;;;;;;-1:-1:-1;4591:22:18;;;;:9;:22;;;;;:33;;;-1:-1:-1;;;4591:33:18;;;;4642:15;;;:44;;;4682:3;4661:25;;:10;:25;;;;4642:44;4634:86;;;;;;;-1:-1:-1;;;;;4634:86:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;4634:86:18;;;;;;;;;;;;;;;16649:11;5647:1;5635:9;:13;5627:47;;;;;-1:-1:-1;;;;;5627:47:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;5707:22;;;;:9;:22;;;;;:27;;;:34;;5739:1;5707:34;:31;:34;:::i;:::-;5693:9;:49;;5685:104;;;;;-1:-1:-1;;;;;5685:104:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16705:11;16718:12;5929:1;5914:12;:16;5910:132;;;5954:22;;;;:9;:22;;;;;:27;;;:43;-1:-1:-1;5954:43:18;5946:85;;;;;-1:-1:-1;;;;;5946:85:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;5946:85:18;;;;;;;;;;;;;;;16798:53;;;;;;;;;;;;;;;;16841:9;16798:53;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;16798:53:18;;;;;;;;16788:64;;16798:53;;;;;16788:64;;;;16798:53;16788:64;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;;;;365:33;;16788:64:18;;;;;;;;;;;-1:-1:-1;;;;;;;;;16882:25:18;;;16881:52;;16924:9;16881:52;;;16911:10;16881:52;16862:71;;16943:44;16960:11;16973:13;16943:16;:44::i;:::-;16997:74;17017:11;17030:13;17045:8;17055:9;17066:4;16997:19;:74::i;:::-;5799:1;;4731;16479:600;;;;;;;;;:::o;21102:355::-;3866:22;;;;:9;:22;;;;;:33;;;:22;;-1:-1:-1;;;;;3866:33:18;3852:10;:47;3844:89;;;;;-1:-1:-1;;;;;3844:89:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;4817:22;;;;:9;:22;;;;;:45;;;21219:11;;4817:45;;4809:94;;;;;;;-1:-1:-1;;;;;4809:94:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21303:5;21255:22;;;:9;:22;;;;;:45;;;:53;;-1:-1:-1;;21255:53:18;;;-1:-1:-1;21371:30:18;;21355:47;;21371:30;21362:3;21355:15;;;-1:-1:-1;;;21371:30:18;;;;;21355:15;:47;:::i;:::-;21318:22;;;;:9;:22;;;;;;:34;;:84;;;;;;;-1:-1:-1;;;21318:84:18;;;;;;;;;;;;21417:33;;21328:11;;21417:33;;;3943:1;21102:355;;:::o;20367:506::-;3866:22;;;;:9;:22;;;;;:33;;;:22;;-1:-1:-1;;;;;3866:33:18;3852:10;:47;3844:89;;;;;-1:-1:-1;;;;;3844:89:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;4387:18;4210:22;;;:9;:22;;;;;:30;;;:22;;4387:18;;;-1:-1:-1;;;4210:30:18;;;;-1:-1:-1;;4202:66:18;;;;;-1:-1:-1;;;;;4202:66:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;4202:66:18;;;;;;;;;;;;;;;4287:22;;;;:9;:22;;;;;:45;;;;;4286:46;4278:99;;;;;-1:-1:-1;;;;;4278:99:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;4278:99:18;;;;-1:-1:-1;;;;;;;;;;;4278:99:18;;;;;;;;;;;;;;;4408:22;;;;:9;:22;;;;;:34;;;-1:-1:-1;;;4408:34:18;;;;;-1:-1:-1;4460:25:18;;;:54;;;4510:3;4489:25;;:11;:25;;;4460:54;4452:109;;;;;;;-1:-1:-1;;;;;4452:109:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;4452:109:18;;;;-1:-1:-1;;;;;;;;;;;4452:109:18;;;;;;;;;;;;;;;-1:-1:-1;4591:22:18;;;;:9;:22;;;;;:33;;;-1:-1:-1;;;4591:33:18;;;;4642:15;;;:44;;;4682:3;4661:25;;:10;:25;;;;4642:44;4634:86;;;;;;;-1:-1:-1;;;;;4634:86:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;4634:86:18;;;;;;;;;;;;;;;20576:11;20589:12;5929:1;5914:12;:16;5910:132;;;5954:22;;;;:9;:22;;;;;:27;;;:43;-1:-1:-1;5954:43:18;5946:85;;;;;-1:-1:-1;;;;;5946:85:18;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;5946:85:18;;;;;;;;;;;;;;;20664:1;20634:22;;;:9;:22;;;;;:27;;;:31;20626:110;;;;;-1:-1:-1;;;;;20626:110:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20746:22;;;;:9;:22;;;;;;:45;;:52;;-1:-1:-1;;20746:52:18;20794:4;20746:52;;;20813:53;-1:-1:-1;;;;;20813:53:18;;;20756:11;;20813:53;;20746:22;20813:53;4731:1;;3943;;;20367:506;;;;:::o;22053:498::-;3866:22;;;;:9;:22;;;;;:33;;;:22;;-1:-1:-1;;;;;3866:33:18;3852:10;:47;3844:89;;;;;-1:-1:-1;;;;;3844:89:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;4817:22;;;;:9;:22;;;;;:45;;;22211:11;;4817:45;;4809:94;;;;;;;-1:-1:-1;;;;;4809:94:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;22254:24:18;;;;22246:62;;;;;-1:-1:-1;;;;;22246:62:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;22323:32;;22348:6;;22335:11;;22323:32;;;;;22414:5;22366:22;;;:9;:22;;;;;:45;;:53;;-1:-1:-1;;22366:53:18;;;22429:60;;22376:11;;22462:6;;22470:8;;22414:5;22429:19;:60::i;:::-;22499:44;22520:11;22533:6;22541:1;22499:20;:44::i;:::-;3943:1;22053:498;;;;:::o;31638:549::-;31868:56;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;31868:56:18;;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;31868:56:18;;;;;;;;31858:67;;31817:4;;31868:56;;;31858:67;;;;;31868:56;31858:67;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;;;;365:33;;31858:67:18;;;;;;;;;;31837:88;;31833:131;;-1:-1:-1;31833:131:18;;-1:-1:-1;;31833:131:18;-1:-1:-1;31949:4:18;31942:11;;31833:131;32008:57;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;32008:57:18;;;;;;;32059:5;32008:57;;;;;;22:32:-1;26:21;;;22:32;6:49;;32008:57:18;;;;;;;;31998:68;;32008:57;;;;;31998:68;;;;32008:57;31998:68;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;;;;365:33;;31998:68:18;;;;;;;;;;31977:89;;31973:133;;-1:-1:-1;31973:133:18;;-1:-1:-1;;31973:133:18;-1:-1:-1;32090:5:18;32083:12;;31973:133;32116:64;;;-1:-1:-1;;;;;32116:64:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31638:549;;;;;;;;:::o;719:129:16:-;777:7;804:5;;;822:6;;;;815:14;;;;842:1;835:8;;719:129;;;;;;:::o;32193:2411:18:-;32419:7;32428;32665:21;34143:27;32636:13;32632:482;;;32811:26;;;;:11;:26;;;;;:38;:26;;-1:-1:-1;32811:38:18;;;;;32810:39;32806:298;;;32876:26;;;;:11;:26;;;;;32869:33;;-1:-1:-1;;32869:33:18;;;;;;32928:12;;-1:-1:-1;32942:5:18;;-1:-1:-1;32920:28:18;;32806:298;32996:26;;;;:11;:26;;;;;:42;;;;;33056:33;;-1:-1:-1;;33056:33:18;;;;;;;;32996:42;-1:-1:-1;32806:298:18;33128:21;;;33124:1434;;;-1:-1:-1;;;;;33170:21:18;;;33166:1381;;;33402:22;;;;:9;:22;;;;;:29;;;33348:4;;-1:-1:-1;33348:4:18;;33385:47;;:12;;:47;:16;:47;:::i;:::-;33482:1;33450:22;;;:9;:22;;;;;:29;;:33;33370:62;-1:-1:-1;33166:1381:18;;;-1:-1:-1;;;;;33509:13:18;;;;;;;33505:1042;;34190:4;34174:12;:20;;34173:44;;34205:12;34173:44;;;34198:4;34173:44;34143:74;-1:-1:-1;34299:68:18;34309:11;34322:5;34329:37;:12;34143:74;34329:37;:16;:37;:::i;34299:68::-;34475:4;34467:12;;34512:19;34497:34;;33505:1042;34576:12;34590:5;34568:28;;;;32193:2411;;;;;;;;;;;;;;:::o;605:110:16:-;663:7;685:6;;;;678:14;;;;-1:-1:-1;705:5:16;;;605:110::o;31435:197:18:-;-1:-1:-1;;;;;31548:16:18;;:9;:16;;;;;;;;;;;:27;;31569:5;31548:27;:20;:27;:::i;:::-;-1:-1:-1;;;;;31529:16:18;;:9;:16;;;;;;;;;;;;:46;;;;31590:35;;;;;;;31529:16;;31599:11;;31590:35;;;;;;;;;;31435:197;;;:::o;159:173:16:-;217:7;;236:6;;232:35;;;259:1;252:8;;;;232:35;-1:-1:-1;284:5:16;;;288:1;284;:5;302;;;;;;;;:10;295:18;;;18965:678:18;19129:24;19183:22;;;:9;:22;;;;;;;;:35;;;19166:109;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;19166:109:18;;;;;;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;19166:109:18;;;;;;;;19156:120;;19166:109;;;;19156:120;;;;;19166:109;19156:120;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;19156:120:18;;;;;;;;;;;;;;;;19129:147;;19391:1;19384:4;:8;19380:73;;;19408:22;;;;:9;:22;;;;;:27;;:34;;;19380:73;19462:22;;;;:9;:22;;;;;;;;;:35;;:54;;;19532:104;;;;;;;;;;;;;;;;;19617:3;19532:104;;;;;;;;;;;;;-1:-1:-1;;;;;19532:104:18;;;19472:11;;19532:104;;;;;;;;;18965:678;;;;;;:::o;19649:237::-;19760:22;;;;:9;:22;;;;;;;;:34;:43;;;19850:29;:15;19857:3;19850:15;;;19866:12;;19850:15;:29;:::i;:::-;19813:22;;;;:9;:22;;;;;;:34;;:66;;;;;;;-1:-1:-1;;;19813:66:18;;;;;;;;;;;;-1:-1:-1;;19649:237:18:o;10919:1487::-;11390:14;4065:22;;;:9;:22;;;;;:30;;;11390:14;;4065:22;;-1:-1:-1;;;4065:30:18;;;;:35;4057:71;;;;;-1:-1:-1;;;;;4057:71:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;11201:1;11191:11;;;;11183:48;;;;;-1:-1:-1;;;;;11183:48:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;11260:8;11250:18;;;;11242:65;;;;;-1:-1:-1;;;;;11242:65:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;11326:26:18;;;;11318:61;;;;;-1:-1:-1;;;;;11318:61:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;11407:9;;-1:-1:-1;11808:10:18;-1:-1:-1;;;;;11808:24:18;;;11804:324;;-1:-1:-1;;;;;11871:36:18;;;;;;:24;:36;;;;;;;-1:-1:-1;11929:22:18;;;;11921:71;;;;;-1:-1:-1;;;;;11921:71:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12016:24;:6;12027:12;12016:24;:10;:24;:::i;:::-;-1:-1:-1;;;;;12078:21:18;;:9;:21;;;;;;;;;;;12007:33;;-1:-1:-1;12078:39:18;;12104:12;12078:39;:25;:39;:::i;:::-;-1:-1:-1;;;;;12054:21:18;;:9;:21;;;;;;;;;;:63;11804:324;-1:-1:-1;;12138:22:18;;;;:9;:22;;;;;;:50;;;12198:33;;;:46;;-1:-1:-1;;12198:46:18;-1:-1:-1;;;;;12198:46:18;;;;;;;;-1:-1:-1;;12254:46:18;-1:-1:-1;;;12254:46:18;;;;;;12310:40;;-1:-1:-1;;;12310:40:18;;;;;;;;;;;12360:29;;:38;10919:1487::o;15148:394::-;15366:25;15254:26;;;:11;:26;;;;;:36;;;:63;15246:109;;;;;-1:-1:-1;;;;;15246:109:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15394:22;;;;:9;:22;;;;;:30;;;991:1;;-1:-1:-1;;;15394:30:18;;:57;:30;:57;;-1:-1:-1;15500:35:18;:15;15507:3;15500:15;;;15394:57;;15500:15;:35;:::i;:::-;15461:26;;;;:11;:26;;;;;;:74;;-1:-1:-1;;15461:74:18;;;;;;;;;;;;-1:-1:-1;;15148:394:18:o;255:125:17:-;311:6;336:5;;;354:6;;;;;;;;;347:14;;", + "source": "pragma solidity ^0.4.25;\n\nimport './RealitioSafeMath256.sol';\nimport './RealitioSafeMath32.sol';\nimport './BalanceHolder.sol';\n\n// Next version of Realitio v2, will be deployed on xdai, may be deployed to other networks in future\n// API-compatible with Realitio v2, address will be stored in Realitio.json\ncontract Realitio_v2_1 is BalanceHolder {\n\n using RealitioSafeMath256 for uint256;\n using RealitioSafeMath32 for uint32;\n\n address constant NULL_ADDRESS = address(0);\n\n // History hash when no history is created, or history has been cleared\n bytes32 constant NULL_HASH = bytes32(0);\n\n // An unitinalized finalize_ts for a question will indicate an unanswered question.\n uint32 constant UNANSWERED = 0;\n\n // An unanswered reveal_ts for a commitment will indicate that it does not exist.\n uint256 constant COMMITMENT_NON_EXISTENT = 0;\n\n // Commit->reveal timeout is 1/8 of the question timeout (rounded down).\n uint32 constant COMMITMENT_TIMEOUT_RATIO = 8;\n\n // Proportion withheld when you claim an earlier bond.\n uint256 constant BOND_CLAIM_FEE_PROPORTION = 40; // One 40th ie 2.5%\n\n event LogSetQuestionFee(\n address arbitrator,\n uint256 amount\n );\n\n event LogNewTemplate(\n uint256 indexed template_id,\n address indexed user, \n string question_text\n );\n\n event LogNewQuestion(\n bytes32 indexed question_id,\n address indexed user, \n uint256 template_id,\n string question,\n bytes32 indexed content_hash,\n address arbitrator, \n uint32 timeout,\n uint32 opening_ts,\n uint256 nonce,\n uint256 created\n );\n\n event LogFundAnswerBounty(\n bytes32 indexed question_id,\n uint256 bounty_added,\n uint256 bounty,\n address indexed user \n );\n\n event LogNewAnswer(\n bytes32 answer,\n bytes32 indexed question_id,\n bytes32 history_hash,\n address indexed user,\n uint256 bond,\n uint256 ts,\n bool is_commitment\n );\n\n event LogAnswerReveal(\n bytes32 indexed question_id, \n address indexed user, \n bytes32 indexed answer_hash, \n bytes32 answer, \n uint256 nonce, \n uint256 bond\n );\n\n event LogNotifyOfArbitrationRequest(\n bytes32 indexed question_id,\n address indexed user \n );\n\n event LogCancelArbitration(\n bytes32 indexed question_id\n );\n\n event LogFinalize(\n bytes32 indexed question_id,\n bytes32 indexed answer\n );\n\n event LogClaim(\n bytes32 indexed question_id,\n address indexed user,\n uint256 amount\n );\n\n struct Question {\n bytes32 content_hash;\n address arbitrator;\n uint32 opening_ts;\n uint32 timeout;\n uint32 finalize_ts;\n bool is_pending_arbitration;\n uint256 bounty;\n bytes32 best_answer;\n bytes32 history_hash;\n uint256 bond;\n }\n\n // Stored in a mapping indexed by commitment_id, a hash of commitment hash, question, bond. \n struct Commitment {\n uint32 reveal_ts;\n bool is_revealed;\n bytes32 revealed_answer;\n }\n\n // Only used when claiming more bonds than fits into a transaction\n // Stored in a mapping indexed by question_id.\n struct Claim {\n address payee;\n uint256 last_bond;\n uint256 queued_funds;\n }\n\n uint256 nextTemplateID = 0;\n mapping(uint256 => uint256) public templates;\n mapping(uint256 => bytes32) public template_hashes;\n mapping(bytes32 => Question) public questions;\n mapping(bytes32 => Claim) public question_claims;\n mapping(bytes32 => Commitment) public commitments;\n mapping(address => uint256) public arbitrator_question_fees; \n\n modifier onlyArbitrator(bytes32 question_id) {\n require(msg.sender == questions[question_id].arbitrator, \"msg.sender must be arbitrator\");\n _;\n }\n\n modifier stateAny() {\n _;\n }\n\n modifier stateNotCreated(bytes32 question_id) {\n require(questions[question_id].timeout == 0, \"question must not exist\");\n _;\n }\n\n modifier stateOpen(bytes32 question_id) {\n require(questions[question_id].timeout > 0, \"question must exist\");\n require(!questions[question_id].is_pending_arbitration, \"question must not be pending arbitration\");\n uint32 finalize_ts = questions[question_id].finalize_ts;\n require(finalize_ts == UNANSWERED || finalize_ts > uint32(now), \"finalization deadline must not have passed\");\n uint32 opening_ts = questions[question_id].opening_ts;\n require(opening_ts == 0 || opening_ts <= uint32(now), \"opening date must have passed\"); \n _;\n }\n\n modifier statePendingArbitration(bytes32 question_id) {\n require(questions[question_id].is_pending_arbitration, \"question must be pending arbitration\");\n _;\n }\n\n modifier stateOpenOrPendingArbitration(bytes32 question_id) {\n require(questions[question_id].timeout > 0, \"question must exist\");\n uint32 finalize_ts = questions[question_id].finalize_ts;\n require(finalize_ts == UNANSWERED || finalize_ts > uint32(now), \"finalization dealine must not have passed\");\n uint32 opening_ts = questions[question_id].opening_ts;\n require(opening_ts == 0 || opening_ts <= uint32(now), \"opening date must have passed\"); \n _;\n }\n\n modifier stateFinalized(bytes32 question_id) {\n require(isFinalized(question_id), \"question must be finalized\");\n _;\n }\n\n modifier bondMustDouble(bytes32 question_id) {\n require(msg.value > 0, \"bond must be positive\"); \n require(msg.value >= (questions[question_id].bond.mul(2)), \"bond must be double at least previous bond\");\n _;\n }\n\n modifier previousBondMustNotBeatMaxPrevious(bytes32 question_id, uint256 max_previous) {\n if (max_previous > 0) {\n require(questions[question_id].bond <= max_previous, \"bond must exceed max_previous\");\n }\n _;\n }\n\n /// @notice Constructor, sets up some initial templates\n /// @dev Creates some generalized templates for different question types used in the DApp.\n constructor() \n public {\n createTemplate('{\"title\": \"%s\", \"type\": \"bool\", \"category\": \"%s\", \"lang\": \"%s\"}');\n createTemplate('{\"title\": \"%s\", \"type\": \"uint\", \"decimals\": 18, \"category\": \"%s\", \"lang\": \"%s\"}');\n createTemplate('{\"title\": \"%s\", \"type\": \"single-select\", \"outcomes\": [%s], \"category\": \"%s\", \"lang\": \"%s\"}');\n createTemplate('{\"title\": \"%s\", \"type\": \"multiple-select\", \"outcomes\": [%s], \"category\": \"%s\", \"lang\": \"%s\"}');\n createTemplate('{\"title\": \"%s\", \"type\": \"datetime\", \"category\": \"%s\", \"lang\": \"%s\"}');\n }\n\n /// @notice Function for arbitrator to set an optional per-question fee. \n /// @dev The per-question fee, charged when a question is asked, is intended as an anti-spam measure.\n /// @param fee The fee to be charged by the arbitrator when a question is asked\n function setQuestionFee(uint256 fee) \n stateAny() \n external {\n arbitrator_question_fees[msg.sender] = fee;\n emit LogSetQuestionFee(msg.sender, fee);\n }\n\n /// @notice Create a reusable template, which should be a JSON document.\n /// Placeholders should use gettext() syntax, eg %s.\n /// @dev Template data is only stored in the event logs, but its block number is kept in contract storage.\n /// @param content The template content\n /// @return The ID of the newly-created template, which is created sequentially.\n function createTemplate(string content) \n stateAny()\n public returns (uint256) {\n uint256 id = nextTemplateID;\n templates[id] = block.number;\n template_hashes[id] = keccak256(abi.encodePacked(content));\n emit LogNewTemplate(id, msg.sender, content);\n nextTemplateID = id.add(1);\n return id;\n }\n\n /// @notice Create a new reusable template and use it to ask a question\n /// @dev Template data is only stored in the event logs, but its block number is kept in contract storage.\n /// @param content The template content\n /// @param question A string containing the parameters that will be passed into the template to make the question\n /// @param arbitrator The arbitration contract that will have the final word on the answer if there is a dispute\n /// @param timeout How long the contract should wait after the answer is changed before finalizing on that answer\n /// @param opening_ts If set, the earliest time it should be possible to answer the question.\n /// @param nonce A user-specified nonce used in the question ID. Change it to repeat a question.\n /// @return The ID of the newly-created template, which is created sequentially.\n function createTemplateAndAskQuestion(\n string content, \n string question, address arbitrator, uint32 timeout, uint32 opening_ts, uint256 nonce \n ) \n // stateNotCreated is enforced by the internal _askQuestion\n public payable returns (bytes32) {\n uint256 template_id = createTemplate(content);\n return askQuestion(template_id, question, arbitrator, timeout, opening_ts, nonce);\n }\n\n /// @notice Ask a new question and return the ID\n /// @dev Template data is only stored in the event logs, but its block number is kept in contract storage.\n /// @param template_id The ID number of the template the question will use\n /// @param question A string containing the parameters that will be passed into the template to make the question\n /// @param arbitrator The arbitration contract that will have the final word on the answer if there is a dispute\n /// @param timeout How long the contract should wait after the answer is changed before finalizing on that answer\n /// @param opening_ts If set, the earliest time it should be possible to answer the question.\n /// @param nonce A user-specified nonce used in the question ID. Change it to repeat a question.\n /// @return The ID of the newly-created question, created deterministically.\n function askQuestion(uint256 template_id, string question, address arbitrator, uint32 timeout, uint32 opening_ts, uint256 nonce) \n // stateNotCreated is enforced by the internal _askQuestion\n public payable returns (bytes32) {\n\n require(templates[template_id] > 0, \"template must exist\");\n\n bytes32 content_hash = keccak256(abi.encodePacked(template_id, opening_ts, question));\n bytes32 question_id = keccak256(abi.encodePacked(content_hash, arbitrator, timeout, msg.sender, nonce));\n\n _askQuestion(question_id, content_hash, arbitrator, timeout, opening_ts);\n emit LogNewQuestion(question_id, msg.sender, template_id, question, content_hash, arbitrator, timeout, opening_ts, nonce, now);\n\n return question_id;\n }\n\n function _askQuestion(bytes32 question_id, bytes32 content_hash, address arbitrator, uint32 timeout, uint32 opening_ts) \n stateNotCreated(question_id)\n internal {\n\n // A timeout of 0 makes no sense, and we will use this to check existence\n require(timeout > 0, \"timeout must be positive\"); \n require(timeout < 365 days, \"timeout must be less than 365 days\"); \n require(arbitrator != NULL_ADDRESS, \"arbitrator must be set\");\n\n uint256 bounty = msg.value;\n\n // The arbitrator can set a fee for asking a question. \n // This is intended as an anti-spam defence.\n // The fee is waived if the arbitrator is asking the question.\n // This allows them to set an impossibly high fee and make users proxy the question through them.\n // This would allow more sophisticated pricing, question whitelisting etc.\n if (msg.sender != arbitrator) {\n uint256 question_fee = arbitrator_question_fees[arbitrator];\n require(bounty >= question_fee, \"ETH provided must cover question fee\"); \n bounty = bounty.sub(question_fee);\n balanceOf[arbitrator] = balanceOf[arbitrator].add(question_fee);\n }\n\n questions[question_id].content_hash = content_hash;\n questions[question_id].arbitrator = arbitrator;\n questions[question_id].opening_ts = opening_ts;\n questions[question_id].timeout = timeout;\n questions[question_id].bounty = bounty;\n\n }\n\n /// @notice Add funds to the bounty for a question\n /// @dev Add bounty funds after the initial question creation. Can be done any time until the question is finalized.\n /// @param question_id The ID of the question you wish to fund\n function fundAnswerBounty(bytes32 question_id) \n stateOpen(question_id)\n external payable {\n questions[question_id].bounty = questions[question_id].bounty.add(msg.value);\n emit LogFundAnswerBounty(question_id, msg.value, questions[question_id].bounty, msg.sender);\n }\n\n /// @notice Submit an answer for a question.\n /// @dev Adds the answer to the history and updates the current \"best\" answer.\n /// May be subject to front-running attacks; Substitute submitAnswerCommitment()->submitAnswerReveal() to prevent them.\n /// @param question_id The ID of the question\n /// @param answer The answer, encoded into bytes32\n /// @param max_previous If specified, reverts if a bond higher than this was submitted after you sent your transaction.\n function submitAnswer(bytes32 question_id, bytes32 answer, uint256 max_previous) \n stateOpen(question_id)\n bondMustDouble(question_id)\n previousBondMustNotBeatMaxPrevious(question_id, max_previous)\n external payable {\n _addAnswerToHistory(question_id, answer, msg.sender, msg.value, false);\n _updateCurrentAnswer(question_id, answer, questions[question_id].timeout);\n }\n\n /// @notice Submit an answer for a question, crediting it to the specified account.\n /// @dev Adds the answer to the history and updates the current \"best\" answer.\n /// May be subject to front-running attacks; Substitute submitAnswerCommitment()->submitAnswerReveal() to prevent them.\n /// @param question_id The ID of the question\n /// @param answer The answer, encoded into bytes32\n /// @param max_previous If specified, reverts if a bond higher than this was submitted after you sent your transaction.\n /// @param answerer The account to which the answer should be credited\n function submitAnswerFor(bytes32 question_id, bytes32 answer, uint256 max_previous, address answerer)\n stateOpen(question_id)\n bondMustDouble(question_id)\n previousBondMustNotBeatMaxPrevious(question_id, max_previous)\n external payable {\n require(answerer != NULL_ADDRESS, \"answerer must be non-zero\");\n _addAnswerToHistory(question_id, answer, answerer, msg.value, false);\n _updateCurrentAnswer(question_id, answer, questions[question_id].timeout);\n }\n\n // @notice Verify and store a commitment, including an appropriate timeout\n // @param question_id The ID of the question to store\n // @param commitment The ID of the commitment\n function _storeCommitment(bytes32 question_id, bytes32 commitment_id) \n internal\n {\n require(commitments[commitment_id].reveal_ts == COMMITMENT_NON_EXISTENT, \"commitment must not already exist\");\n\n uint32 commitment_timeout = questions[question_id].timeout / COMMITMENT_TIMEOUT_RATIO;\n commitments[commitment_id].reveal_ts = uint32(now).add(commitment_timeout);\n }\n\n /// @notice Submit the hash of an answer, laying your claim to that answer if you reveal it in a subsequent transaction.\n /// @dev Creates a hash, commitment_id, uniquely identifying this answer, to this question, with this bond.\n /// The commitment_id is stored in the answer history where the answer would normally go.\n /// Does not update the current best answer - this is left to the later submitAnswerReveal() transaction.\n /// @param question_id The ID of the question\n /// @param answer_hash The hash of your answer, plus a nonce that you will later reveal\n /// @param max_previous If specified, reverts if a bond higher than this was submitted after you sent your transaction.\n /// @param _answerer If specified, the address to be given as the question answerer. Defaults to the sender.\n /// @dev Specifying the answerer is useful if you want to delegate the commit-and-reveal to a third-party.\n function submitAnswerCommitment(bytes32 question_id, bytes32 answer_hash, uint256 max_previous, address _answerer) \n stateOpen(question_id)\n bondMustDouble(question_id)\n previousBondMustNotBeatMaxPrevious(question_id, max_previous)\n external payable {\n\n bytes32 commitment_id = keccak256(abi.encodePacked(question_id, answer_hash, msg.value));\n address answerer = (_answerer == NULL_ADDRESS) ? msg.sender : _answerer;\n _storeCommitment(question_id, commitment_id);\n _addAnswerToHistory(question_id, commitment_id, answerer, msg.value, true);\n\n }\n\n /// @notice Submit the answer whose hash you sent in a previous submitAnswerCommitment() transaction\n /// @dev Checks the parameters supplied recreate an existing commitment, and stores the revealed answer\n /// Updates the current answer unless someone has since supplied a new answer with a higher bond\n /// msg.sender is intentionally not restricted to the user who originally sent the commitment; \n /// For example, the user may want to provide the answer+nonce to a third-party service and let them send the tx\n /// NB If we are pending arbitration, it will be up to the arbitrator to wait and see any outstanding reveal is sent\n /// @param question_id The ID of the question\n /// @param answer The answer, encoded as bytes32\n /// @param nonce The nonce that, combined with the answer, recreates the answer_hash you gave in submitAnswerCommitment()\n /// @param bond The bond that you paid in your submitAnswerCommitment() transaction\n function submitAnswerReveal(bytes32 question_id, bytes32 answer, uint256 nonce, uint256 bond) \n stateOpenOrPendingArbitration(question_id)\n external {\n\n bytes32 answer_hash = keccak256(abi.encodePacked(answer, nonce));\n bytes32 commitment_id = keccak256(abi.encodePacked(question_id, answer_hash, bond));\n\n require(!commitments[commitment_id].is_revealed, \"commitment must not have been revealed yet\");\n require(commitments[commitment_id].reveal_ts > uint32(now), \"reveal deadline must not have passed\");\n\n commitments[commitment_id].revealed_answer = answer;\n commitments[commitment_id].is_revealed = true;\n\n if (bond == questions[question_id].bond) {\n _updateCurrentAnswer(question_id, answer, questions[question_id].timeout);\n }\n\n emit LogAnswerReveal(question_id, msg.sender, answer_hash, answer, nonce, bond);\n\n }\n\n function _addAnswerToHistory(bytes32 question_id, bytes32 answer_or_commitment_id, address answerer, uint256 bond, bool is_commitment) \n internal \n {\n bytes32 new_history_hash = keccak256(abi.encodePacked(questions[question_id].history_hash, answer_or_commitment_id, bond, answerer, is_commitment));\n\n // Update the current bond level, if there's a bond (ie anything except arbitration)\n if (bond > 0) {\n questions[question_id].bond = bond;\n }\n questions[question_id].history_hash = new_history_hash;\n\n emit LogNewAnswer(answer_or_commitment_id, question_id, new_history_hash, answerer, bond, now, is_commitment);\n }\n\n function _updateCurrentAnswer(bytes32 question_id, bytes32 answer, uint32 timeout_secs)\n internal {\n questions[question_id].best_answer = answer;\n questions[question_id].finalize_ts = uint32(now).add(timeout_secs);\n }\n\n /// @notice Notify the contract that the arbitrator has been paid for a question, freezing it pending their decision.\n /// @dev The arbitrator contract is trusted to only call this if they've been paid, and tell us who paid them.\n /// @param question_id The ID of the question\n /// @param requester The account that requested arbitration\n /// @param max_previous If specified, reverts if a bond higher than this was submitted after you sent your transaction.\n function notifyOfArbitrationRequest(bytes32 question_id, address requester, uint256 max_previous) \n onlyArbitrator(question_id)\n stateOpen(question_id)\n previousBondMustNotBeatMaxPrevious(question_id, max_previous)\n external {\n require(questions[question_id].bond > 0, \"Question must already have an answer when arbitration is requested\");\n questions[question_id].is_pending_arbitration = true;\n emit LogNotifyOfArbitrationRequest(question_id, requester);\n }\n\n /// @notice Cancel a previously-requested arbitration and extend the timeout\n /// @dev Useful when doing arbitration across chains that can't be requested atomically\n /// @param question_id The ID of the question\n function cancelArbitration(bytes32 question_id) \n onlyArbitrator(question_id)\n statePendingArbitration(question_id)\n external {\n questions[question_id].is_pending_arbitration = false;\n questions[question_id].finalize_ts = uint32(now).add(questions[question_id].timeout);\n emit LogCancelArbitration(question_id);\n }\n\n /// @notice Submit the answer for a question, for use by the arbitrator.\n /// @dev Doesn't require (or allow) a bond.\n /// If the current final answer is correct, the account should be whoever submitted it.\n /// If the current final answer is wrong, the account should be whoever paid for arbitration.\n /// However, the answerer stipulations are not enforced by the contract.\n /// @param question_id The ID of the question\n /// @param answer The answer, encoded into bytes32\n /// @param answerer The account credited with this answer for the purpose of bond claims\n function submitAnswerByArbitrator(bytes32 question_id, bytes32 answer, address answerer) \n onlyArbitrator(question_id)\n statePendingArbitration(question_id)\n public {\n\n require(answerer != NULL_ADDRESS, \"answerer must be provided\");\n emit LogFinalize(question_id, answer);\n\n questions[question_id].is_pending_arbitration = false;\n _addAnswerToHistory(question_id, answer, answerer, 0, false);\n _updateCurrentAnswer(question_id, answer, 0);\n\n }\n\n /// @notice Submit the answer for a question, for use by the arbitrator, working out the appropriate winner based on the last answer details.\n /// @dev Doesn't require (or allow) a bond.\n /// @param question_id The ID of the question\n /// @param answer The answer, encoded into bytes32\n /// @param payee_if_wrong The account to by credited as winner if the last answer given is wrong, usually the account that paid the arbitrator\n /// @param last_history_hash The history hash before the final one\n /// @param last_answer_or_commitment_id The last answer given, or the commitment ID if it was a commitment.\n /// @param last_answerer The address that supplied the last answer\n function assignWinnerAndSubmitAnswerByArbitrator(bytes32 question_id, bytes32 answer, address payee_if_wrong, bytes32 last_history_hash, bytes32 last_answer_or_commitment_id, address last_answerer) \n external {\n bool is_commitment = _verifyHistoryInputOrRevert(questions[question_id].history_hash, last_history_hash, last_answer_or_commitment_id, questions[question_id].bond, last_answerer);\n\n address payee;\n // If the last answer is an unrevealed commit, it's always wrong.\n // For anything else, the last answer was set as the \"best answer\" in submitAnswer or submitAnswerReveal.\n if (is_commitment && !commitments[last_answer_or_commitment_id].is_revealed) {\n require(commitments[last_answer_or_commitment_id].reveal_ts < uint32(now), \"You must wait for the reveal deadline before finalizing\");\n payee = payee_if_wrong;\n } else {\n payee = (questions[question_id].best_answer == answer) ? last_answerer : payee_if_wrong;\n }\n submitAnswerByArbitrator(question_id, answer, payee);\n }\n\n\n /// @notice Report whether the answer to the specified question is finalized\n /// @param question_id The ID of the question\n /// @return Return true if finalized\n function isFinalized(bytes32 question_id) \n view public returns (bool) {\n uint32 finalize_ts = questions[question_id].finalize_ts;\n return ( !questions[question_id].is_pending_arbitration && (finalize_ts > UNANSWERED) && (finalize_ts <= uint32(now)) );\n }\n\n /// @notice (Deprecated) Return the final answer to the specified question, or revert if there isn't one\n /// @param question_id The ID of the question\n /// @return The answer formatted as a bytes32\n function getFinalAnswer(bytes32 question_id) \n stateFinalized(question_id)\n external view returns (bytes32) {\n return questions[question_id].best_answer;\n }\n\n /// @notice Return the final answer to the specified question, or revert if there isn't one\n /// @param question_id The ID of the question\n /// @return The answer formatted as a bytes32\n function resultFor(bytes32 question_id) \n stateFinalized(question_id)\n external view returns (bytes32) {\n return questions[question_id].best_answer;\n }\n\n\n /// @notice Return the final answer to the specified question, provided it matches the specified criteria.\n /// @dev Reverts if the question is not finalized, or if it does not match the specified criteria.\n /// @param question_id The ID of the question\n /// @param content_hash The hash of the question content (template ID + opening time + question parameter string)\n /// @param arbitrator The arbitrator chosen for the question (regardless of whether they are asked to arbitrate)\n /// @param min_timeout The timeout set in the initial question settings must be this high or higher\n /// @param min_bond The bond sent with the final answer must be this high or higher\n /// @return The answer formatted as a bytes32\n function getFinalAnswerIfMatches(\n bytes32 question_id, \n bytes32 content_hash, address arbitrator, uint32 min_timeout, uint256 min_bond\n ) \n stateFinalized(question_id)\n external view returns (bytes32) {\n require(content_hash == questions[question_id].content_hash, \"content hash must match\");\n require(arbitrator == questions[question_id].arbitrator, \"arbitrator must match\");\n require(min_timeout <= questions[question_id].timeout, \"timeout must be long enough\");\n require(min_bond <= questions[question_id].bond, \"bond must be high enough\");\n return questions[question_id].best_answer;\n }\n\n /// @notice Assigns the winnings (bounty and bonds) to everyone who gave the accepted answer\n /// Caller must provide the answer history, in reverse order\n /// @dev Works up the chain and assign bonds to the person who gave the right answer\n /// If someone gave the winning answer earlier, they must get paid from the higher bond\n /// That means we can't pay out the bond added at n until we have looked at n-1\n /// The first answer is authenticated by checking against the stored history_hash.\n /// One of the inputs to history_hash is the history_hash before it, so we use that to authenticate the next entry, etc\n /// Once we get to a null hash we'll know we're done and there are no more answers.\n /// Usually you would call the whole thing in a single transaction, but if not then the data is persisted to pick up later.\n /// @param question_id The ID of the question\n /// @param history_hashes Second-last-to-first, the hash of each history entry. (Final one should be empty).\n /// @param addrs Last-to-first, the address of each answerer or commitment sender\n /// @param bonds Last-to-first, the bond supplied with each answer or commitment\n /// @param answers Last-to-first, each answer supplied, or commitment ID if the answer was supplied with commit->reveal\n function claimWinnings(\n bytes32 question_id, \n bytes32[] history_hashes, address[] addrs, uint256[] bonds, bytes32[] answers\n ) \n stateFinalized(question_id)\n public {\n\n require(history_hashes.length > 0, \"at least one history hash entry must be provided\");\n\n // These are only set if we split our claim over multiple transactions.\n address payee = question_claims[question_id].payee; \n uint256 last_bond = question_claims[question_id].last_bond; \n uint256 queued_funds = question_claims[question_id].queued_funds; \n\n // Starts as the hash of the final answer submitted. It'll be cleared when we're done.\n // If we're splitting the claim over multiple transactions, it'll be the hash where we left off last time\n bytes32 last_history_hash = questions[question_id].history_hash;\n\n bytes32 best_answer = questions[question_id].best_answer;\n\n uint256 i;\n for (i = 0; i < history_hashes.length; i++) {\n \n // Check input against the history hash, and see which of 2 possible values of is_commitment fits.\n bool is_commitment = _verifyHistoryInputOrRevert(last_history_hash, history_hashes[i], answers[i], bonds[i], addrs[i]);\n \n queued_funds = queued_funds.add(last_bond); \n (queued_funds, payee) = _processHistoryItem(\n question_id, best_answer, queued_funds, payee, \n addrs[i], bonds[i], answers[i], is_commitment);\n \n // Line the bond up for next time, when it will be added to somebody's queued_funds\n last_bond = bonds[i];\n\n // Burn (just leave in contract balance) a fraction of all bonds except the final one.\n // This creates a cost to increasing your own bond, which could be used to delay resolution maliciously\n if (last_bond != questions[question_id].bond) {\n last_bond = last_bond.sub(last_bond / BOND_CLAIM_FEE_PROPORTION);\n }\n\n last_history_hash = history_hashes[i];\n\n }\n \n if (last_history_hash != NULL_HASH) {\n // We haven't yet got to the null hash (1st answer), ie the caller didn't supply the full answer chain.\n // Persist the details so we can pick up later where we left off later.\n\n // If we know who to pay we can go ahead and pay them out, only keeping back last_bond\n // (We always know who to pay unless all we saw were unrevealed commits)\n if (payee != NULL_ADDRESS) {\n _payPayee(question_id, payee, queued_funds);\n queued_funds = 0;\n }\n\n question_claims[question_id].payee = payee;\n question_claims[question_id].last_bond = last_bond;\n question_claims[question_id].queued_funds = queued_funds;\n } else {\n // There is nothing left below us so the payee can keep what remains\n _payPayee(question_id, payee, queued_funds.add(last_bond));\n delete question_claims[question_id];\n }\n\n questions[question_id].history_hash = last_history_hash;\n\n }\n\n function _payPayee(bytes32 question_id, address payee, uint256 value) \n internal {\n balanceOf[payee] = balanceOf[payee].add(value);\n emit LogClaim(question_id, payee, value);\n }\n\n function _verifyHistoryInputOrRevert(\n bytes32 last_history_hash,\n bytes32 history_hash, bytes32 answer, uint256 bond, address addr\n )\n internal pure returns (bool) {\n if (last_history_hash == keccak256(abi.encodePacked(history_hash, answer, bond, addr, true)) ) {\n return true;\n }\n if (last_history_hash == keccak256(abi.encodePacked(history_hash, answer, bond, addr, false)) ) {\n return false;\n } \n revert(\"History input provided did not match the expected hash\");\n }\n\n function _processHistoryItem(\n bytes32 question_id, bytes32 best_answer, \n uint256 queued_funds, address payee, \n address addr, uint256 bond, bytes32 answer, bool is_commitment\n )\n internal returns (uint256, address) {\n\n // For commit-and-reveal, the answer history holds the commitment ID instead of the answer.\n // We look at the referenced commitment ID and switch in the actual answer.\n if (is_commitment) {\n bytes32 commitment_id = answer;\n // If it's a commit but it hasn't been revealed, it will always be considered wrong.\n if (!commitments[commitment_id].is_revealed) {\n delete commitments[commitment_id];\n return (queued_funds, payee);\n } else {\n answer = commitments[commitment_id].revealed_answer;\n delete commitments[commitment_id];\n }\n }\n\n if (answer == best_answer) {\n\n if (payee == NULL_ADDRESS) {\n\n // The entry is for the first payee we come to, ie the winner.\n // They get the question bounty.\n payee = addr;\n queued_funds = queued_funds.add(questions[question_id].bounty);\n questions[question_id].bounty = 0;\n\n } else if (addr != payee) {\n\n // Answerer has changed, ie we found someone lower down who needs to be paid\n\n // The lower answerer will take over receiving bonds from higher answerer.\n // They should also be paid the takeover fee, which is set at a rate equivalent to their bond. \n // (This is our arbitrary rule, to give consistent right-answerers a defence against high-rollers.)\n\n // There should be enough for the fee, but if not, take what we have.\n // There's an edge case involving weird arbitrator behaviour where we may be short.\n uint256 answer_takeover_fee = (queued_funds >= bond) ? bond : queued_funds;\n // Settle up with the old (higher-bonded) payee\n _payPayee(question_id, payee, queued_funds.sub(answer_takeover_fee));\n\n // Now start queued_funds again for the new (lower-bonded) payee\n payee = addr;\n queued_funds = answer_takeover_fee;\n\n }\n\n }\n\n return (queued_funds, payee);\n\n }\n\n /// @notice Convenience function to assign bounties/bonds for multiple questions in one go, then withdraw all your funds.\n /// Caller must provide the answer history for each question, in reverse order\n /// @dev Can be called by anyone to assign bonds/bounties, but funds are only withdrawn for the user making the call.\n /// @param question_ids The IDs of the questions you want to claim for\n /// @param lengths The number of history entries you will supply for each question ID\n /// @param hist_hashes In a single list for all supplied questions, the hash of each history entry.\n /// @param addrs In a single list for all supplied questions, the address of each answerer or commitment sender\n /// @param bonds In a single list for all supplied questions, the bond supplied with each answer or commitment\n /// @param answers In a single list for all supplied questions, each answer supplied, or commitment ID \n function claimMultipleAndWithdrawBalance(\n bytes32[] question_ids, uint256[] lengths, \n bytes32[] hist_hashes, address[] addrs, uint256[] bonds, bytes32[] answers\n ) \n stateAny() // The finalization checks are done in the claimWinnings function\n public {\n \n uint256 qi;\n uint256 i;\n for (qi = 0; qi < question_ids.length; qi++) {\n bytes32 qid = question_ids[qi];\n uint256 ln = lengths[qi];\n bytes32[] memory hh = new bytes32[](ln);\n address[] memory ad = new address[](ln);\n uint256[] memory bo = new uint256[](ln);\n bytes32[] memory an = new bytes32[](ln);\n uint256 j;\n for (j = 0; j < ln; j++) {\n hh[j] = hist_hashes[i];\n ad[j] = addrs[i];\n bo[j] = bonds[i];\n an[j] = answers[i];\n i++;\n }\n claimWinnings(qid, hh, ad, bo, an);\n }\n withdraw();\n }\n\n /// @notice Returns the questions's content hash, identifying the question content\n /// @param question_id The ID of the question \n function getContentHash(bytes32 question_id) \n public view returns(bytes32) {\n return questions[question_id].content_hash;\n }\n\n /// @notice Returns the arbitrator address for the question\n /// @param question_id The ID of the question \n function getArbitrator(bytes32 question_id) \n public view returns(address) {\n return questions[question_id].arbitrator;\n }\n\n /// @notice Returns the timestamp when the question can first be answered\n /// @param question_id The ID of the question \n function getOpeningTS(bytes32 question_id) \n public view returns(uint32) {\n return questions[question_id].opening_ts;\n }\n\n /// @notice Returns the timeout in seconds used after each answer\n /// @param question_id The ID of the question \n function getTimeout(bytes32 question_id) \n public view returns(uint32) {\n return questions[question_id].timeout;\n }\n\n /// @notice Returns the timestamp at which the question will be/was finalized\n /// @param question_id The ID of the question \n function getFinalizeTS(bytes32 question_id) \n public view returns(uint32) {\n return questions[question_id].finalize_ts;\n }\n\n /// @notice Returns whether the question is pending arbitration\n /// @param question_id The ID of the question \n function isPendingArbitration(bytes32 question_id) \n public view returns(bool) {\n return questions[question_id].is_pending_arbitration;\n }\n\n /// @notice Returns the current total unclaimed bounty\n /// @dev Set back to zero once the bounty has been claimed\n /// @param question_id The ID of the question \n function getBounty(bytes32 question_id) \n public view returns(uint256) {\n return questions[question_id].bounty;\n }\n\n /// @notice Returns the current best answer\n /// @param question_id The ID of the question \n function getBestAnswer(bytes32 question_id) \n public view returns(bytes32) {\n return questions[question_id].best_answer;\n }\n\n /// @notice Returns the history hash of the question \n /// @param question_id The ID of the question \n /// @dev Updated on each answer, then rewound as each is claimed\n function getHistoryHash(bytes32 question_id) \n public view returns(bytes32) {\n return questions[question_id].history_hash;\n }\n\n /// @notice Returns the highest bond posted so far for a question\n /// @param question_id The ID of the question \n function getBond(bytes32 question_id) \n public view returns(uint256) {\n return questions[question_id].bond;\n }\n\n}\n", + "sourcePath": "/home/ed/working/realitio-contracts/truffle/contracts/Realitio_v2_1.sol", + "ast": { + "absolutePath": "/home/ed/working/realitio-contracts/truffle/contracts/Realitio_v2_1.sol", + "exportedSymbols": { + "Realitio_v2_1": [ + 9314 + ] + }, + "id": 9315, + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 7110, + "literals": [ + "solidity", + "^", + "0.4", + ".25" + ], + "nodeType": "PragmaDirective", + "src": "0:24:18" + }, + { + "absolutePath": "/home/ed/working/realitio-contracts/truffle/contracts/RealitioSafeMath256.sol", + "file": "./RealitioSafeMath256.sol", + "id": 7111, + "nodeType": "ImportDirective", + "scope": 9315, + "sourceUnit": 7082, + "src": "26:35:18", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/home/ed/working/realitio-contracts/truffle/contracts/RealitioSafeMath32.sol", + "file": "./RealitioSafeMath32.sol", + "id": 7112, + "nodeType": "ImportDirective", + "scope": 9315, + "sourceUnit": 7109, + "src": "62:34:18", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/home/ed/working/realitio-contracts/truffle/contracts/BalanceHolder.sol", + "file": "./BalanceHolder.sol", + "id": 7113, + "nodeType": "ImportDirective", + "scope": 9315, + "sourceUnit": 436, + "src": "97:29:18", + "symbolAliases": [], + "unitAlias": "" + }, + { + "baseContracts": [ + { + "arguments": null, + "baseName": { + "contractScope": null, + "id": 7114, + "name": "BalanceHolder", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 435, + "src": "332:13:18", + "typeDescriptions": { + "typeIdentifier": "t_contract$_BalanceHolder_$435", + "typeString": "contract BalanceHolder" + } + }, + "id": 7115, + "nodeType": "InheritanceSpecifier", + "src": "332:13:18" + } + ], + "contractDependencies": [ + 435 + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 9314, + "linearizedBaseContracts": [ + 9314, + 435 + ], + "name": "Realitio_v2_1", + "nodeType": "ContractDefinition", + "nodes": [ + { + "id": 7118, + "libraryName": { + "contractScope": null, + "id": 7116, + "name": "RealitioSafeMath256", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 7081, + "src": "359:19:18", + "typeDescriptions": { + "typeIdentifier": "t_contract$_RealitioSafeMath256_$7081", + "typeString": "library RealitioSafeMath256" + } + }, + "nodeType": "UsingForDirective", + "src": "353:38:18", + "typeName": { + "id": 7117, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "383:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + }, + { + "id": 7121, + "libraryName": { + "contractScope": null, + "id": 7119, + "name": "RealitioSafeMath32", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 7108, + "src": "402:18:18", + "typeDescriptions": { + "typeIdentifier": "t_contract$_RealitioSafeMath32_$7108", + "typeString": "library RealitioSafeMath32" + } + }, + "nodeType": "UsingForDirective", + "src": "396:36:18", + "typeName": { + "id": 7120, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "425:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + } + }, + { + "constant": true, + "id": 7126, + "name": "NULL_ADDRESS", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "438:42:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7122, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "438:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 7124, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "478:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 7123, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "470:7:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 7125, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "470:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": true, + "id": 7131, + "name": "NULL_HASH", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "563:39:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7127, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "563:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 7129, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "600:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 7128, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "592:7:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": "bytes32" + }, + "id": 7130, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "592:10:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": true, + "id": 7134, + "name": "UNANSWERED", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "697:30:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7132, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "697:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "30", + "id": 7133, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "726:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "visibility": "internal" + }, + { + "constant": true, + "id": 7137, + "name": "COMMITMENT_NON_EXISTENT", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "820:44:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7135, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "820:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "30", + "id": 7136, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "863:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "visibility": "internal" + }, + { + "constant": true, + "id": 7140, + "name": "COMMITMENT_TIMEOUT_RATIO", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "948:44:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7138, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "948:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "38", + "id": 7139, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "991:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_8_by_1", + "typeString": "int_const 8" + }, + "value": "8" + }, + "visibility": "internal" + }, + { + "constant": true, + "id": 7143, + "name": "BOND_CLAIM_FEE_PROPORTION", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "1058:47:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7141, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1058:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "3430", + "id": 7142, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1103:2:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_40_by_1", + "typeString": "int_const 40" + }, + "value": "40" + }, + "visibility": "internal" + }, + { + "anonymous": false, + "documentation": null, + "id": 7149, + "name": "LogSetQuestionFee", + "nodeType": "EventDefinition", + "parameters": { + "id": 7148, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7145, + "indexed": false, + "name": "arbitrator", + "nodeType": "VariableDeclaration", + "scope": 7149, + "src": "1165:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7144, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1165:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7147, + "indexed": false, + "name": "amount", + "nodeType": "VariableDeclaration", + "scope": 7149, + "src": "1193:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7146, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1193:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "1155:58:18" + }, + "src": "1132:82:18" + }, + { + "anonymous": false, + "documentation": null, + "id": 7157, + "name": "LogNewTemplate", + "nodeType": "EventDefinition", + "parameters": { + "id": 7156, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7151, + "indexed": true, + "name": "template_id", + "nodeType": "VariableDeclaration", + "scope": 7157, + "src": "1250:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7150, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1250:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7153, + "indexed": true, + "name": "user", + "nodeType": "VariableDeclaration", + "scope": 7157, + "src": "1287:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7152, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1287:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7155, + "indexed": false, + "name": "question_text", + "nodeType": "VariableDeclaration", + "scope": 7157, + "src": "1318:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 7154, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "1318:6:18", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "1240:104:18" + }, + "src": "1220:125:18" + }, + { + "anonymous": false, + "documentation": null, + "id": 7179, + "name": "LogNewQuestion", + "nodeType": "EventDefinition", + "parameters": { + "id": 7178, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7159, + "indexed": true, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7179, + "src": "1381:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7158, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1381:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7161, + "indexed": true, + "name": "user", + "nodeType": "VariableDeclaration", + "scope": 7179, + "src": "1418:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7160, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1418:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7163, + "indexed": false, + "name": "template_id", + "nodeType": "VariableDeclaration", + "scope": 7179, + "src": "1449:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7162, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1449:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7165, + "indexed": false, + "name": "question", + "nodeType": "VariableDeclaration", + "scope": 7179, + "src": "1478:15:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 7164, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "1478:6:18", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7167, + "indexed": true, + "name": "content_hash", + "nodeType": "VariableDeclaration", + "scope": 7179, + "src": "1503:28:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7166, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1503:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7169, + "indexed": false, + "name": "arbitrator", + "nodeType": "VariableDeclaration", + "scope": 7179, + "src": "1541:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7168, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1541:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7171, + "indexed": false, + "name": "timeout", + "nodeType": "VariableDeclaration", + "scope": 7179, + "src": "1570:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7170, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "1570:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7173, + "indexed": false, + "name": "opening_ts", + "nodeType": "VariableDeclaration", + "scope": 7179, + "src": "1594:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7172, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "1594:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7175, + "indexed": false, + "name": "nonce", + "nodeType": "VariableDeclaration", + "scope": 7179, + "src": "1621:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7174, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1621:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7177, + "indexed": false, + "name": "created", + "nodeType": "VariableDeclaration", + "scope": 7179, + "src": "1644:15:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7176, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1644:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "1371:294:18" + }, + "src": "1351:315:18" + }, + { + "anonymous": false, + "documentation": null, + "id": 7189, + "name": "LogFundAnswerBounty", + "nodeType": "EventDefinition", + "parameters": { + "id": 7188, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7181, + "indexed": true, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7189, + "src": "1707:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7180, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1707:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7183, + "indexed": false, + "name": "bounty_added", + "nodeType": "VariableDeclaration", + "scope": 7189, + "src": "1744:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7182, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1744:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7185, + "indexed": false, + "name": "bounty", + "nodeType": "VariableDeclaration", + "scope": 7189, + "src": "1774:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7184, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1774:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7187, + "indexed": true, + "name": "user", + "nodeType": "VariableDeclaration", + "scope": 7189, + "src": "1798:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7186, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1798:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "1697:128:18" + }, + "src": "1672:154:18" + }, + { + "anonymous": false, + "documentation": null, + "id": 7205, + "name": "LogNewAnswer", + "nodeType": "EventDefinition", + "parameters": { + "id": 7204, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7191, + "indexed": false, + "name": "answer", + "nodeType": "VariableDeclaration", + "scope": 7205, + "src": "1860:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7190, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1860:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7193, + "indexed": true, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7205, + "src": "1884:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7192, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1884:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7195, + "indexed": false, + "name": "history_hash", + "nodeType": "VariableDeclaration", + "scope": 7205, + "src": "1921:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7194, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1921:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7197, + "indexed": true, + "name": "user", + "nodeType": "VariableDeclaration", + "scope": 7205, + "src": "1951:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7196, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1951:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7199, + "indexed": false, + "name": "bond", + "nodeType": "VariableDeclaration", + "scope": 7205, + "src": "1981:12:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7198, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1981:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7201, + "indexed": false, + "name": "ts", + "nodeType": "VariableDeclaration", + "scope": 7205, + "src": "2003:10:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7200, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2003:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7203, + "indexed": false, + "name": "is_commitment", + "nodeType": "VariableDeclaration", + "scope": 7205, + "src": "2023:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 7202, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2023:4:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "1850:197:18" + }, + "src": "1832:216:18" + }, + { + "anonymous": false, + "documentation": null, + "id": 7219, + "name": "LogAnswerReveal", + "nodeType": "EventDefinition", + "parameters": { + "id": 7218, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7207, + "indexed": true, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7219, + "src": "2085:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7206, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2085:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7209, + "indexed": true, + "name": "user", + "nodeType": "VariableDeclaration", + "scope": 7219, + "src": "2123:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7208, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2123:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7211, + "indexed": true, + "name": "answer_hash", + "nodeType": "VariableDeclaration", + "scope": 7219, + "src": "2154:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7210, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2154:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7213, + "indexed": false, + "name": "answer", + "nodeType": "VariableDeclaration", + "scope": 7219, + "src": "2192:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7212, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2192:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7215, + "indexed": false, + "name": "nonce", + "nodeType": "VariableDeclaration", + "scope": 7219, + "src": "2217:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7214, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2217:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7217, + "indexed": false, + "name": "bond", + "nodeType": "VariableDeclaration", + "scope": 7219, + "src": "2241:12:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7216, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2241:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2075:184:18" + }, + "src": "2054:206:18" + }, + { + "anonymous": false, + "documentation": null, + "id": 7225, + "name": "LogNotifyOfArbitrationRequest", + "nodeType": "EventDefinition", + "parameters": { + "id": 7224, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7221, + "indexed": true, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7225, + "src": "2311:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7220, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2311:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7223, + "indexed": true, + "name": "user", + "nodeType": "VariableDeclaration", + "scope": 7225, + "src": "2348:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7222, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2348:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2301:74:18" + }, + "src": "2266:110:18" + }, + { + "anonymous": false, + "documentation": null, + "id": 7229, + "name": "LogCancelArbitration", + "nodeType": "EventDefinition", + "parameters": { + "id": 7228, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7227, + "indexed": true, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7229, + "src": "2418:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7226, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2418:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2408:43:18" + }, + "src": "2382:70:18" + }, + { + "anonymous": false, + "documentation": null, + "id": 7235, + "name": "LogFinalize", + "nodeType": "EventDefinition", + "parameters": { + "id": 7234, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7231, + "indexed": true, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7235, + "src": "2485:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7230, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2485:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7233, + "indexed": true, + "name": "answer", + "nodeType": "VariableDeclaration", + "scope": 7235, + "src": "2522:22:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7232, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2522:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2475:75:18" + }, + "src": "2458:93:18" + }, + { + "anonymous": false, + "documentation": null, + "id": 7243, + "name": "LogClaim", + "nodeType": "EventDefinition", + "parameters": { + "id": 7242, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7237, + "indexed": true, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7243, + "src": "2581:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7236, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2581:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7239, + "indexed": true, + "name": "user", + "nodeType": "VariableDeclaration", + "scope": 7243, + "src": "2618:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7238, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2618:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7241, + "indexed": false, + "name": "amount", + "nodeType": "VariableDeclaration", + "scope": 7243, + "src": "2648:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7240, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2648:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2571:97:18" + }, + "src": "2557:112:18" + }, + { + "canonicalName": "Realitio_v2_1.Question", + "id": 7264, + "members": [ + { + "constant": false, + "id": 7245, + "name": "content_hash", + "nodeType": "VariableDeclaration", + "scope": 7264, + "src": "2701:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7244, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2701:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7247, + "name": "arbitrator", + "nodeType": "VariableDeclaration", + "scope": 7264, + "src": "2731:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7246, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2731:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7249, + "name": "opening_ts", + "nodeType": "VariableDeclaration", + "scope": 7264, + "src": "2759:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7248, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "2759:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7251, + "name": "timeout", + "nodeType": "VariableDeclaration", + "scope": 7264, + "src": "2786:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7250, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "2786:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7253, + "name": "finalize_ts", + "nodeType": "VariableDeclaration", + "scope": 7264, + "src": "2810:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7252, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "2810:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7255, + "name": "is_pending_arbitration", + "nodeType": "VariableDeclaration", + "scope": 7264, + "src": "2838:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 7254, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2838:4:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7257, + "name": "bounty", + "nodeType": "VariableDeclaration", + "scope": 7264, + "src": "2875:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7256, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2875:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7259, + "name": "best_answer", + "nodeType": "VariableDeclaration", + "scope": 7264, + "src": "2899:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7258, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2899:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7261, + "name": "history_hash", + "nodeType": "VariableDeclaration", + "scope": 7264, + "src": "2928:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7260, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2928:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7263, + "name": "bond", + "nodeType": "VariableDeclaration", + "scope": 7264, + "src": "2958:12:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7262, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2958:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "name": "Question", + "nodeType": "StructDefinition", + "scope": 9314, + "src": "2675:302:18", + "visibility": "public" + }, + { + "canonicalName": "Realitio_v2_1.Commitment", + "id": 7271, + "members": [ + { + "constant": false, + "id": 7266, + "name": "reveal_ts", + "nodeType": "VariableDeclaration", + "scope": 7271, + "src": "3108:16:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7265, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "3108:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7268, + "name": "is_revealed", + "nodeType": "VariableDeclaration", + "scope": 7271, + "src": "3134:16:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 7267, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "3134:4:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7270, + "name": "revealed_answer", + "nodeType": "VariableDeclaration", + "scope": 7271, + "src": "3160:23:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7269, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3160:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "name": "Commitment", + "nodeType": "StructDefinition", + "scope": 9314, + "src": "3080:110:18", + "visibility": "public" + }, + { + "canonicalName": "Realitio_v2_1.Claim", + "id": 7278, + "members": [ + { + "constant": false, + "id": 7273, + "name": "payee", + "nodeType": "VariableDeclaration", + "scope": 7278, + "src": "3341:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7272, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3341:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7275, + "name": "last_bond", + "nodeType": "VariableDeclaration", + "scope": 7278, + "src": "3364:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7274, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3364:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7277, + "name": "queued_funds", + "nodeType": "VariableDeclaration", + "scope": 7278, + "src": "3391:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7276, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3391:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "name": "Claim", + "nodeType": "StructDefinition", + "scope": 9314, + "src": "3318:100:18", + "visibility": "public" + }, + { + "constant": false, + "id": 7281, + "name": "nextTemplateID", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "3424:26:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7279, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3424:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "30", + "id": 7280, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3449:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 7285, + "name": "templates", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "3456:44:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint256_$_t_uint256_$", + "typeString": "mapping(uint256 => uint256)" + }, + "typeName": { + "id": 7284, + "keyType": { + "id": 7282, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3464:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Mapping", + "src": "3456:27:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint256_$_t_uint256_$", + "typeString": "mapping(uint256 => uint256)" + }, + "valueType": { + "id": 7283, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3475:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": false, + "id": 7289, + "name": "template_hashes", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "3506:50:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint256_$_t_bytes32_$", + "typeString": "mapping(uint256 => bytes32)" + }, + "typeName": { + "id": 7288, + "keyType": { + "id": 7286, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3514:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Mapping", + "src": "3506:27:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint256_$_t_bytes32_$", + "typeString": "mapping(uint256 => bytes32)" + }, + "valueType": { + "id": 7287, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3525:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": false, + "id": 7293, + "name": "questions", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "3562:45:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question)" + }, + "typeName": { + "id": 7292, + "keyType": { + "id": 7290, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3570:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Mapping", + "src": "3562:28:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question)" + }, + "valueType": { + "contractScope": null, + "id": 7291, + "name": "Question", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 7264, + "src": "3581:8:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage_ptr", + "typeString": "struct Realitio_v2_1.Question" + } + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": false, + "id": 7297, + "name": "question_claims", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "3613:48:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Claim_$7278_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Claim)" + }, + "typeName": { + "id": 7296, + "keyType": { + "id": 7294, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3621:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Mapping", + "src": "3613:25:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Claim_$7278_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Claim)" + }, + "valueType": { + "contractScope": null, + "id": 7295, + "name": "Claim", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 7278, + "src": "3632:5:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Claim_$7278_storage_ptr", + "typeString": "struct Realitio_v2_1.Claim" + } + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": false, + "id": 7301, + "name": "commitments", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "3667:49:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment)" + }, + "typeName": { + "id": 7300, + "keyType": { + "id": 7298, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3675:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Mapping", + "src": "3667:30:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment)" + }, + "valueType": { + "contractScope": null, + "id": 7299, + "name": "Commitment", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 7271, + "src": "3686:10:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage_ptr", + "typeString": "struct Realitio_v2_1.Commitment" + } + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": false, + "id": 7305, + "name": "arbitrator_question_fees", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "3722:59:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + }, + "typeName": { + "id": 7304, + "keyType": { + "id": 7302, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3730:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Mapping", + "src": "3722:27:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + }, + "valueType": { + "id": 7303, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3741:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + }, + "value": null, + "visibility": "public" + }, + { + "body": { + "id": 7321, + "nodeType": "Block", + "src": "3834:117:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 7316, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7310, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "3852:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7311, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "3852:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7312, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "3866:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7314, + "indexExpression": { + "argumentTypes": null, + "id": 7313, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7307, + "src": "3876:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "3866:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7315, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "arbitrator", + "nodeType": "MemberAccess", + "referencedDeclaration": 7247, + "src": "3866:33:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "3852:47:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "6d73672e73656e646572206d7573742062652061726269747261746f72", + "id": 7317, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3901:31:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_5af564fa249397c704c7c39694db25de233707a7dfa60dd4e063a5865f683bf0", + "typeString": "literal_string \"msg.sender must be arbitrator\"" + }, + "value": "msg.sender must be arbitrator" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_5af564fa249397c704c7c39694db25de233707a7dfa60dd4e063a5865f683bf0", + "typeString": "literal_string \"msg.sender must be arbitrator\"" + } + ], + "id": 7309, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "3844:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7318, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3844:89:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7319, + "nodeType": "ExpressionStatement", + "src": "3844:89:18" + }, + { + "id": 7320, + "nodeType": "PlaceholderStatement", + "src": "3943:1:18" + } + ] + }, + "documentation": null, + "id": 7322, + "name": "onlyArbitrator", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 7308, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7307, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7322, + "src": "3813:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7306, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3813:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "3812:21:18" + }, + "src": "3789:162:18", + "visibility": "internal" + }, + { + "body": { + "id": 7325, + "nodeType": "Block", + "src": "3977:18:18", + "statements": [ + { + "id": 7324, + "nodeType": "PlaceholderStatement", + "src": "3987:1:18" + } + ] + }, + "documentation": null, + "id": 7326, + "name": "stateAny", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 7323, + "nodeType": "ParameterList", + "parameters": [], + "src": "3974:2:18" + }, + "src": "3957:38:18", + "visibility": "internal" + }, + { + "body": { + "id": 7341, + "nodeType": "Block", + "src": "4047:99:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7336, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7331, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "4065:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7333, + "indexExpression": { + "argumentTypes": null, + "id": 7332, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7328, + "src": "4075:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "4065:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7334, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timeout", + "nodeType": "MemberAccess", + "referencedDeclaration": 7251, + "src": "4065:30:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 7335, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4099:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "4065:35:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "7175657374696f6e206d757374206e6f74206578697374", + "id": 7337, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4102:25:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_9422abd8923f5fcae9417fb15deac6177aedec6abb4620f33db030efb4ed0419", + "typeString": "literal_string \"question must not exist\"" + }, + "value": "question must not exist" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_9422abd8923f5fcae9417fb15deac6177aedec6abb4620f33db030efb4ed0419", + "typeString": "literal_string \"question must not exist\"" + } + ], + "id": 7330, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "4057:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7338, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4057:71:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7339, + "nodeType": "ExpressionStatement", + "src": "4057:71:18" + }, + { + "id": 7340, + "nodeType": "PlaceholderStatement", + "src": "4138:1:18" + } + ] + }, + "documentation": null, + "id": 7342, + "name": "stateNotCreated", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 7329, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7328, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7342, + "src": "4026:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7327, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "4026:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "4025:21:18" + }, + "src": "4001:145:18", + "visibility": "internal" + }, + { + "body": { + "id": 7406, + "nodeType": "Block", + "src": "4192:547:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7352, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7347, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "4210:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7349, + "indexExpression": { + "argumentTypes": null, + "id": 7348, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7344, + "src": "4220:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "4210:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7350, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timeout", + "nodeType": "MemberAccess", + "referencedDeclaration": 7251, + "src": "4210:30:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 7351, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4243:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "4210:34:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "7175657374696f6e206d757374206578697374", + "id": 7353, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4246:21:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_472769862e940c55535785d7e47562583d0c118be9a62024347d29ed8338806b", + "typeString": "literal_string \"question must exist\"" + }, + "value": "question must exist" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_472769862e940c55535785d7e47562583d0c118be9a62024347d29ed8338806b", + "typeString": "literal_string \"question must exist\"" + } + ], + "id": 7346, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "4202:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7354, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4202:66:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7355, + "nodeType": "ExpressionStatement", + "src": "4202:66:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7361, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "4286:46:18", + "subExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7357, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "4287:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7359, + "indexExpression": { + "argumentTypes": null, + "id": 7358, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7344, + "src": "4297:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "4287:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7360, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "is_pending_arbitration", + "nodeType": "MemberAccess", + "referencedDeclaration": 7255, + "src": "4287:45:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "7175657374696f6e206d757374206e6f742062652070656e64696e67206172626974726174696f6e", + "id": 7362, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4334:42:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_e0d7c56d5455922671038afc010672319828847765f75d021ca63b233340fb79", + "typeString": "literal_string \"question must not be pending arbitration\"" + }, + "value": "question must not be pending arbitration" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_e0d7c56d5455922671038afc010672319828847765f75d021ca63b233340fb79", + "typeString": "literal_string \"question must not be pending arbitration\"" + } + ], + "id": 7356, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "4278:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7363, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4278:99:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7364, + "nodeType": "ExpressionStatement", + "src": "4278:99:18" + }, + { + "assignments": [ + 7366 + ], + "declarations": [ + { + "constant": false, + "id": 7366, + "name": "finalize_ts", + "nodeType": "VariableDeclaration", + "scope": 7407, + "src": "4387:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7365, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "4387:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 7371, + "initialValue": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7367, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "4408:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7369, + "indexExpression": { + "argumentTypes": null, + "id": 7368, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7344, + "src": "4418:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "4408:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7370, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "finalize_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7253, + "src": "4408:34:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "4387:55:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 7381, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7375, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7373, + "name": "finalize_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7366, + "src": "4460:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 7374, + "name": "UNANSWERED", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7134, + "src": "4475:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "4460:25:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "||", + "rightExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7380, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7376, + "name": "finalize_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7366, + "src": "4489:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7378, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "4510:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 7377, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "4503:6:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint32_$", + "typeString": "type(uint32)" + }, + "typeName": "uint32" + }, + "id": 7379, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4503:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "4489:25:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "4460:54:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "66696e616c697a6174696f6e20646561646c696e65206d757374206e6f74206861766520706173736564", + "id": 7382, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4516:44:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_381ca4d13deaf278dc64e461f023657740bec9f7b7a71cf63c10807ee5f2d777", + "typeString": "literal_string \"finalization deadline must not have passed\"" + }, + "value": "finalization deadline must not have passed" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_381ca4d13deaf278dc64e461f023657740bec9f7b7a71cf63c10807ee5f2d777", + "typeString": "literal_string \"finalization deadline must not have passed\"" + } + ], + "id": 7372, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "4452:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7383, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4452:109:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7384, + "nodeType": "ExpressionStatement", + "src": "4452:109:18" + }, + { + "assignments": [ + 7386 + ], + "declarations": [ + { + "constant": false, + "id": 7386, + "name": "opening_ts", + "nodeType": "VariableDeclaration", + "scope": 7407, + "src": "4571:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7385, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "4571:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 7391, + "initialValue": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7387, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "4591:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7389, + "indexExpression": { + "argumentTypes": null, + "id": 7388, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7344, + "src": "4601:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "4591:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7390, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "opening_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7249, + "src": "4591:33:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "4571:53:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 7401, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7395, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7393, + "name": "opening_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7386, + "src": "4642:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 7394, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4656:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "4642:15:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "||", + "rightExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7400, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7396, + "name": "opening_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7386, + "src": "4661:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7398, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "4682:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 7397, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "4675:6:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint32_$", + "typeString": "type(uint32)" + }, + "typeName": "uint32" + }, + "id": 7399, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4675:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "4661:25:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "4642:44:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "6f70656e696e672064617465206d757374206861766520706173736564", + "id": 7402, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4688:31:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_5963fbf852ce76142d772c6ce4c8614e81ba76b348890013b4cd0addd58b31b3", + "typeString": "literal_string \"opening date must have passed\"" + }, + "value": "opening date must have passed" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_5963fbf852ce76142d772c6ce4c8614e81ba76b348890013b4cd0addd58b31b3", + "typeString": "literal_string \"opening date must have passed\"" + } + ], + "id": 7392, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "4634:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7403, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4634:86:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7404, + "nodeType": "ExpressionStatement", + "src": "4634:86:18" + }, + { + "id": 7405, + "nodeType": "PlaceholderStatement", + "src": "4731:1:18" + } + ] + }, + "documentation": null, + "id": 7407, + "name": "stateOpen", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 7345, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7344, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7407, + "src": "4171:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7343, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "4171:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "4170:21:18" + }, + "src": "4152:587:18", + "visibility": "internal" + }, + { + "body": { + "id": 7420, + "nodeType": "Block", + "src": "4799:122:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7412, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "4817:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7414, + "indexExpression": { + "argumentTypes": null, + "id": 7413, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7409, + "src": "4827:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "4817:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7415, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "is_pending_arbitration", + "nodeType": "MemberAccess", + "referencedDeclaration": 7255, + "src": "4817:45:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "7175657374696f6e206d7573742062652070656e64696e67206172626974726174696f6e", + "id": 7416, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4864:38:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_4f7d8d6d43d9c6b0643db0ab03bfd160dd192eaa68b6c3b38d0d94803ffac248", + "typeString": "literal_string \"question must be pending arbitration\"" + }, + "value": "question must be pending arbitration" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_4f7d8d6d43d9c6b0643db0ab03bfd160dd192eaa68b6c3b38d0d94803ffac248", + "typeString": "literal_string \"question must be pending arbitration\"" + } + ], + "id": 7411, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "4809:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7417, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4809:94:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7418, + "nodeType": "ExpressionStatement", + "src": "4809:94:18" + }, + { + "id": 7419, + "nodeType": "PlaceholderStatement", + "src": "4913:1:18" + } + ] + }, + "documentation": null, + "id": 7421, + "name": "statePendingArbitration", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 7410, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7409, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7421, + "src": "4778:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7408, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "4778:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "4777:21:18" + }, + "src": "4745:176:18", + "visibility": "internal" + }, + { + "body": { + "id": 7476, + "nodeType": "Block", + "src": "4987:437:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7431, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7426, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "5005:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7428, + "indexExpression": { + "argumentTypes": null, + "id": 7427, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7423, + "src": "5015:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "5005:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7429, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timeout", + "nodeType": "MemberAccess", + "referencedDeclaration": 7251, + "src": "5005:30:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 7430, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5038:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "5005:34:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "7175657374696f6e206d757374206578697374", + "id": 7432, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5041:21:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_472769862e940c55535785d7e47562583d0c118be9a62024347d29ed8338806b", + "typeString": "literal_string \"question must exist\"" + }, + "value": "question must exist" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_472769862e940c55535785d7e47562583d0c118be9a62024347d29ed8338806b", + "typeString": "literal_string \"question must exist\"" + } + ], + "id": 7425, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "4997:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7433, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4997:66:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7434, + "nodeType": "ExpressionStatement", + "src": "4997:66:18" + }, + { + "assignments": [ + 7436 + ], + "declarations": [ + { + "constant": false, + "id": 7436, + "name": "finalize_ts", + "nodeType": "VariableDeclaration", + "scope": 7477, + "src": "5073:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7435, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "5073:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 7441, + "initialValue": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7437, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "5094:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7439, + "indexExpression": { + "argumentTypes": null, + "id": 7438, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7423, + "src": "5104:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "5094:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7440, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "finalize_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7253, + "src": "5094:34:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "5073:55:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 7451, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7445, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7443, + "name": "finalize_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7436, + "src": "5146:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 7444, + "name": "UNANSWERED", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7134, + "src": "5161:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "5146:25:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "||", + "rightExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7450, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7446, + "name": "finalize_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7436, + "src": "5175:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7448, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "5196:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 7447, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "5189:6:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint32_$", + "typeString": "type(uint32)" + }, + "typeName": "uint32" + }, + "id": 7449, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5189:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "5175:25:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "5146:54:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "66696e616c697a6174696f6e206465616c696e65206d757374206e6f74206861766520706173736564", + "id": 7452, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5202:43:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_8f540895d8d15453e87897307cb8351f2857abfee4e235e10c3b3c286692a622", + "typeString": "literal_string \"finalization dealine must not have passed\"" + }, + "value": "finalization dealine must not have passed" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_8f540895d8d15453e87897307cb8351f2857abfee4e235e10c3b3c286692a622", + "typeString": "literal_string \"finalization dealine must not have passed\"" + } + ], + "id": 7442, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "5138:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7453, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5138:108:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7454, + "nodeType": "ExpressionStatement", + "src": "5138:108:18" + }, + { + "assignments": [ + 7456 + ], + "declarations": [ + { + "constant": false, + "id": 7456, + "name": "opening_ts", + "nodeType": "VariableDeclaration", + "scope": 7477, + "src": "5256:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7455, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "5256:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 7461, + "initialValue": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7457, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "5276:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7459, + "indexExpression": { + "argumentTypes": null, + "id": 7458, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7423, + "src": "5286:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "5276:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7460, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "opening_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7249, + "src": "5276:33:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "5256:53:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 7471, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7465, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7463, + "name": "opening_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7456, + "src": "5327:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 7464, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5341:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "5327:15:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "||", + "rightExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7470, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7466, + "name": "opening_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7456, + "src": "5346:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7468, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "5367:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 7467, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "5360:6:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint32_$", + "typeString": "type(uint32)" + }, + "typeName": "uint32" + }, + "id": 7469, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5360:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "5346:25:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "5327:44:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "6f70656e696e672064617465206d757374206861766520706173736564", + "id": 7472, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5373:31:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_5963fbf852ce76142d772c6ce4c8614e81ba76b348890013b4cd0addd58b31b3", + "typeString": "literal_string \"opening date must have passed\"" + }, + "value": "opening date must have passed" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_5963fbf852ce76142d772c6ce4c8614e81ba76b348890013b4cd0addd58b31b3", + "typeString": "literal_string \"opening date must have passed\"" + } + ], + "id": 7462, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "5319:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7473, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5319:86:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7474, + "nodeType": "ExpressionStatement", + "src": "5319:86:18" + }, + { + "id": 7475, + "nodeType": "PlaceholderStatement", + "src": "5416:1:18" + } + ] + }, + "documentation": null, + "id": 7477, + "name": "stateOpenOrPendingArbitration", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 7424, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7423, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7477, + "src": "4966:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7422, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "4966:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "4965:21:18" + }, + "src": "4927:497:18", + "visibility": "internal" + }, + { + "body": { + "id": 7489, + "nodeType": "Block", + "src": "5475:91:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7483, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7479, + "src": "5505:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 7482, + "name": "isFinalized", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8507, + "src": "5493:11:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$returns$_t_bool_$", + "typeString": "function (bytes32) view returns (bool)" + } + }, + "id": 7484, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5493:24:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "7175657374696f6e206d7573742062652066696e616c697a6564", + "id": 7485, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5519:28:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_7678ea862d4110864dbd24145ec43051bb85f78d8eeb3bbb14a3533dd60847c8", + "typeString": "literal_string \"question must be finalized\"" + }, + "value": "question must be finalized" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_7678ea862d4110864dbd24145ec43051bb85f78d8eeb3bbb14a3533dd60847c8", + "typeString": "literal_string \"question must be finalized\"" + } + ], + "id": 7481, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "5485:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7486, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5485:63:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7487, + "nodeType": "ExpressionStatement", + "src": "5485:63:18" + }, + { + "id": 7488, + "nodeType": "PlaceholderStatement", + "src": "5558:1:18" + } + ] + }, + "documentation": null, + "id": 7490, + "name": "stateFinalized", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 7480, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7479, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7490, + "src": "5454:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7478, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "5454:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "5453:21:18" + }, + "src": "5430:136:18", + "visibility": "internal" + }, + { + "body": { + "id": 7518, + "nodeType": "Block", + "src": "5617:190:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 7498, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7495, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "5635:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7496, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "5635:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 7497, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5647:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "5635:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "626f6e64206d75737420626520706f736974697665", + "id": 7499, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5650:23:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_b3c9ee472042e2067e6f11b009a7238c6ed21a4872f0b12d2abbe4092d3c0b88", + "typeString": "literal_string \"bond must be positive\"" + }, + "value": "bond must be positive" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_b3c9ee472042e2067e6f11b009a7238c6ed21a4872f0b12d2abbe4092d3c0b88", + "typeString": "literal_string \"bond must be positive\"" + } + ], + "id": 7494, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "5627:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7500, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5627:47:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7501, + "nodeType": "ExpressionStatement", + "src": "5627:47:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 7513, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7503, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "5693:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7504, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "5693:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "32", + "id": 7510, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5739:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + } + ], + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7505, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "5707:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7507, + "indexExpression": { + "argumentTypes": null, + "id": 7506, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7492, + "src": "5717:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "5707:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7508, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bond", + "nodeType": "MemberAccess", + "referencedDeclaration": 7263, + "src": "5707:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7509, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "mul", + "nodeType": "MemberAccess", + "referencedDeclaration": 7018, + "src": "5707:31:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 7511, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5707:34:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 7512, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "5706:36:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "5693:49:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "626f6e64206d75737420626520646f75626c65206174206c656173742070726576696f757320626f6e64", + "id": 7514, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5744:44:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_65ffa1219e4f08f995c93eadfebcd61b4db428d3222f9b65896f079b3b960d3d", + "typeString": "literal_string \"bond must be double at least previous bond\"" + }, + "value": "bond must be double at least previous bond" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_65ffa1219e4f08f995c93eadfebcd61b4db428d3222f9b65896f079b3b960d3d", + "typeString": "literal_string \"bond must be double at least previous bond\"" + } + ], + "id": 7502, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "5685:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7515, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5685:104:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7516, + "nodeType": "ExpressionStatement", + "src": "5685:104:18" + }, + { + "id": 7517, + "nodeType": "PlaceholderStatement", + "src": "5799:1:18" + } + ] + }, + "documentation": null, + "id": 7519, + "name": "bondMustDouble", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 7493, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7492, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7519, + "src": "5596:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7491, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "5596:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "5595:21:18" + }, + "src": "5572:235:18", + "visibility": "internal" + }, + { + "body": { + "id": 7541, + "nodeType": "Block", + "src": "5900:159:18", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 7527, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7525, + "name": "max_previous", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7523, + "src": "5914:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 7526, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5929:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "5914:16:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 7539, + "nodeType": "IfStatement", + "src": "5910:132:18", + "trueBody": { + "id": 7538, + "nodeType": "Block", + "src": "5932:110:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 7534, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7529, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "5954:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7531, + "indexExpression": { + "argumentTypes": null, + "id": 7530, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7521, + "src": "5964:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "5954:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7532, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bond", + "nodeType": "MemberAccess", + "referencedDeclaration": 7263, + "src": "5954:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "id": 7533, + "name": "max_previous", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7523, + "src": "5985:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "5954:43:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "626f6e64206d75737420657863656564206d61785f70726576696f7573", + "id": 7535, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5999:31:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_86da50f4411a4001f63186489f5e9177ab1df516512e13b6a709fd5c2385c100", + "typeString": "literal_string \"bond must exceed max_previous\"" + }, + "value": "bond must exceed max_previous" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_86da50f4411a4001f63186489f5e9177ab1df516512e13b6a709fd5c2385c100", + "typeString": "literal_string \"bond must exceed max_previous\"" + } + ], + "id": 7528, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "5946:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7536, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5946:85:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7537, + "nodeType": "ExpressionStatement", + "src": "5946:85:18" + } + ] + } + }, + { + "id": 7540, + "nodeType": "PlaceholderStatement", + "src": "6051:1:18" + } + ] + }, + "documentation": null, + "id": 7542, + "name": "previousBondMustNotBeatMaxPrevious", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 7524, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7521, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7542, + "src": "5857:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7520, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "5857:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7523, + "name": "max_previous", + "nodeType": "VariableDeclaration", + "scope": 7542, + "src": "5878:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7522, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "5878:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "5856:43:18" + }, + "src": "5813:246:18", + "visibility": "internal" + }, + { + "body": { + "id": 7565, + "nodeType": "Block", + "src": "6246:538:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "7b227469746c65223a20222573222c202274797065223a2022626f6f6c222c202263617465676f7279223a20222573222c20226c616e67223a20222573227d", + "id": 7546, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6271:65:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_2630d91f54445fa42ec6738610b1a4c52b08a197156ab2ed97e4e17201528f2f", + "typeString": "literal_string \"{\"title\": \"%s\", \"type\": \"bool\", \"category\": \"%s\", \"lang\": \"%s\"}\"" + }, + "value": "{\"title\": \"%s\", \"type\": \"bool\", \"category\": \"%s\", \"lang\": \"%s\"}" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_2630d91f54445fa42ec6738610b1a4c52b08a197156ab2ed97e4e17201528f2f", + "typeString": "literal_string \"{\"title\": \"%s\", \"type\": \"bool\", \"category\": \"%s\", \"lang\": \"%s\"}\"" + } + ], + "id": 7545, + "name": "createTemplate", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7635, + "src": "6256:14:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_string_memory_ptr_$returns$_t_uint256_$", + "typeString": "function (string memory) returns (uint256)" + } + }, + "id": 7547, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "6256:81:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7548, + "nodeType": "ExpressionStatement", + "src": "6256:81:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "7b227469746c65223a20222573222c202274797065223a202275696e74222c2022646563696d616c73223a2031382c202263617465676f7279223a20222573222c20226c616e67223a20222573227d", + "id": 7550, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6362:81:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_f006792a99a5de2495a30060356c53fdfd8cd04c53ad3402c5353035dc6b9589", + "typeString": "literal_string \"{\"title\": \"%s\", \"type\": \"uint\", \"decimals\": 18, \"category\": \"%s\", \"lang\": \"%s\"}\"" + }, + "value": "{\"title\": \"%s\", \"type\": \"uint\", \"decimals\": 18, \"category\": \"%s\", \"lang\": \"%s\"}" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_f006792a99a5de2495a30060356c53fdfd8cd04c53ad3402c5353035dc6b9589", + "typeString": "literal_string \"{\"title\": \"%s\", \"type\": \"uint\", \"decimals\": 18, \"category\": \"%s\", \"lang\": \"%s\"}\"" + } + ], + "id": 7549, + "name": "createTemplate", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7635, + "src": "6347:14:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_string_memory_ptr_$returns$_t_uint256_$", + "typeString": "function (string memory) returns (uint256)" + } + }, + "id": 7551, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "6347:97:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7552, + "nodeType": "ExpressionStatement", + "src": "6347:97:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "7b227469746c65223a20222573222c202274797065223a202273696e676c652d73656c656374222c20226f7574636f6d6573223a205b25735d2c202263617465676f7279223a20222573222c20226c616e67223a20222573227d", + "id": 7554, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6469:92:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_e49d22c3fb3eac70dc2d9d76aa17b7e4b487f2f4b7c683f3705b638453520000", + "typeString": "literal_string \"{\"title\": \"%s\", \"type\": \"single-select\", \"outcomes\": [%s], \"category\": \"%s\", \"lang\": \"%s\"}\"" + }, + "value": "{\"title\": \"%s\", \"type\": \"single-select\", \"outcomes\": [%s], \"category\": \"%s\", \"lang\": \"%s\"}" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_e49d22c3fb3eac70dc2d9d76aa17b7e4b487f2f4b7c683f3705b638453520000", + "typeString": "literal_string \"{\"title\": \"%s\", \"type\": \"single-select\", \"outcomes\": [%s], \"category\": \"%s\", \"lang\": \"%s\"}\"" + } + ], + "id": 7553, + "name": "createTemplate", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7635, + "src": "6454:14:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_string_memory_ptr_$returns$_t_uint256_$", + "typeString": "function (string memory) returns (uint256)" + } + }, + "id": 7555, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "6454:108:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7556, + "nodeType": "ExpressionStatement", + "src": "6454:108:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "7b227469746c65223a20222573222c202274797065223a20226d756c7469706c652d73656c656374222c20226f7574636f6d6573223a205b25735d2c202263617465676f7279223a20222573222c20226c616e67223a20222573227d", + "id": 7558, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6587:94:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_1d41a41b7d3550c01209c10495988bfa01dd2e86c5a3fae5f9dbc2ccde20c1a9", + "typeString": "literal_string \"{\"title\": \"%s\", \"type\": \"multiple-select\", \"outcomes\": [%s], \"category\": \"%s\", \"lang\": \"%s\"}\"" + }, + "value": "{\"title\": \"%s\", \"type\": \"multiple-select\", \"outcomes\": [%s], \"category\": \"%s\", \"lang\": \"%s\"}" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_1d41a41b7d3550c01209c10495988bfa01dd2e86c5a3fae5f9dbc2ccde20c1a9", + "typeString": "literal_string \"{\"title\": \"%s\", \"type\": \"multiple-select\", \"outcomes\": [%s], \"category\": \"%s\", \"lang\": \"%s\"}\"" + } + ], + "id": 7557, + "name": "createTemplate", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7635, + "src": "6572:14:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_string_memory_ptr_$returns$_t_uint256_$", + "typeString": "function (string memory) returns (uint256)" + } + }, + "id": 7559, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "6572:110:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7560, + "nodeType": "ExpressionStatement", + "src": "6572:110:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "7b227469746c65223a20222573222c202274797065223a20226461746574696d65222c202263617465676f7279223a20222573222c20226c616e67223a20222573227d", + "id": 7562, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6707:69:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_5b13a2ad9e4dfbf057ecf2c35d4152b61718a3ab46a14db63feb17b1515749ba", + "typeString": "literal_string \"{\"title\": \"%s\", \"type\": \"datetime\", \"category\": \"%s\", \"lang\": \"%s\"}\"" + }, + "value": "{\"title\": \"%s\", \"type\": \"datetime\", \"category\": \"%s\", \"lang\": \"%s\"}" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_5b13a2ad9e4dfbf057ecf2c35d4152b61718a3ab46a14db63feb17b1515749ba", + "typeString": "literal_string \"{\"title\": \"%s\", \"type\": \"datetime\", \"category\": \"%s\", \"lang\": \"%s\"}\"" + } + ], + "id": 7561, + "name": "createTemplate", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7635, + "src": "6692:14:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_string_memory_ptr_$returns$_t_uint256_$", + "typeString": "function (string memory) returns (uint256)" + } + }, + "id": 7563, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "6692:85:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7564, + "nodeType": "ExpressionStatement", + "src": "6692:85:18" + } + ] + }, + "documentation": "@notice Constructor, sets up some initial templates\n @dev Creates some generalized templates for different question types used in the DApp.", + "id": 7566, + "implemented": true, + "isConstructor": true, + "isDeclaredConst": false, + "modifiers": [], + "name": "", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 7543, + "nodeType": "ParameterList", + "parameters": [], + "src": "6231:2:18" + }, + "payable": false, + "returnParameters": { + "id": 7544, + "nodeType": "ParameterList", + "parameters": [], + "src": "6246:0:18" + }, + "scope": 9314, + "src": "6220:564:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 7586, + "nodeType": "Block", + "src": "7129:108:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 7578, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7573, + "name": "arbitrator_question_fees", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7305, + "src": "7139:24:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 7576, + "indexExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7574, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "7164:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7575, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7164:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "7139:36:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 7577, + "name": "fee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7568, + "src": "7178:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7139:42:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7579, + "nodeType": "ExpressionStatement", + "src": "7139:42:18" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7581, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "7214:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7582, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7214:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 7583, + "name": "fee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7568, + "src": "7226:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 7580, + "name": "LogSetQuestionFee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7149, + "src": "7196:17:18", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,uint256)" + } + }, + "id": 7584, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7196:34:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7585, + "nodeType": "EmitStatement", + "src": "7191:39:18" + } + ] + }, + "documentation": "@notice Function for arbitrator to set an optional per-question fee. \n @dev The per-question fee, charged when a question is asked, is intended as an anti-spam measure.\n @param fee The fee to be charged by the arbitrator when a question is asked", + "id": 7587, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [], + "id": 7571, + "modifierName": { + "argumentTypes": null, + "id": 7570, + "name": "stateAny", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7326, + "src": "7104:8:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "7104:10:18" + } + ], + "name": "setQuestionFee", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 7569, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7568, + "name": "fee", + "nodeType": "VariableDeclaration", + "scope": 7587, + "src": "7082:11:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7567, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "7082:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "7081:13:18" + }, + "payable": false, + "returnParameters": { + "id": 7572, + "nodeType": "ParameterList", + "parameters": [], + "src": "7129:0:18" + }, + "scope": 9314, + "src": "7058:179:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 7634, + "nodeType": "Block", + "src": "7706:259:18", + "statements": [ + { + "assignments": [ + 7597 + ], + "declarations": [ + { + "constant": false, + "id": 7597, + "name": "id", + "nodeType": "VariableDeclaration", + "scope": 7635, + "src": "7716:10:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7596, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "7716:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 7599, + "initialValue": { + "argumentTypes": null, + "id": 7598, + "name": "nextTemplateID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7281, + "src": "7729:14:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "7716:27:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 7605, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7600, + "name": "templates", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7285, + "src": "7753:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint256_$_t_uint256_$", + "typeString": "mapping(uint256 => uint256)" + } + }, + "id": 7602, + "indexExpression": { + "argumentTypes": null, + "id": 7601, + "name": "id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7597, + "src": "7763:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "7753:13:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7603, + "name": "block", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9706, + "src": "7769:5:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_block", + "typeString": "block" + } + }, + "id": 7604, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "number", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7769:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7753:28:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7606, + "nodeType": "ExpressionStatement", + "src": "7753:28:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 7616, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7607, + "name": "template_hashes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7289, + "src": "7791:15:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint256_$_t_bytes32_$", + "typeString": "mapping(uint256 => bytes32)" + } + }, + "id": 7609, + "indexExpression": { + "argumentTypes": null, + "id": 7608, + "name": "id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7597, + "src": "7807:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "7791:19:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7613, + "name": "content", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7589, + "src": "7840:7:18", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + ], + "expression": { + "argumentTypes": null, + "id": 7611, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9703, + "src": "7823:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 7612, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7823:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 7614, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7823:25:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 7610, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9710, + "src": "7813:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 7615, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7813:36:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "7791:58:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 7617, + "nodeType": "ExpressionStatement", + "src": "7791:58:18" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7619, + "name": "id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7597, + "src": "7879:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7620, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "7883:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7621, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7883:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 7622, + "name": "content", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7589, + "src": "7895:7:18", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + ], + "id": 7618, + "name": "LogNewTemplate", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7157, + "src": "7864:14:18", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_uint256_$_t_address_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (uint256,address,string memory)" + } + }, + "id": 7623, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7864:39:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7624, + "nodeType": "EmitStatement", + "src": "7859:44:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 7630, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 7625, + "name": "nextTemplateID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7281, + "src": "7913:14:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "31", + "id": 7628, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7937:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + } + ], + "expression": { + "argumentTypes": null, + "id": 7626, + "name": "id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7597, + "src": "7930:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7627, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 7080, + "src": "7930:6:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 7629, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7930:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7913:26:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7631, + "nodeType": "ExpressionStatement", + "src": "7913:26:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 7632, + "name": "id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7597, + "src": "7956:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 7595, + "id": 7633, + "nodeType": "Return", + "src": "7949:9:18" + } + ] + }, + "documentation": "@notice Create a reusable template, which should be a JSON document.\n Placeholders should use gettext() syntax, eg %s.\n @dev Template data is only stored in the event logs, but its block number is kept in contract storage.\n @param content The template content\n @return The ID of the newly-created template, which is created sequentially.", + "id": 7635, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [], + "id": 7592, + "modifierName": { + "argumentTypes": null, + "id": 7591, + "name": "stateAny", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7326, + "src": "7666:8:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "7666:10:18" + } + ], + "name": "createTemplate", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 7590, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7589, + "name": "content", + "nodeType": "VariableDeclaration", + "scope": 7635, + "src": "7641:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 7588, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "7641:6:18", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "7640:16:18" + }, + "payable": false, + "returnParameters": { + "id": 7595, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7594, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 7635, + "src": "7697:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7593, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "7697:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "7696:9:18" + }, + "scope": 9314, + "src": "7617:348:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 7667, + "nodeType": "Block", + "src": "9110:153:18", + "statements": [ + { + "assignments": [ + 7653 + ], + "declarations": [ + { + "constant": false, + "id": 7653, + "name": "template_id", + "nodeType": "VariableDeclaration", + "scope": 7668, + "src": "9120:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7652, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "9120:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 7657, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7655, + "name": "content", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7637, + "src": "9157:7:18", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + ], + "id": 7654, + "name": "createTemplate", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7635, + "src": "9142:14:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_string_memory_ptr_$returns$_t_uint256_$", + "typeString": "function (string memory) returns (uint256)" + } + }, + "id": 7656, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "9142:23:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "9120:45:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7659, + "name": "template_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7653, + "src": "9194:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 7660, + "name": "question", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7639, + "src": "9207:8:18", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + }, + { + "argumentTypes": null, + "id": 7661, + "name": "arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7641, + "src": "9217:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 7662, + "name": "timeout", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7643, + "src": "9229:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + { + "argumentTypes": null, + "id": 7663, + "name": "opening_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7645, + "src": "9238:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + { + "argumentTypes": null, + "id": 7664, + "name": "nonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7647, + "src": "9250:5:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 7658, + "name": "askQuestion", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7744, + "src": "9182:11:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_uint256_$_t_string_memory_ptr_$_t_address_$_t_uint32_$_t_uint32_$_t_uint256_$returns$_t_bytes32_$", + "typeString": "function (uint256,string memory,address,uint32,uint32,uint256) returns (bytes32)" + } + }, + "id": 7665, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "9182:74:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 7651, + "id": 7666, + "nodeType": "Return", + "src": "9175:81:18" + } + ] + }, + "documentation": "@notice Create a new reusable template and use it to ask a question\n @dev Template data is only stored in the event logs, but its block number is kept in contract storage.\n @param content The template content\n @param question A string containing the parameters that will be passed into the template to make the question\n @param arbitrator The arbitration contract that will have the final word on the answer if there is a dispute\n @param timeout How long the contract should wait after the answer is changed before finalizing on that answer\n @param opening_ts If set, the earliest time it should be possible to answer the question.\n @param nonce A user-specified nonce used in the question ID. Change it to repeat a question.\n @return The ID of the newly-created template, which is created sequentially.", + "id": 7668, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "createTemplateAndAskQuestion", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 7648, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7637, + "name": "content", + "nodeType": "VariableDeclaration", + "scope": 7668, + "src": "8886:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 7636, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "8886:6:18", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7639, + "name": "question", + "nodeType": "VariableDeclaration", + "scope": 7668, + "src": "8911:15:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 7638, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "8911:6:18", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7641, + "name": "arbitrator", + "nodeType": "VariableDeclaration", + "scope": 7668, + "src": "8928:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7640, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "8928:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7643, + "name": "timeout", + "nodeType": "VariableDeclaration", + "scope": 7668, + "src": "8948:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7642, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "8948:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7645, + "name": "opening_ts", + "nodeType": "VariableDeclaration", + "scope": 7668, + "src": "8964:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7644, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "8964:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7647, + "name": "nonce", + "nodeType": "VariableDeclaration", + "scope": 7668, + "src": "8983:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7646, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "8983:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "8876:127:18" + }, + "payable": true, + "returnParameters": { + "id": 7651, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7650, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 7668, + "src": "9101:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7649, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "9101:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "9100:9:18" + }, + "scope": 9314, + "src": "8839:424:18", + "stateMutability": "payable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 7743, + "nodeType": "Block", + "src": "10380:533:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 7690, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7686, + "name": "templates", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7285, + "src": "10399:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint256_$_t_uint256_$", + "typeString": "mapping(uint256 => uint256)" + } + }, + "id": 7688, + "indexExpression": { + "argumentTypes": null, + "id": 7687, + "name": "template_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7670, + "src": "10409:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10399:22:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 7689, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10424:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "10399:26:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "74656d706c617465206d757374206578697374", + "id": 7691, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10427:21:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_6b763f6fbc16e7da696107f42e85f1f46703aa651f9e70e97d489e8899582b16", + "typeString": "literal_string \"template must exist\"" + }, + "value": "template must exist" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_6b763f6fbc16e7da696107f42e85f1f46703aa651f9e70e97d489e8899582b16", + "typeString": "literal_string \"template must exist\"" + } + ], + "id": 7685, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "10391:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7692, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10391:58:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7693, + "nodeType": "ExpressionStatement", + "src": "10391:58:18" + }, + { + "assignments": [ + 7695 + ], + "declarations": [ + { + "constant": false, + "id": 7695, + "name": "content_hash", + "nodeType": "VariableDeclaration", + "scope": 7744, + "src": "10460:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7694, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "10460:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 7704, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7699, + "name": "template_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7670, + "src": "10510:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 7700, + "name": "opening_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7678, + "src": "10523:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + { + "argumentTypes": null, + "id": 7701, + "name": "question", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7672, + "src": "10535:8:18", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + ], + "expression": { + "argumentTypes": null, + "id": 7697, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9703, + "src": "10493:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 7698, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "10493:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 7702, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10493:51:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 7696, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9710, + "src": "10483:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 7703, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10483:62:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "10460:85:18" + }, + { + "assignments": [ + 7706 + ], + "declarations": [ + { + "constant": false, + "id": 7706, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7744, + "src": "10555:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7705, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "10555:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 7718, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7710, + "name": "content_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7695, + "src": "10604:12:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 7711, + "name": "arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7674, + "src": "10618:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 7712, + "name": "timeout", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7676, + "src": "10630:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7713, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "10639:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7714, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "10639:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 7715, + "name": "nonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7680, + "src": "10651:5:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 7708, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9703, + "src": "10587:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 7709, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "10587:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 7716, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10587:70:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 7707, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9710, + "src": "10577:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 7717, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10577:81:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "10555:103:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7720, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7706, + "src": "10682:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 7721, + "name": "content_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7695, + "src": "10695:12:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 7722, + "name": "arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7674, + "src": "10709:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 7723, + "name": "timeout", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7676, + "src": "10721:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + { + "argumentTypes": null, + "id": 7724, + "name": "opening_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7678, + "src": "10730:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + ], + "id": 7719, + "name": "_askQuestion", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7859, + "src": "10669:12:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_address_$_t_uint32_$_t_uint32_$returns$__$", + "typeString": "function (bytes32,bytes32,address,uint32,uint32)" + } + }, + "id": 7725, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10669:72:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7726, + "nodeType": "ExpressionStatement", + "src": "10669:72:18" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7728, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7706, + "src": "10771:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7729, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "10784:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7730, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "10784:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 7731, + "name": "template_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7670, + "src": "10796:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 7732, + "name": "question", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7672, + "src": "10809:8:18", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + }, + { + "argumentTypes": null, + "id": 7733, + "name": "content_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7695, + "src": "10819:12:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 7734, + "name": "arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7674, + "src": "10833:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 7735, + "name": "timeout", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7676, + "src": "10845:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + { + "argumentTypes": null, + "id": 7736, + "name": "opening_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7678, + "src": "10854:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + { + "argumentTypes": null, + "id": 7737, + "name": "nonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7680, + "src": "10866:5:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 7738, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "10873:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 7727, + "name": "LogNewQuestion", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7179, + "src": "10756:14:18", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_address_$_t_uint256_$_t_string_memory_ptr_$_t_bytes32_$_t_address_$_t_uint32_$_t_uint32_$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (bytes32,address,uint256,string memory,bytes32,address,uint32,uint32,uint256,uint256)" + } + }, + "id": 7739, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10756:121:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7740, + "nodeType": "EmitStatement", + "src": "10751:126:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 7741, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7706, + "src": "10895:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 7684, + "id": 7742, + "nodeType": "Return", + "src": "10888:18:18" + } + ] + }, + "documentation": "@notice Ask a new question and return the ID\n @dev Template data is only stored in the event logs, but its block number is kept in contract storage.\n @param template_id The ID number of the template the question will use\n @param question A string containing the parameters that will be passed into the template to make the question\n @param arbitrator The arbitration contract that will have the final word on the answer if there is a dispute\n @param timeout How long the contract should wait after the answer is changed before finalizing on that answer\n @param opening_ts If set, the earliest time it should be possible to answer the question.\n @param nonce A user-specified nonce used in the question ID. Change it to repeat a question.\n @return The ID of the newly-created question, created deterministically.", + "id": 7744, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "askQuestion", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 7681, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7670, + "name": "template_id", + "nodeType": "VariableDeclaration", + "scope": 7744, + "src": "10166:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7669, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "10166:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7672, + "name": "question", + "nodeType": "VariableDeclaration", + "scope": 7744, + "src": "10187:15:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 7671, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "10187:6:18", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7674, + "name": "arbitrator", + "nodeType": "VariableDeclaration", + "scope": 7744, + "src": "10204:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7673, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "10204:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7676, + "name": "timeout", + "nodeType": "VariableDeclaration", + "scope": 7744, + "src": "10224:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7675, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "10224:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7678, + "name": "opening_ts", + "nodeType": "VariableDeclaration", + "scope": 7744, + "src": "10240:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7677, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "10240:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7680, + "name": "nonce", + "nodeType": "VariableDeclaration", + "scope": 7744, + "src": "10259:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7679, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "10259:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "10165:108:18" + }, + "payable": true, + "returnParameters": { + "id": 7684, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7683, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 7744, + "src": "10371:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7682, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "10371:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "10370:9:18" + }, + "scope": 9314, + "src": "10145:768:18", + "stateMutability": "payable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 7858, + "nodeType": "Block", + "src": "11090:1316:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7763, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7761, + "name": "timeout", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7752, + "src": "11191:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 7762, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11201:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "11191:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "74696d656f7574206d75737420626520706f736974697665", + "id": 7764, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11204:26:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_21a6e8d6041a43652989cb6df398a64082bcb4cf008fb5cf0deefa1dfb00eaf0", + "typeString": "literal_string \"timeout must be positive\"" + }, + "value": "timeout must be positive" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_21a6e8d6041a43652989cb6df398a64082bcb4cf008fb5cf0deefa1dfb00eaf0", + "typeString": "literal_string \"timeout must be positive\"" + } + ], + "id": 7760, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "11183:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7765, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11183:48:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7766, + "nodeType": "ExpressionStatement", + "src": "11183:48:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7770, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7768, + "name": "timeout", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7752, + "src": "11250:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "hexValue": "333635", + "id": 7769, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11260:8:18", + "subdenomination": "days", + "typeDescriptions": { + "typeIdentifier": "t_rational_31536000_by_1", + "typeString": "int_const 31536000" + }, + "value": "365" + }, + "src": "11250:18:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "74696d656f7574206d757374206265206c657373207468616e203336352064617973", + "id": 7771, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11270:36:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_d41c7cd8b163218b0d4e0b8fc4fae3eb6e53b50e3a40bd3b56ca7bc1b684a1e9", + "typeString": "literal_string \"timeout must be less than 365 days\"" + }, + "value": "timeout must be less than 365 days" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_d41c7cd8b163218b0d4e0b8fc4fae3eb6e53b50e3a40bd3b56ca7bc1b684a1e9", + "typeString": "literal_string \"timeout must be less than 365 days\"" + } + ], + "id": 7767, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "11242:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7772, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11242:65:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7773, + "nodeType": "ExpressionStatement", + "src": "11242:65:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 7777, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7775, + "name": "arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7750, + "src": "11326:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "id": 7776, + "name": "NULL_ADDRESS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7126, + "src": "11340:12:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "11326:26:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "61726269747261746f72206d75737420626520736574", + "id": 7778, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11354:24:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_41e3ac7303a8b1456ede85d1facc68e58dc10ca71a9ec24a5bab787499ac2a73", + "typeString": "literal_string \"arbitrator must be set\"" + }, + "value": "arbitrator must be set" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_41e3ac7303a8b1456ede85d1facc68e58dc10ca71a9ec24a5bab787499ac2a73", + "typeString": "literal_string \"arbitrator must be set\"" + } + ], + "id": 7774, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "11318:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7779, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11318:61:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7780, + "nodeType": "ExpressionStatement", + "src": "11318:61:18" + }, + { + "assignments": [ + 7782 + ], + "declarations": [ + { + "constant": false, + "id": 7782, + "name": "bounty", + "nodeType": "VariableDeclaration", + "scope": 7859, + "src": "11390:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7781, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11390:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 7785, + "initialValue": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7783, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "11407:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7784, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "11407:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "11390:26:18" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 7789, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7786, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "11808:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7787, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "11808:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "id": 7788, + "name": "arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7750, + "src": "11822:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "11808:24:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 7822, + "nodeType": "IfStatement", + "src": "11804:324:18", + "trueBody": { + "id": 7821, + "nodeType": "Block", + "src": "11834:294:18", + "statements": [ + { + "assignments": [ + 7791 + ], + "declarations": [ + { + "constant": false, + "id": 7791, + "name": "question_fee", + "nodeType": "VariableDeclaration", + "scope": 7859, + "src": "11848:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7790, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11848:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 7795, + "initialValue": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7792, + "name": "arbitrator_question_fees", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7305, + "src": "11871:24:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 7794, + "indexExpression": { + "argumentTypes": null, + "id": 7793, + "name": "arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7750, + "src": "11896:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "11871:36:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "11848:59:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 7799, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7797, + "name": "bounty", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7782, + "src": "11929:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": { + "argumentTypes": null, + "id": 7798, + "name": "question_fee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7791, + "src": "11939:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "11929:22:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4554482070726f7669646564206d75737420636f766572207175657374696f6e20666565", + "id": 7800, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11953:38:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_f563467593cc476b2eaa9803db9a434ac560eec51474d9492a841a55aff9878c", + "typeString": "literal_string \"ETH provided must cover question fee\"" + }, + "value": "ETH provided must cover question fee" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_f563467593cc476b2eaa9803db9a434ac560eec51474d9492a841a55aff9878c", + "typeString": "literal_string \"ETH provided must cover question fee\"" + } + ], + "id": 7796, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "11921:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7801, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11921:71:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7802, + "nodeType": "ExpressionStatement", + "src": "11921:71:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 7808, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 7803, + "name": "bounty", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7782, + "src": "12007:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7806, + "name": "question_fee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7791, + "src": "12027:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 7804, + "name": "bounty", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7782, + "src": "12016:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7805, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sub", + "nodeType": "MemberAccess", + "referencedDeclaration": 7056, + "src": "12016:10:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 7807, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12016:24:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "12007:33:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7809, + "nodeType": "ExpressionStatement", + "src": "12007:33:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 7819, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7810, + "name": "balanceOf", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 396, + "src": "12054:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 7812, + "indexExpression": { + "argumentTypes": null, + "id": 7811, + "name": "arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7750, + "src": "12064:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "12054:21:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7817, + "name": "question_fee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7791, + "src": "12104:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7813, + "name": "balanceOf", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 396, + "src": "12078:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 7815, + "indexExpression": { + "argumentTypes": null, + "id": 7814, + "name": "arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7750, + "src": "12088:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12078:21:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7816, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 7080, + "src": "12078:25:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 7818, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12078:39:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "12054:63:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7820, + "nodeType": "ExpressionStatement", + "src": "12054:63:18" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "id": 7828, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7823, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "12138:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7825, + "indexExpression": { + "argumentTypes": null, + "id": 7824, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7746, + "src": "12148:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12138:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7826, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "content_hash", + "nodeType": "MemberAccess", + "referencedDeclaration": 7245, + "src": "12138:35:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 7827, + "name": "content_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7748, + "src": "12176:12:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "12138:50:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 7829, + "nodeType": "ExpressionStatement", + "src": "12138:50:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 7835, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7830, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "12198:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7832, + "indexExpression": { + "argumentTypes": null, + "id": 7831, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7746, + "src": "12208:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12198:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7833, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "arbitrator", + "nodeType": "MemberAccess", + "referencedDeclaration": 7247, + "src": "12198:33:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 7834, + "name": "arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7750, + "src": "12234:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "12198:46:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 7836, + "nodeType": "ExpressionStatement", + "src": "12198:46:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 7842, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7837, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "12254:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7839, + "indexExpression": { + "argumentTypes": null, + "id": 7838, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7746, + "src": "12264:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12254:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7840, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "opening_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7249, + "src": "12254:33:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 7841, + "name": "opening_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7754, + "src": "12290:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "12254:46:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "id": 7843, + "nodeType": "ExpressionStatement", + "src": "12254:46:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 7849, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7844, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "12310:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7846, + "indexExpression": { + "argumentTypes": null, + "id": 7845, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7746, + "src": "12320:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12310:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7847, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "timeout", + "nodeType": "MemberAccess", + "referencedDeclaration": 7251, + "src": "12310:30:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 7848, + "name": "timeout", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7752, + "src": "12343:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "12310:40:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "id": 7850, + "nodeType": "ExpressionStatement", + "src": "12310:40:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 7856, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7851, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "12360:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7853, + "indexExpression": { + "argumentTypes": null, + "id": 7852, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7746, + "src": "12370:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12360:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7854, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "bounty", + "nodeType": "MemberAccess", + "referencedDeclaration": 7257, + "src": "12360:29:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 7855, + "name": "bounty", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7782, + "src": "12392:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "12360:38:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7857, + "nodeType": "ExpressionStatement", + "src": "12360:38:18" + } + ] + }, + "documentation": null, + "id": 7859, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 7757, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7746, + "src": "11064:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 7758, + "modifierName": { + "argumentTypes": null, + "id": 7756, + "name": "stateNotCreated", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7342, + "src": "11048:15:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "11048:28:18" + } + ], + "name": "_askQuestion", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 7755, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7746, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7859, + "src": "10941:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7745, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "10941:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7748, + "name": "content_hash", + "nodeType": "VariableDeclaration", + "scope": 7859, + "src": "10962:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7747, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "10962:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7750, + "name": "arbitrator", + "nodeType": "VariableDeclaration", + "scope": 7859, + "src": "10984:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7749, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "10984:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7752, + "name": "timeout", + "nodeType": "VariableDeclaration", + "scope": 7859, + "src": "11004:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7751, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "11004:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7754, + "name": "opening_ts", + "nodeType": "VariableDeclaration", + "scope": 7859, + "src": "11020:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7753, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "11020:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "10940:98:18" + }, + "payable": false, + "returnParameters": { + "id": 7759, + "nodeType": "ParameterList", + "parameters": [], + "src": "11090:0:18" + }, + "scope": 9314, + "src": "10919:1487:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 7893, + "nodeType": "Block", + "src": "12755:194:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 7879, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7867, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "12765:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7869, + "indexExpression": { + "argumentTypes": null, + "id": 7868, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7861, + "src": "12775:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12765:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7870, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "bounty", + "nodeType": "MemberAccess", + "referencedDeclaration": 7257, + "src": "12765:29:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7876, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "12831:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7877, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "12831:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7871, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "12797:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7873, + "indexExpression": { + "argumentTypes": null, + "id": 7872, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7861, + "src": "12807:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12797:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7874, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bounty", + "nodeType": "MemberAccess", + "referencedDeclaration": 7257, + "src": "12797:29:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7875, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 7080, + "src": "12797:33:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 7878, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12797:44:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "12765:76:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7880, + "nodeType": "ExpressionStatement", + "src": "12765:76:18" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7882, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7861, + "src": "12876:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7883, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "12889:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7884, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "12889:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7885, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "12900:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7887, + "indexExpression": { + "argumentTypes": null, + "id": 7886, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7861, + "src": "12910:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12900:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7888, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bounty", + "nodeType": "MemberAccess", + "referencedDeclaration": 7257, + "src": "12900:29:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7889, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "12931:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7890, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "12931:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 7881, + "name": "LogFundAnswerBounty", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7189, + "src": "12856:19:18", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_uint256_$_t_uint256_$_t_address_$returns$__$", + "typeString": "function (bytes32,uint256,uint256,address)" + } + }, + "id": 7891, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12856:86:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7892, + "nodeType": "EmitStatement", + "src": "12851:91:18" + } + ] + }, + "documentation": "@notice Add funds to the bounty for a question\n @dev Add bounty funds after the initial question creation. Can be done any time until the question is finalized.\n @param question_id The ID of the question you wish to fund", + "id": 7894, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 7864, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7861, + "src": "12721:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 7865, + "modifierName": { + "argumentTypes": null, + "id": 7863, + "name": "stateOpen", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7407, + "src": "12711:9:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "12711:22:18" + } + ], + "name": "fundAnswerBounty", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 7862, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7861, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7894, + "src": "12681:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7860, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "12681:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "12680:21:18" + }, + "payable": true, + "returnParameters": { + "id": 7866, + "nodeType": "ParameterList", + "parameters": [], + "src": "12755:0:18" + }, + "scope": 9314, + "src": "12655:294:18", + "stateMutability": "payable", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 7932, + "nodeType": "Block", + "src": "13680:170:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7914, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7896, + "src": "13710:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 7915, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7898, + "src": "13723:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7916, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "13731:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7917, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "13731:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7918, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "13743:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7919, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "13743:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 7920, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13754:5:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 7913, + "name": "_addAnswerToHistory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8235, + "src": "13690:19:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_address_$_t_uint256_$_t_bool_$returns$__$", + "typeString": "function (bytes32,bytes32,address,uint256,bool)" + } + }, + "id": 7921, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13690:70:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7922, + "nodeType": "ExpressionStatement", + "src": "13690:70:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7924, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7896, + "src": "13791:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 7925, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7898, + "src": "13804:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7926, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "13812:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7928, + "indexExpression": { + "argumentTypes": null, + "id": 7927, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7896, + "src": "13822:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "13812:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7929, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timeout", + "nodeType": "MemberAccess", + "referencedDeclaration": 7251, + "src": "13812:30:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + ], + "id": 7923, + "name": "_updateCurrentAnswer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8264, + "src": "13770:20:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_uint32_$returns$__$", + "typeString": "function (bytes32,bytes32,uint32)" + } + }, + "id": 7930, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13770:73:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7931, + "nodeType": "ExpressionStatement", + "src": "13770:73:18" + } + ] + }, + "documentation": "@notice Submit an answer for a question.\n @dev Adds the answer to the history and updates the current \"best\" answer.\n May be subject to front-running attacks; Substitute submitAnswerCommitment()->submitAnswerReveal() to prevent them.\n @param question_id The ID of the question\n @param answer The answer, encoded into bytes32\n @param max_previous If specified, reverts if a bond higher than this was submitted after you sent your transaction.", + "id": 7933, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 7903, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7896, + "src": "13540:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 7904, + "modifierName": { + "argumentTypes": null, + "id": 7902, + "name": "stateOpen", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7407, + "src": "13530:9:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "13530:22:18" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 7906, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7896, + "src": "13576:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 7907, + "modifierName": { + "argumentTypes": null, + "id": 7905, + "name": "bondMustDouble", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7519, + "src": "13561:14:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "13561:27:18" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 7909, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7896, + "src": "13632:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 7910, + "name": "max_previous", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7900, + "src": "13645:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 7911, + "modifierName": { + "argumentTypes": null, + "id": 7908, + "name": "previousBondMustNotBeatMaxPrevious", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7542, + "src": "13597:34:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$_t_uint256_$", + "typeString": "modifier (bytes32,uint256)" + } + }, + "nodeType": "ModifierInvocation", + "src": "13597:61:18" + } + ], + "name": "submitAnswer", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 7901, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7896, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7933, + "src": "13462:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7895, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "13462:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7898, + "name": "answer", + "nodeType": "VariableDeclaration", + "scope": 7933, + "src": "13483:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7897, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "13483:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7900, + "name": "max_previous", + "nodeType": "VariableDeclaration", + "scope": 7933, + "src": "13499:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7899, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "13499:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "13461:59:18" + }, + "payable": true, + "returnParameters": { + "id": 7912, + "nodeType": "ParameterList", + "parameters": [], + "src": "13680:0:18" + }, + "scope": 9314, + "src": "13440:410:18", + "stateMutability": "payable", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 7979, + "nodeType": "Block", + "src": "14715:240:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 7957, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7955, + "name": "answerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7941, + "src": "14733:8:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "id": 7956, + "name": "NULL_ADDRESS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7126, + "src": "14745:12:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "14733:24:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "616e737765726572206d757374206265206e6f6e2d7a65726f", + "id": 7958, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14759:27:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_1a11019cd9d1425a5b8b53e98d98a4940adc356e8b64f2a44d399cf8bb21778b", + "typeString": "literal_string \"answerer must be non-zero\"" + }, + "value": "answerer must be non-zero" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_1a11019cd9d1425a5b8b53e98d98a4940adc356e8b64f2a44d399cf8bb21778b", + "typeString": "literal_string \"answerer must be non-zero\"" + } + ], + "id": 7954, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "14725:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7959, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "14725:62:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7960, + "nodeType": "ExpressionStatement", + "src": "14725:62:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7962, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7935, + "src": "14817:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 7963, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7937, + "src": "14830:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 7964, + "name": "answerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7941, + "src": "14838:8:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7965, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "14848:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7966, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "14848:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 7967, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14859:5:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 7961, + "name": "_addAnswerToHistory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8235, + "src": "14797:19:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_address_$_t_uint256_$_t_bool_$returns$__$", + "typeString": "function (bytes32,bytes32,address,uint256,bool)" + } + }, + "id": 7968, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "14797:68:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7969, + "nodeType": "ExpressionStatement", + "src": "14797:68:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7971, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7935, + "src": "14896:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 7972, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7937, + "src": "14909:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7973, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "14917:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7975, + "indexExpression": { + "argumentTypes": null, + "id": 7974, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7935, + "src": "14927:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "14917:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7976, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timeout", + "nodeType": "MemberAccess", + "referencedDeclaration": 7251, + "src": "14917:30:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + ], + "id": 7970, + "name": "_updateCurrentAnswer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8264, + "src": "14875:20:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_uint32_$returns$__$", + "typeString": "function (bytes32,bytes32,uint32)" + } + }, + "id": 7977, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "14875:73:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7978, + "nodeType": "ExpressionStatement", + "src": "14875:73:18" + } + ] + }, + "documentation": "@notice Submit an answer for a question, crediting it to the specified account.\n @dev Adds the answer to the history and updates the current \"best\" answer.\n May be subject to front-running attacks; Substitute submitAnswerCommitment()->submitAnswerReveal() to prevent them.\n @param question_id The ID of the question\n @param answer The answer, encoded into bytes32\n @param max_previous If specified, reverts if a bond higher than this was submitted after you sent your transaction.\n @param answerer The account to which the answer should be credited", + "id": 7980, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 7944, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7935, + "src": "14575:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 7945, + "modifierName": { + "argumentTypes": null, + "id": 7943, + "name": "stateOpen", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7407, + "src": "14565:9:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "14565:22:18" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 7947, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7935, + "src": "14611:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 7948, + "modifierName": { + "argumentTypes": null, + "id": 7946, + "name": "bondMustDouble", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7519, + "src": "14596:14:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "14596:27:18" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 7950, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7935, + "src": "14667:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 7951, + "name": "max_previous", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7939, + "src": "14680:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 7952, + "modifierName": { + "argumentTypes": null, + "id": 7949, + "name": "previousBondMustNotBeatMaxPrevious", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7542, + "src": "14632:34:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$_t_uint256_$", + "typeString": "modifier (bytes32,uint256)" + } + }, + "nodeType": "ModifierInvocation", + "src": "14632:61:18" + } + ], + "name": "submitAnswerFor", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 7942, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7935, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7980, + "src": "14480:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7934, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "14480:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7937, + "name": "answer", + "nodeType": "VariableDeclaration", + "scope": 7980, + "src": "14501:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7936, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "14501:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7939, + "name": "max_previous", + "nodeType": "VariableDeclaration", + "scope": 7980, + "src": "14517:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7938, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "14517:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7941, + "name": "answerer", + "nodeType": "VariableDeclaration", + "scope": 7980, + "src": "14539:16:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7940, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "14539:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "14479:77:18" + }, + "payable": true, + "returnParameters": { + "id": 7953, + "nodeType": "ParameterList", + "parameters": [], + "src": "14715:0:18" + }, + "scope": 9314, + "src": "14455:500:18", + "stateMutability": "payable", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 8018, + "nodeType": "Block", + "src": "15236:306:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 7993, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7988, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "15254:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 7990, + "indexExpression": { + "argumentTypes": null, + "id": 7989, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7984, + "src": "15266:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "15254:26:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "id": 7991, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "reveal_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7266, + "src": "15254:36:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 7992, + "name": "COMMITMENT_NON_EXISTENT", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7137, + "src": "15294:23:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "15254:63:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "636f6d6d69746d656e74206d757374206e6f7420616c7265616479206578697374", + "id": 7994, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "15319:35:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c2878907358507a98137b5e459ef2a610f3aa0fc728f22215b4a187d8849acf0", + "typeString": "literal_string \"commitment must not already exist\"" + }, + "value": "commitment must not already exist" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_c2878907358507a98137b5e459ef2a610f3aa0fc728f22215b4a187d8849acf0", + "typeString": "literal_string \"commitment must not already exist\"" + } + ], + "id": 7987, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "15246:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7995, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "15246:109:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7996, + "nodeType": "ExpressionStatement", + "src": "15246:109:18" + }, + { + "assignments": [ + 7998 + ], + "declarations": [ + { + "constant": false, + "id": 7998, + "name": "commitment_timeout", + "nodeType": "VariableDeclaration", + "scope": 8019, + "src": "15366:25:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7997, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "15366:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8005, + "initialValue": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 8004, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7999, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "15394:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8001, + "indexExpression": { + "argumentTypes": null, + "id": 8000, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7982, + "src": "15404:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "15394:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8002, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timeout", + "nodeType": "MemberAccess", + "referencedDeclaration": 7251, + "src": "15394:30:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "/", + "rightExpression": { + "argumentTypes": null, + "id": 8003, + "name": "COMMITMENT_TIMEOUT_RATIO", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7140, + "src": "15427:24:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "15394:57:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "15366:85:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8016, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8006, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "15461:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 8008, + "indexExpression": { + "argumentTypes": null, + "id": 8007, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7984, + "src": "15473:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "15461:26:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "id": 8009, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "reveal_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7266, + "src": "15461:36:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8014, + "name": "commitment_timeout", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7998, + "src": "15516:18:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8011, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "15507:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 8010, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "15500:6:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint32_$", + "typeString": "type(uint32)" + }, + "typeName": "uint32" + }, + "id": 8012, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "15500:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "id": 8013, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 7107, + "src": "15500:15:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint32_$_t_uint32_$returns$_t_uint32_$bound_to$_t_uint32_$", + "typeString": "function (uint32,uint32) pure returns (uint32)" + } + }, + "id": 8015, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "15500:35:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "15461:74:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "id": 8017, + "nodeType": "ExpressionStatement", + "src": "15461:74:18" + } + ] + }, + "documentation": null, + "id": 8019, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "_storeCommitment", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 7985, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7982, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8019, + "src": "15174:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7981, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "15174:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7984, + "name": "commitment_id", + "nodeType": "VariableDeclaration", + "scope": 8019, + "src": "15195:21:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7983, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "15195:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "15173:44:18" + }, + "payable": false, + "returnParameters": { + "id": 7986, + "nodeType": "ParameterList", + "parameters": [], + "src": "15236:0:18" + }, + "scope": 9314, + "src": "15148:394:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 8077, + "nodeType": "Block", + "src": "16753:326:18", + "statements": [ + { + "assignments": [ + 8041 + ], + "declarations": [ + { + "constant": false, + "id": 8041, + "name": "commitment_id", + "nodeType": "VariableDeclaration", + "scope": 8078, + "src": "16764:21:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8040, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "16764:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8051, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8045, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8021, + "src": "16815:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8046, + "name": "answer_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8023, + "src": "16828:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 8047, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "16841:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 8048, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "16841:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 8043, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9703, + "src": "16798:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 8044, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "16798:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 8049, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "16798:53:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 8042, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9710, + "src": "16788:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 8050, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "16788:64:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "16764:88:18" + }, + { + "assignments": [ + 8053 + ], + "declarations": [ + { + "constant": false, + "id": 8053, + "name": "answerer", + "nodeType": "VariableDeclaration", + "scope": 8078, + "src": "16862:16:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8052, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "16862:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8062, + "initialValue": { + "argumentTypes": null, + "condition": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 8056, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8054, + "name": "_answerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8027, + "src": "16882:9:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 8055, + "name": "NULL_ADDRESS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7126, + "src": "16895:12:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "16882:25:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 8057, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "16881:27:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "argumentTypes": null, + "id": 8060, + "name": "_answerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8027, + "src": "16924:9:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 8061, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "16881:52:18", + "trueExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 8058, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "16911:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 8059, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "16911:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "16862:71:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8064, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8021, + "src": "16960:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8065, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8041, + "src": "16973:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 8063, + "name": "_storeCommitment", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8019, + "src": "16943:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$returns$__$", + "typeString": "function (bytes32,bytes32)" + } + }, + "id": 8066, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "16943:44:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8067, + "nodeType": "ExpressionStatement", + "src": "16943:44:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8069, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8021, + "src": "17017:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8070, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8041, + "src": "17030:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8071, + "name": "answerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8053, + "src": "17045:8:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 8072, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "17055:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 8073, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "17055:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "hexValue": "74727565", + "id": 8074, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "17066:4:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 8068, + "name": "_addAnswerToHistory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8235, + "src": "16997:19:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_address_$_t_uint256_$_t_bool_$returns$__$", + "typeString": "function (bytes32,bytes32,address,uint256,bool)" + } + }, + "id": 8075, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "16997:74:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8076, + "nodeType": "ExpressionStatement", + "src": "16997:74:18" + } + ] + }, + "documentation": "@notice Submit the hash of an answer, laying your claim to that answer if you reveal it in a subsequent transaction.\n @dev Creates a hash, commitment_id, uniquely identifying this answer, to this question, with this bond.\n The commitment_id is stored in the answer history where the answer would normally go.\n Does not update the current best answer - this is left to the later submitAnswerReveal() transaction.\n @param question_id The ID of the question\n @param answer_hash The hash of your answer, plus a nonce that you will later reveal\n @param max_previous If specified, reverts if a bond higher than this was submitted after you sent your transaction.\n @param _answerer If specified, the address to be given as the question answerer. Defaults to the sender.\n @dev Specifying the answerer is useful if you want to delegate the commit-and-reveal to a third-party.", + "id": 8078, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 8030, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8021, + "src": "16613:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8031, + "modifierName": { + "argumentTypes": null, + "id": 8029, + "name": "stateOpen", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7407, + "src": "16603:9:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "16603:22:18" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 8033, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8021, + "src": "16649:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8034, + "modifierName": { + "argumentTypes": null, + "id": 8032, + "name": "bondMustDouble", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7519, + "src": "16634:14:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "16634:27:18" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 8036, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8021, + "src": "16705:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8037, + "name": "max_previous", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8025, + "src": "16718:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 8038, + "modifierName": { + "argumentTypes": null, + "id": 8035, + "name": "previousBondMustNotBeatMaxPrevious", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7542, + "src": "16670:34:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$_t_uint256_$", + "typeString": "modifier (bytes32,uint256)" + } + }, + "nodeType": "ModifierInvocation", + "src": "16670:61:18" + } + ], + "name": "submitAnswerCommitment", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8028, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8021, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8078, + "src": "16511:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8020, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "16511:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8023, + "name": "answer_hash", + "nodeType": "VariableDeclaration", + "scope": 8078, + "src": "16532:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8022, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "16532:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8025, + "name": "max_previous", + "nodeType": "VariableDeclaration", + "scope": 8078, + "src": "16553:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8024, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "16553:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8027, + "name": "_answerer", + "nodeType": "VariableDeclaration", + "scope": 8078, + "src": "16575:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8026, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "16575:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "16510:83:18" + }, + "payable": true, + "returnParameters": { + "id": 8039, + "nodeType": "ParameterList", + "parameters": [], + "src": "16753:0:18" + }, + "scope": 9314, + "src": "16479:600:18", + "stateMutability": "payable", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 8175, + "nodeType": "Block", + "src": "18213:746:18", + "statements": [ + { + "assignments": [ + 8093 + ], + "declarations": [ + { + "constant": false, + "id": 8093, + "name": "answer_hash", + "nodeType": "VariableDeclaration", + "scope": 8176, + "src": "18224:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8092, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "18224:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8101, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8097, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8082, + "src": "18273:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8098, + "name": "nonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8084, + "src": "18281:5:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 8095, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9703, + "src": "18256:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 8096, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "18256:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 8099, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18256:31:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 8094, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9710, + "src": "18246:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 8100, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18246:42:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "18224:64:18" + }, + { + "assignments": [ + 8103 + ], + "declarations": [ + { + "constant": false, + "id": 8103, + "name": "commitment_id", + "nodeType": "VariableDeclaration", + "scope": 8176, + "src": "18298:21:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8102, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "18298:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8112, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8107, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8080, + "src": "18349:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8108, + "name": "answer_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8093, + "src": "18362:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8109, + "name": "bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8086, + "src": "18375:4:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 8105, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9703, + "src": "18332:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 8106, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "18332:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 8110, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18332:48:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 8104, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9710, + "src": "18322:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 8111, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18322:59:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "18298:83:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8118, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "18400:39:18", + "subExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8114, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "18401:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 8116, + "indexExpression": { + "argumentTypes": null, + "id": 8115, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8103, + "src": "18413:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "18401:26:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "id": 8117, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "is_revealed", + "nodeType": "MemberAccess", + "referencedDeclaration": 7268, + "src": "18401:38:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "636f6d6d69746d656e74206d757374206e6f742068617665206265656e2072657665616c656420796574", + "id": 8119, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "18441:44:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_6dc39b75299a8c5d94f5d4fe4d23fcb2fa3f298c414cad40577eebdbf4fb5bba", + "typeString": "literal_string \"commitment must not have been revealed yet\"" + }, + "value": "commitment must not have been revealed yet" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_6dc39b75299a8c5d94f5d4fe4d23fcb2fa3f298c414cad40577eebdbf4fb5bba", + "typeString": "literal_string \"commitment must not have been revealed yet\"" + } + ], + "id": 8113, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "18392:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 8120, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18392:94:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8121, + "nodeType": "ExpressionStatement", + "src": "18392:94:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 8130, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8123, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "18504:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 8125, + "indexExpression": { + "argumentTypes": null, + "id": 8124, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8103, + "src": "18516:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "18504:26:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "id": 8126, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "reveal_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7266, + "src": "18504:36:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8128, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "18550:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 8127, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "18543:6:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint32_$", + "typeString": "type(uint32)" + }, + "typeName": "uint32" + }, + "id": 8129, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18543:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "18504:50:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "72657665616c20646561646c696e65206d757374206e6f74206861766520706173736564", + "id": 8131, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "18556:38:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c0aef0f9c54528968b7d0aecff5e54568fd8cfc861f8c854eb9d7453b7f722c0", + "typeString": "literal_string \"reveal deadline must not have passed\"" + }, + "value": "reveal deadline must not have passed" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_c0aef0f9c54528968b7d0aecff5e54568fd8cfc861f8c854eb9d7453b7f722c0", + "typeString": "literal_string \"reveal deadline must not have passed\"" + } + ], + "id": 8122, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "18496:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 8132, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18496:99:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8133, + "nodeType": "ExpressionStatement", + "src": "18496:99:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8139, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8134, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "18606:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 8136, + "indexExpression": { + "argumentTypes": null, + "id": 8135, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8103, + "src": "18618:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "18606:26:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "id": 8137, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "revealed_answer", + "nodeType": "MemberAccess", + "referencedDeclaration": 7270, + "src": "18606:42:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 8138, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8082, + "src": "18651:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "18606:51:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 8140, + "nodeType": "ExpressionStatement", + "src": "18606:51:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8146, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8141, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "18667:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 8143, + "indexExpression": { + "argumentTypes": null, + "id": 8142, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8103, + "src": "18679:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "18667:26:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "id": 8144, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "is_revealed", + "nodeType": "MemberAccess", + "referencedDeclaration": 7268, + "src": "18667:38:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 8145, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "18708:4:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "18667:45:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 8147, + "nodeType": "ExpressionStatement", + "src": "18667:45:18" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 8153, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8148, + "name": "bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8086, + "src": "18727:4:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8149, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "18735:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8151, + "indexExpression": { + "argumentTypes": null, + "id": 8150, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8080, + "src": "18745:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "18735:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8152, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bond", + "nodeType": "MemberAccess", + "referencedDeclaration": 7263, + "src": "18735:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "18727:35:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 8164, + "nodeType": "IfStatement", + "src": "18723:139:18", + "trueBody": { + "id": 8163, + "nodeType": "Block", + "src": "18764:98:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8155, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8080, + "src": "18799:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8156, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8082, + "src": "18812:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8157, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "18820:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8159, + "indexExpression": { + "argumentTypes": null, + "id": 8158, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8080, + "src": "18830:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "18820:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8160, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timeout", + "nodeType": "MemberAccess", + "referencedDeclaration": 7251, + "src": "18820:30:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + ], + "id": 8154, + "name": "_updateCurrentAnswer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8264, + "src": "18778:20:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_uint32_$returns$__$", + "typeString": "function (bytes32,bytes32,uint32)" + } + }, + "id": 8161, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18778:73:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8162, + "nodeType": "ExpressionStatement", + "src": "18778:73:18" + } + ] + } + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8166, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8080, + "src": "18893:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 8167, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "18906:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 8168, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "18906:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 8169, + "name": "answer_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8093, + "src": "18918:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8170, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8082, + "src": "18931:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8171, + "name": "nonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8084, + "src": "18939:5:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 8172, + "name": "bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8086, + "src": "18946:4:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 8165, + "name": "LogAnswerReveal", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7219, + "src": "18877:15:18", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_address_$_t_bytes32_$_t_bytes32_$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (bytes32,address,bytes32,bytes32,uint256,uint256)" + } + }, + "id": 8173, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18877:74:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8174, + "nodeType": "EmitStatement", + "src": "18872:79:18" + } + ] + }, + "documentation": "@notice Submit the answer whose hash you sent in a previous submitAnswerCommitment() transaction\n @dev Checks the parameters supplied recreate an existing commitment, and stores the revealed answer\n Updates the current answer unless someone has since supplied a new answer with a higher bond\n msg.sender is intentionally not restricted to the user who originally sent the commitment; \n For example, the user may want to provide the answer+nonce to a third-party service and let them send the tx\n NB If we are pending arbitration, it will be up to the arbitrator to wait and see any outstanding reveal is sent\n @param question_id The ID of the question\n @param answer The answer, encoded as bytes32\n @param nonce The nonce that, combined with the answer, recreates the answer_hash you gave in submitAnswerCommitment()\n @param bond The bond that you paid in your submitAnswerCommitment() transaction", + "id": 8176, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 8089, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8080, + "src": "18187:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8090, + "modifierName": { + "argumentTypes": null, + "id": 8088, + "name": "stateOpenOrPendingArbitration", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7477, + "src": "18157:29:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "18157:42:18" + } + ], + "name": "submitAnswerReveal", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8087, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8080, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8176, + "src": "18082:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8079, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "18082:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8082, + "name": "answer", + "nodeType": "VariableDeclaration", + "scope": 8176, + "src": "18103:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8081, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "18103:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8084, + "name": "nonce", + "nodeType": "VariableDeclaration", + "scope": 8176, + "src": "18119:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8083, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "18119:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8086, + "name": "bond", + "nodeType": "VariableDeclaration", + "scope": 8176, + "src": "18134:12:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8085, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "18134:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "18081:66:18" + }, + "payable": false, + "returnParameters": { + "id": 8091, + "nodeType": "ParameterList", + "parameters": [], + "src": "18213:0:18" + }, + "scope": 9314, + "src": "18054:905:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 8234, + "nodeType": "Block", + "src": "19119:524:18", + "statements": [ + { + "assignments": [ + 8190 + ], + "declarations": [ + { + "constant": false, + "id": 8190, + "name": "new_history_hash", + "nodeType": "VariableDeclaration", + "scope": 8235, + "src": "19129:24:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8189, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "19129:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8204, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8194, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "19183:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8196, + "indexExpression": { + "argumentTypes": null, + "id": 8195, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8178, + "src": "19193:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "19183:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8197, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "history_hash", + "nodeType": "MemberAccess", + "referencedDeclaration": 7261, + "src": "19183:35:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8198, + "name": "answer_or_commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8180, + "src": "19220:23:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8199, + "name": "bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8184, + "src": "19245:4:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 8200, + "name": "answerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8182, + "src": "19251:8:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 8201, + "name": "is_commitment", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8186, + "src": "19261:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "expression": { + "argumentTypes": null, + "id": 8192, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9703, + "src": "19166:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 8193, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "19166:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 8202, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "19166:109:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 8191, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9710, + "src": "19156:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 8203, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "19156:120:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "19129:147:18" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 8207, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8205, + "name": "bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8184, + "src": "19384:4:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 8206, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19391:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "19384:8:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 8216, + "nodeType": "IfStatement", + "src": "19380:73:18", + "trueBody": { + "id": 8215, + "nodeType": "Block", + "src": "19394:59:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 8213, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8208, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "19408:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8210, + "indexExpression": { + "argumentTypes": null, + "id": 8209, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8178, + "src": "19418:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "19408:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8211, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "bond", + "nodeType": "MemberAccess", + "referencedDeclaration": 7263, + "src": "19408:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 8212, + "name": "bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8184, + "src": "19438:4:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "19408:34:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8214, + "nodeType": "ExpressionStatement", + "src": "19408:34:18" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "id": 8222, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8217, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "19462:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8219, + "indexExpression": { + "argumentTypes": null, + "id": 8218, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8178, + "src": "19472:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "19462:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8220, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "history_hash", + "nodeType": "MemberAccess", + "referencedDeclaration": 7261, + "src": "19462:35:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 8221, + "name": "new_history_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8190, + "src": "19500:16:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "19462:54:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 8223, + "nodeType": "ExpressionStatement", + "src": "19462:54:18" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8225, + "name": "answer_or_commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8180, + "src": "19545:23:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8226, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8178, + "src": "19570:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8227, + "name": "new_history_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8190, + "src": "19583:16:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8228, + "name": "answerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8182, + "src": "19601:8:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 8229, + "name": "bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8184, + "src": "19611:4:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 8230, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "19617:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 8231, + "name": "is_commitment", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8186, + "src": "19622:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 8224, + "name": "LogNewAnswer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7205, + "src": "19532:12:18", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_bytes32_$_t_bytes32_$_t_address_$_t_uint256_$_t_uint256_$_t_bool_$returns$__$", + "typeString": "function (bytes32,bytes32,bytes32,address,uint256,uint256,bool)" + } + }, + "id": 8232, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "19532:104:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8233, + "nodeType": "EmitStatement", + "src": "19527:109:18" + } + ] + }, + "documentation": null, + "id": 8235, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "_addAnswerToHistory", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8187, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8178, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8235, + "src": "18994:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8177, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "18994:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8180, + "name": "answer_or_commitment_id", + "nodeType": "VariableDeclaration", + "scope": 8235, + "src": "19015:31:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8179, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "19015:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8182, + "name": "answerer", + "nodeType": "VariableDeclaration", + "scope": 8235, + "src": "19048:16:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8181, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "19048:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8184, + "name": "bond", + "nodeType": "VariableDeclaration", + "scope": 8235, + "src": "19066:12:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8183, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "19066:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8186, + "name": "is_commitment", + "nodeType": "VariableDeclaration", + "scope": 8235, + "src": "19080:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 8185, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "19080:4:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "18993:106:18" + }, + "payable": false, + "returnParameters": { + "id": 8188, + "nodeType": "ParameterList", + "parameters": [], + "src": "19119:0:18" + }, + "scope": 9314, + "src": "18965:678:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 8263, + "nodeType": "Block", + "src": "19750:136:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 8249, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8244, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "19760:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8246, + "indexExpression": { + "argumentTypes": null, + "id": 8245, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8237, + "src": "19770:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "19760:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8247, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "best_answer", + "nodeType": "MemberAccess", + "referencedDeclaration": 7259, + "src": "19760:34:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 8248, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8239, + "src": "19797:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "19760:43:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 8250, + "nodeType": "ExpressionStatement", + "src": "19760:43:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8261, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8251, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "19813:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8253, + "indexExpression": { + "argumentTypes": null, + "id": 8252, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8237, + "src": "19823:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "19813:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8254, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "finalize_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7253, + "src": "19813:34:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8259, + "name": "timeout_secs", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8241, + "src": "19866:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8256, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "19857:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 8255, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "19850:6:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint32_$", + "typeString": "type(uint32)" + }, + "typeName": "uint32" + }, + "id": 8257, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "19850:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "id": 8258, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 7107, + "src": "19850:15:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint32_$_t_uint32_$returns$_t_uint32_$bound_to$_t_uint32_$", + "typeString": "function (uint32,uint32) pure returns (uint32)" + } + }, + "id": 8260, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "19850:29:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "19813:66:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "id": 8262, + "nodeType": "ExpressionStatement", + "src": "19813:66:18" + } + ] + }, + "documentation": null, + "id": 8264, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "_updateCurrentAnswer", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8242, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8237, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8264, + "src": "19679:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8236, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "19679:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8239, + "name": "answer", + "nodeType": "VariableDeclaration", + "scope": 8264, + "src": "19700:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8238, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "19700:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8241, + "name": "timeout_secs", + "nodeType": "VariableDeclaration", + "scope": 8264, + "src": "19716:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 8240, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "19716:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "19678:58:18" + }, + "payable": false, + "returnParameters": { + "id": 8243, + "nodeType": "ParameterList", + "parameters": [], + "src": "19750:0:18" + }, + "scope": 9314, + "src": "19649:237:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 8305, + "nodeType": "Block", + "src": "20616:257:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 8289, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8284, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "20634:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8286, + "indexExpression": { + "argumentTypes": null, + "id": 8285, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8266, + "src": "20644:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "20634:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8287, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bond", + "nodeType": "MemberAccess", + "referencedDeclaration": 7263, + "src": "20634:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 8288, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "20664:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "20634:31:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "5175657374696f6e206d75737420616c7265616479206861766520616e20616e73776572207768656e206172626974726174696f6e20697320726571756573746564", + "id": 8290, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "20667:68:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_7fdaca9206a1cc3ce5480327eab94eaea78ffd196334cab0e144479eb0ad45d4", + "typeString": "literal_string \"Question must already have an answer when arbitration is requested\"" + }, + "value": "Question must already have an answer when arbitration is requested" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_7fdaca9206a1cc3ce5480327eab94eaea78ffd196334cab0e144479eb0ad45d4", + "typeString": "literal_string \"Question must already have an answer when arbitration is requested\"" + } + ], + "id": 8283, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "20626:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 8291, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "20626:110:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8292, + "nodeType": "ExpressionStatement", + "src": "20626:110:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8298, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8293, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "20746:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8295, + "indexExpression": { + "argumentTypes": null, + "id": 8294, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8266, + "src": "20756:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "20746:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8296, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "is_pending_arbitration", + "nodeType": "MemberAccess", + "referencedDeclaration": 7255, + "src": "20746:45:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 8297, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "20794:4:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "20746:52:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 8299, + "nodeType": "ExpressionStatement", + "src": "20746:52:18" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8301, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8266, + "src": "20843:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8302, + "name": "requester", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8268, + "src": "20856:9:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 8300, + "name": "LogNotifyOfArbitrationRequest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7225, + "src": "20813:29:18", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_address_$returns$__$", + "typeString": "function (bytes32,address)" + } + }, + "id": 8303, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "20813:53:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8304, + "nodeType": "EmitStatement", + "src": "20808:58:18" + } + ] + }, + "documentation": "@notice Notify the contract that the arbitrator has been paid for a question, freezing it pending their decision.\n @dev The arbitrator contract is trusted to only call this if they've been paid, and tell us who paid them.\n @param question_id The ID of the question\n @param requester The account that requested arbitration\n @param max_previous If specified, reverts if a bond higher than this was submitted after you sent your transaction.", + "id": 8306, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 8273, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8266, + "src": "20489:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8274, + "modifierName": { + "argumentTypes": null, + "id": 8272, + "name": "onlyArbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7322, + "src": "20474:14:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "20474:27:18" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 8276, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8266, + "src": "20520:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8277, + "modifierName": { + "argumentTypes": null, + "id": 8275, + "name": "stateOpen", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7407, + "src": "20510:9:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "20510:22:18" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 8279, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8266, + "src": "20576:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8280, + "name": "max_previous", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8270, + "src": "20589:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 8281, + "modifierName": { + "argumentTypes": null, + "id": 8278, + "name": "previousBondMustNotBeatMaxPrevious", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7542, + "src": "20541:34:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$_t_uint256_$", + "typeString": "modifier (bytes32,uint256)" + } + }, + "nodeType": "ModifierInvocation", + "src": "20541:61:18" + } + ], + "name": "notifyOfArbitrationRequest", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8271, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8266, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8306, + "src": "20403:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8265, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "20403:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8268, + "name": "requester", + "nodeType": "VariableDeclaration", + "scope": 8306, + "src": "20424:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8267, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "20424:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8270, + "name": "max_previous", + "nodeType": "VariableDeclaration", + "scope": 8306, + "src": "20443:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8269, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "20443:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "20402:62:18" + }, + "payable": false, + "returnParameters": { + "id": 8282, + "nodeType": "ParameterList", + "parameters": [], + "src": "20616:0:18" + }, + "scope": 9314, + "src": "20367:506:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 8343, + "nodeType": "Block", + "src": "21245:212:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 8322, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8317, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "21255:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8319, + "indexExpression": { + "argumentTypes": null, + "id": 8318, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8308, + "src": "21265:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "21255:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8320, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "is_pending_arbitration", + "nodeType": "MemberAccess", + "referencedDeclaration": 7255, + "src": "21255:45:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 8321, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "21303:5:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "src": "21255:53:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 8323, + "nodeType": "ExpressionStatement", + "src": "21255:53:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8337, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8324, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "21318:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8326, + "indexExpression": { + "argumentTypes": null, + "id": 8325, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8308, + "src": "21328:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "21318:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8327, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "finalize_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7253, + "src": "21318:34:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8332, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "21371:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8334, + "indexExpression": { + "argumentTypes": null, + "id": 8333, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8308, + "src": "21381:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "21371:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8335, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timeout", + "nodeType": "MemberAccess", + "referencedDeclaration": 7251, + "src": "21371:30:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8329, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "21362:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 8328, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "21355:6:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint32_$", + "typeString": "type(uint32)" + }, + "typeName": "uint32" + }, + "id": 8330, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21355:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "id": 8331, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 7107, + "src": "21355:15:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint32_$_t_uint32_$returns$_t_uint32_$bound_to$_t_uint32_$", + "typeString": "function (uint32,uint32) pure returns (uint32)" + } + }, + "id": 8336, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21355:47:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "21318:84:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "id": 8338, + "nodeType": "ExpressionStatement", + "src": "21318:84:18" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8340, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8308, + "src": "21438:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 8339, + "name": "LogCancelArbitration", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7229, + "src": "21417:20:18", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$returns$__$", + "typeString": "function (bytes32)" + } + }, + "id": 8341, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21417:33:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8342, + "nodeType": "EmitStatement", + "src": "21412:38:18" + } + ] + }, + "documentation": "@notice Cancel a previously-requested arbitration and extend the timeout\n @dev Useful when doing arbitration across chains that can't be requested atomically\n @param question_id The ID of the question", + "id": 8344, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 8311, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8308, + "src": "21174:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8312, + "modifierName": { + "argumentTypes": null, + "id": 8310, + "name": "onlyArbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7322, + "src": "21159:14:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "21159:27:18" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 8314, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8308, + "src": "21219:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8315, + "modifierName": { + "argumentTypes": null, + "id": 8313, + "name": "statePendingArbitration", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7421, + "src": "21195:23:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "21195:36:18" + } + ], + "name": "cancelArbitration", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8309, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8308, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8344, + "src": "21129:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8307, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "21129:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "21128:21:18" + }, + "payable": false, + "returnParameters": { + "id": 8316, + "nodeType": "ParameterList", + "parameters": [], + "src": "21245:0:18" + }, + "scope": 9314, + "src": "21102:355:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 8392, + "nodeType": "Block", + "src": "22235:316:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 8362, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8360, + "name": "answerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8350, + "src": "22254:8:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "id": 8361, + "name": "NULL_ADDRESS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7126, + "src": "22266:12:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "22254:24:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "616e737765726572206d7573742062652070726f7669646564", + "id": 8363, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "22280:27:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_b2034904ed959e3f06daceb4dada259b4f13c4f11a1b4edcc62492a9fc76ce84", + "typeString": "literal_string \"answerer must be provided\"" + }, + "value": "answerer must be provided" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_b2034904ed959e3f06daceb4dada259b4f13c4f11a1b4edcc62492a9fc76ce84", + "typeString": "literal_string \"answerer must be provided\"" + } + ], + "id": 8359, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "22246:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 8364, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "22246:62:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8365, + "nodeType": "ExpressionStatement", + "src": "22246:62:18" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8367, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8346, + "src": "22335:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8368, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8348, + "src": "22348:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 8366, + "name": "LogFinalize", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7235, + "src": "22323:11:18", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_bytes32_$returns$__$", + "typeString": "function (bytes32,bytes32)" + } + }, + "id": 8369, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "22323:32:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8370, + "nodeType": "EmitStatement", + "src": "22318:37:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8376, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8371, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "22366:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8373, + "indexExpression": { + "argumentTypes": null, + "id": 8372, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8346, + "src": "22376:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "22366:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8374, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "is_pending_arbitration", + "nodeType": "MemberAccess", + "referencedDeclaration": 7255, + "src": "22366:45:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 8375, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "22414:5:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "src": "22366:53:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 8377, + "nodeType": "ExpressionStatement", + "src": "22366:53:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8379, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8346, + "src": "22449:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8380, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8348, + "src": "22462:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8381, + "name": "answerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8350, + "src": "22470:8:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "hexValue": "30", + "id": 8382, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "22480:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 8383, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "22483:5:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 8378, + "name": "_addAnswerToHistory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8235, + "src": "22429:19:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_address_$_t_uint256_$_t_bool_$returns$__$", + "typeString": "function (bytes32,bytes32,address,uint256,bool)" + } + }, + "id": 8384, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "22429:60:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8385, + "nodeType": "ExpressionStatement", + "src": "22429:60:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8387, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8346, + "src": "22520:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8388, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8348, + "src": "22533:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "hexValue": "30", + "id": 8389, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "22541:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 8386, + "name": "_updateCurrentAnswer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8264, + "src": "22499:20:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_uint32_$returns$__$", + "typeString": "function (bytes32,bytes32,uint32)" + } + }, + "id": 8390, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "22499:44:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8391, + "nodeType": "ExpressionStatement", + "src": "22499:44:18" + } + ] + }, + "documentation": "@notice Submit the answer for a question, for use by the arbitrator.\n @dev Doesn't require (or allow) a bond.\n If the current final answer is correct, the account should be whoever submitted it.\n If the current final answer is wrong, the account should be whoever paid for arbitration.\n However, the answerer stipulations are not enforced by the contract.\n @param question_id The ID of the question\n @param answer The answer, encoded into bytes32\n @param answerer The account credited with this answer for the purpose of bond claims", + "id": 8393, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 8353, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8346, + "src": "22166:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8354, + "modifierName": { + "argumentTypes": null, + "id": 8352, + "name": "onlyArbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7322, + "src": "22151:14:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "22151:27:18" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 8356, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8346, + "src": "22211:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8357, + "modifierName": { + "argumentTypes": null, + "id": 8355, + "name": "statePendingArbitration", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7421, + "src": "22187:23:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "22187:36:18" + } + ], + "name": "submitAnswerByArbitrator", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8351, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8346, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8393, + "src": "22087:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8345, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "22087:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8348, + "name": "answer", + "nodeType": "VariableDeclaration", + "scope": 8393, + "src": "22108:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8347, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "22108:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8350, + "name": "answerer", + "nodeType": "VariableDeclaration", + "scope": 8393, + "src": "22124:16:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8349, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "22124:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "22086:55:18" + }, + "payable": false, + "returnParameters": { + "id": 8358, + "nodeType": "ParameterList", + "parameters": [], + "src": "22235:0:18" + }, + "scope": 9314, + "src": "22053:498:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 8472, + "nodeType": "Block", + "src": "23469:867:18", + "statements": [ + { + "assignments": [ + 8409 + ], + "declarations": [ + { + "constant": false, + "id": 8409, + "name": "is_commitment", + "nodeType": "VariableDeclaration", + "scope": 8473, + "src": "23479:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 8408, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "23479:4:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8423, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8411, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "23528:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8413, + "indexExpression": { + "argumentTypes": null, + "id": 8412, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8395, + "src": "23538:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "23528:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8414, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "history_hash", + "nodeType": "MemberAccess", + "referencedDeclaration": 7261, + "src": "23528:35:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8415, + "name": "last_history_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8401, + "src": "23565:17:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8416, + "name": "last_answer_or_commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8403, + "src": "23584:28:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8417, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "23614:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8419, + "indexExpression": { + "argumentTypes": null, + "id": 8418, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8395, + "src": "23624:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "23614:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8420, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bond", + "nodeType": "MemberAccess", + "referencedDeclaration": 7263, + "src": "23614:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 8421, + "name": "last_answerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8405, + "src": "23643:13:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 8410, + "name": "_verifyHistoryInputOrRevert", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8900, + "src": "23500:27:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes32_$_t_bytes32_$_t_bytes32_$_t_uint256_$_t_address_$returns$_t_bool_$", + "typeString": "function (bytes32,bytes32,bytes32,uint256,address) pure returns (bool)" + } + }, + "id": 8422, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "23500:157:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "23479:178:18" + }, + { + "assignments": [], + "declarations": [ + { + "constant": false, + "id": 8425, + "name": "payee", + "nodeType": "VariableDeclaration", + "scope": 8473, + "src": "23668:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8424, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "23668:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8426, + "initialValue": null, + "nodeType": "VariableDeclarationStatement", + "src": "23668:13:18" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 8433, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8427, + "name": "is_commitment", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8409, + "src": "23883:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "id": 8432, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "23900:54:18", + "subExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8428, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "23901:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 8430, + "indexExpression": { + "argumentTypes": null, + "id": 8429, + "name": "last_answer_or_commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8403, + "src": "23913:28:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "23901:41:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "id": 8431, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "is_revealed", + "nodeType": "MemberAccess", + "referencedDeclaration": 7268, + "src": "23901:53:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "23883:71:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 8464, + "nodeType": "Block", + "src": "24156:112:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 8462, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 8451, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8425, + "src": "24170:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "condition": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 8457, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8452, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "24179:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8454, + "indexExpression": { + "argumentTypes": null, + "id": 8453, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8395, + "src": "24189:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "24179:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8455, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "best_answer", + "nodeType": "MemberAccess", + "referencedDeclaration": 7259, + "src": "24179:34:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 8456, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8397, + "src": "24217:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "24179:44:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 8458, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "24178:46:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "argumentTypes": null, + "id": 8460, + "name": "payee_if_wrong", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8399, + "src": "24243:14:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 8461, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "24178:79:18", + "trueExpression": { + "argumentTypes": null, + "id": 8459, + "name": "last_answerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8405, + "src": "24227:13:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "24170:87:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 8463, + "nodeType": "ExpressionStatement", + "src": "24170:87:18" + } + ] + }, + "id": 8465, + "nodeType": "IfStatement", + "src": "23879:389:18", + "trueBody": { + "id": 8450, + "nodeType": "Block", + "src": "23956:194:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 8442, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8435, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "23978:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 8437, + "indexExpression": { + "argumentTypes": null, + "id": 8436, + "name": "last_answer_or_commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8403, + "src": "23990:28:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "23978:41:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "id": 8438, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "reveal_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7266, + "src": "23978:51:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8440, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "24039:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 8439, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "24032:6:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint32_$", + "typeString": "type(uint32)" + }, + "typeName": "uint32" + }, + "id": 8441, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24032:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "23978:65:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "596f75206d757374207761697420666f72207468652072657665616c20646561646c696e65206265666f72652066696e616c697a696e67", + "id": 8443, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "24045:57:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_59906a33bbcf0bc176ce61cc097b3e9182f12a3fed11d73df0b39558e782f100", + "typeString": "literal_string \"You must wait for the reveal deadline before finalizing\"" + }, + "value": "You must wait for the reveal deadline before finalizing" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_59906a33bbcf0bc176ce61cc097b3e9182f12a3fed11d73df0b39558e782f100", + "typeString": "literal_string \"You must wait for the reveal deadline before finalizing\"" + } + ], + "id": 8434, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "23970:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 8444, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "23970:133:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8445, + "nodeType": "ExpressionStatement", + "src": "23970:133:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8448, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 8446, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8425, + "src": "24117:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 8447, + "name": "payee_if_wrong", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8399, + "src": "24125:14:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "24117:22:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 8449, + "nodeType": "ExpressionStatement", + "src": "24117:22:18" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8467, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8395, + "src": "24302:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8468, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8397, + "src": "24315:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8469, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8425, + "src": "24323:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 8466, + "name": "submitAnswerByArbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8393, + "src": "24277:24:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_address_$returns$__$", + "typeString": "function (bytes32,bytes32,address)" + } + }, + "id": 8470, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24277:52:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8471, + "nodeType": "ExpressionStatement", + "src": "24277:52:18" + } + ] + }, + "documentation": "@notice Submit the answer for a question, for use by the arbitrator, working out the appropriate winner based on the last answer details.\n @dev Doesn't require (or allow) a bond.\n @param question_id The ID of the question\n @param answer The answer, encoded into bytes32\n @param payee_if_wrong The account to by credited as winner if the last answer given is wrong, usually the account that paid the arbitrator\n @param last_history_hash The history hash before the final one\n @param last_answer_or_commitment_id The last answer given, or the commitment ID if it was a commitment.\n @param last_answerer The address that supplied the last answer", + "id": 8473, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "assignWinnerAndSubmitAnswerByArbitrator", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8406, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8395, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8473, + "src": "23306:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8394, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "23306:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8397, + "name": "answer", + "nodeType": "VariableDeclaration", + "scope": 8473, + "src": "23327:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8396, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "23327:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8399, + "name": "payee_if_wrong", + "nodeType": "VariableDeclaration", + "scope": 8473, + "src": "23343:22:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8398, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "23343:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8401, + "name": "last_history_hash", + "nodeType": "VariableDeclaration", + "scope": 8473, + "src": "23367:25:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8400, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "23367:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8403, + "name": "last_answer_or_commitment_id", + "nodeType": "VariableDeclaration", + "scope": 8473, + "src": "23394:36:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8402, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "23394:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8405, + "name": "last_answerer", + "nodeType": "VariableDeclaration", + "scope": 8473, + "src": "23432:21:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8404, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "23432:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "23305:149:18" + }, + "payable": false, + "returnParameters": { + "id": 8407, + "nodeType": "ParameterList", + "parameters": [], + "src": "23469:0:18" + }, + "scope": 9314, + "src": "23257:1079:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 8506, + "nodeType": "Block", + "src": "24589:201:18", + "statements": [ + { + "assignments": [ + 8481 + ], + "declarations": [ + { + "constant": false, + "id": 8481, + "name": "finalize_ts", + "nodeType": "VariableDeclaration", + "scope": 8507, + "src": "24599:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 8480, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "24599:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8486, + "initialValue": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8482, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "24620:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8484, + "indexExpression": { + "argumentTypes": null, + "id": 8483, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8475, + "src": "24630:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "24620:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8485, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "finalize_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7253, + "src": "24620:34:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "24599:55:18" + }, + { + "expression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 8503, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 8496, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8491, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "24673:46:18", + "subExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8487, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "24674:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8489, + "indexExpression": { + "argumentTypes": null, + "id": 8488, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8475, + "src": "24684:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "24674:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8490, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "is_pending_arbitration", + "nodeType": "MemberAccess", + "referencedDeclaration": 7255, + "src": "24674:45:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 8494, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8492, + "name": "finalize_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8481, + "src": "24724:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "id": 8493, + "name": "UNANSWERED", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7134, + "src": "24738:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "24724:24:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 8495, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "24723:26:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "24673:76:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 8501, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8497, + "name": "finalize_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8481, + "src": "24754:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8499, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "24776:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 8498, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "24769:6:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint32_$", + "typeString": "type(uint32)" + }, + "typeName": "uint32" + }, + "id": 8500, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24769:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "24754:26:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 8502, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "24753:28:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "24673:108:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 8504, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "24671:112:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "functionReturnParameters": 8479, + "id": 8505, + "nodeType": "Return", + "src": "24664:119:18" + } + ] + }, + "documentation": "@notice Report whether the answer to the specified question is finalized\n @param question_id The ID of the question\n @return Return true if finalized", + "id": 8507, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "isFinalized", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8476, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8475, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8507, + "src": "24536:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8474, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "24536:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "24535:21:18" + }, + "payable": false, + "returnParameters": { + "id": 8479, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8478, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 8507, + "src": "24583:4:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 8477, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "24583:4:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "24582:6:18" + }, + "scope": 9314, + "src": "24515:275:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 8522, + "nodeType": "Block", + "src": "25123:58:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8517, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "25140:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8519, + "indexExpression": { + "argumentTypes": null, + "id": 8518, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8509, + "src": "25150:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "25140:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8520, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "best_answer", + "nodeType": "MemberAccess", + "referencedDeclaration": 7259, + "src": "25140:34:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 8516, + "id": 8521, + "nodeType": "Return", + "src": "25133:41:18" + } + ] + }, + "documentation": "@notice (Deprecated) Return the final answer to the specified question, or revert if there isn't one\n @param question_id The ID of the question\n @return The answer formatted as a bytes32", + "id": 8523, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 8512, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8509, + "src": "25074:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8513, + "modifierName": { + "argumentTypes": null, + "id": 8511, + "name": "stateFinalized", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7490, + "src": "25059:14:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "25059:27:18" + } + ], + "name": "getFinalAnswer", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8510, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8509, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8523, + "src": "25029:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8508, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "25029:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "25028:21:18" + }, + "payable": false, + "returnParameters": { + "id": 8516, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8515, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 8523, + "src": "25114:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8514, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "25114:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "25113:9:18" + }, + "scope": 9314, + "src": "25005:176:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 8538, + "nodeType": "Block", + "src": "25496:58:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8533, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "25513:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8535, + "indexExpression": { + "argumentTypes": null, + "id": 8534, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8525, + "src": "25523:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "25513:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8536, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "best_answer", + "nodeType": "MemberAccess", + "referencedDeclaration": 7259, + "src": "25513:34:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 8532, + "id": 8537, + "nodeType": "Return", + "src": "25506:41:18" + } + ] + }, + "documentation": "@notice Return the final answer to the specified question, or revert if there isn't one\n @param question_id The ID of the question\n @return The answer formatted as a bytes32", + "id": 8539, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 8528, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8525, + "src": "25447:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8529, + "modifierName": { + "argumentTypes": null, + "id": 8527, + "name": "stateFinalized", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7490, + "src": "25432:14:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "25432:27:18" + } + ], + "name": "resultFor", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8526, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8525, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8539, + "src": "25402:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8524, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "25402:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "25401:21:18" + }, + "payable": false, + "returnParameters": { + "id": 8532, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8531, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 8539, + "src": "25487:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8530, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "25487:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "25486:9:18" + }, + "scope": 9314, + "src": "25383:171:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 8602, + "nodeType": "Block", + "src": "26532:427:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 8563, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8558, + "name": "content_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8543, + "src": "26550:12:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8559, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "26566:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8561, + "indexExpression": { + "argumentTypes": null, + "id": 8560, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8541, + "src": "26576:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "26566:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8562, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "content_hash", + "nodeType": "MemberAccess", + "referencedDeclaration": 7245, + "src": "26566:35:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "26550:51:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "636f6e74656e742068617368206d757374206d61746368", + "id": 8564, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26603:25:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_1ab4f91b91ff887ba4101461ee7fdff8a9550df020c832d7174034a04b833c71", + "typeString": "literal_string \"content hash must match\"" + }, + "value": "content hash must match" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_1ab4f91b91ff887ba4101461ee7fdff8a9550df020c832d7174034a04b833c71", + "typeString": "literal_string \"content hash must match\"" + } + ], + "id": 8557, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "26542:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 8565, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "26542:87:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8566, + "nodeType": "ExpressionStatement", + "src": "26542:87:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 8573, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8568, + "name": "arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8545, + "src": "26647:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8569, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "26661:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8571, + "indexExpression": { + "argumentTypes": null, + "id": 8570, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8541, + "src": "26671:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "26661:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8572, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "arbitrator", + "nodeType": "MemberAccess", + "referencedDeclaration": 7247, + "src": "26661:33:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "26647:47:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "61726269747261746f72206d757374206d61746368", + "id": 8574, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26696:23:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_e14333e0b7159d63d81a1f747c3418d619023485dd483dee8ea5dfb57b0ff723", + "typeString": "literal_string \"arbitrator must match\"" + }, + "value": "arbitrator must match" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_e14333e0b7159d63d81a1f747c3418d619023485dd483dee8ea5dfb57b0ff723", + "typeString": "literal_string \"arbitrator must match\"" + } + ], + "id": 8567, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "26639:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 8575, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "26639:81:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8576, + "nodeType": "ExpressionStatement", + "src": "26639:81:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 8583, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8578, + "name": "min_timeout", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8547, + "src": "26738:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8579, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "26753:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8581, + "indexExpression": { + "argumentTypes": null, + "id": 8580, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8541, + "src": "26763:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "26753:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8582, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timeout", + "nodeType": "MemberAccess", + "referencedDeclaration": 7251, + "src": "26753:30:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "26738:45:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "74696d656f7574206d757374206265206c6f6e6720656e6f756768", + "id": 8584, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26785:29:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_cc60de11d8ba89bb648c5bc8147e6f8669fe77735adef82b63fc28eef3d7dfeb", + "typeString": "literal_string \"timeout must be long enough\"" + }, + "value": "timeout must be long enough" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_cc60de11d8ba89bb648c5bc8147e6f8669fe77735adef82b63fc28eef3d7dfeb", + "typeString": "literal_string \"timeout must be long enough\"" + } + ], + "id": 8577, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "26730:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 8585, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "26730:85:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8586, + "nodeType": "ExpressionStatement", + "src": "26730:85:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 8593, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8588, + "name": "min_bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8549, + "src": "26833:8:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8589, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "26845:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8591, + "indexExpression": { + "argumentTypes": null, + "id": 8590, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8541, + "src": "26855:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "26845:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8592, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bond", + "nodeType": "MemberAccess", + "referencedDeclaration": 7263, + "src": "26845:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "26833:39:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "626f6e64206d757374206265206869676820656e6f756768", + "id": 8594, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26874:26:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_4fbe9b5254b5b7c01e42aaadc74b327644dc528a9916fa76193407d46b5c0951", + "typeString": "literal_string \"bond must be high enough\"" + }, + "value": "bond must be high enough" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_4fbe9b5254b5b7c01e42aaadc74b327644dc528a9916fa76193407d46b5c0951", + "typeString": "literal_string \"bond must be high enough\"" + } + ], + "id": 8587, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "26825:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 8595, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "26825:76:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8596, + "nodeType": "ExpressionStatement", + "src": "26825:76:18" + }, + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8597, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "26918:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8599, + "indexExpression": { + "argumentTypes": null, + "id": 8598, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8541, + "src": "26928:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "26918:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8600, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "best_answer", + "nodeType": "MemberAccess", + "referencedDeclaration": 7259, + "src": "26918:34:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 8556, + "id": 8601, + "nodeType": "Return", + "src": "26911:41:18" + } + ] + }, + "documentation": "@notice Return the final answer to the specified question, provided it matches the specified criteria.\n @dev Reverts if the question is not finalized, or if it does not match the specified criteria.\n @param question_id The ID of the question\n @param content_hash The hash of the question content (template ID + opening time + question parameter string)\n @param arbitrator The arbitrator chosen for the question (regardless of whether they are asked to arbitrate)\n @param min_timeout The timeout set in the initial question settings must be this high or higher\n @param min_bond The bond sent with the final answer must be this high or higher\n @return The answer formatted as a bytes32", + "id": 8603, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 8552, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8541, + "src": "26483:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8553, + "modifierName": { + "argumentTypes": null, + "id": 8551, + "name": "stateFinalized", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7490, + "src": "26468:14:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "26468:27:18" + } + ], + "name": "getFinalAnswerIfMatches", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8550, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8541, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8603, + "src": "26344:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8540, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "26344:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8543, + "name": "content_hash", + "nodeType": "VariableDeclaration", + "scope": 8603, + "src": "26374:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8542, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "26374:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8545, + "name": "arbitrator", + "nodeType": "VariableDeclaration", + "scope": 8603, + "src": "26396:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8544, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "26396:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8547, + "name": "min_timeout", + "nodeType": "VariableDeclaration", + "scope": 8603, + "src": "26416:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 8546, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "26416:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8549, + "name": "min_bond", + "nodeType": "VariableDeclaration", + "scope": 8603, + "src": "26436:16:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8548, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "26436:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "26334:124:18" + }, + "payable": false, + "returnParameters": { + "id": 8556, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8555, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 8603, + "src": "26523:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8554, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "26523:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "26522:9:18" + }, + "scope": 9314, + "src": "26302:657:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 8820, + "nodeType": "Block", + "src": "28471:2958:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 8627, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 8624, + "name": "history_hashes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8608, + "src": "28490:14:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 8625, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "28490:21:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 8626, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "28514:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "28490:25:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "6174206c65617374206f6e6520686973746f7279206861736820656e747279206d7573742062652070726f7669646564", + "id": 8628, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "28517:50:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_e887b9c35a99bf27d861fac479e37f4d87d4bceab6db3e0e5edcbd73f35992ed", + "typeString": "literal_string \"at least one history hash entry must be provided\"" + }, + "value": "at least one history hash entry must be provided" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_e887b9c35a99bf27d861fac479e37f4d87d4bceab6db3e0e5edcbd73f35992ed", + "typeString": "literal_string \"at least one history hash entry must be provided\"" + } + ], + "id": 8623, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "28482:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 8629, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "28482:86:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8630, + "nodeType": "ExpressionStatement", + "src": "28482:86:18" + }, + { + "assignments": [ + 8632 + ], + "declarations": [ + { + "constant": false, + "id": 8632, + "name": "payee", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "28659:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8631, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "28659:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8637, + "initialValue": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8633, + "name": "question_claims", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7297, + "src": "28675:15:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Claim_$7278_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Claim storage ref)" + } + }, + "id": 8635, + "indexExpression": { + "argumentTypes": null, + "id": 8634, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "28691:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "28675:28:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Claim_$7278_storage", + "typeString": "struct Realitio_v2_1.Claim storage ref" + } + }, + "id": 8636, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "payee", + "nodeType": "MemberAccess", + "referencedDeclaration": 7273, + "src": "28675:34:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "28659:50:18" + }, + { + "assignments": [ + 8639 + ], + "declarations": [ + { + "constant": false, + "id": 8639, + "name": "last_bond", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "28720:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8638, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "28720:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8644, + "initialValue": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8640, + "name": "question_claims", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7297, + "src": "28740:15:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Claim_$7278_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Claim storage ref)" + } + }, + "id": 8642, + "indexExpression": { + "argumentTypes": null, + "id": 8641, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "28756:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "28740:28:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Claim_$7278_storage", + "typeString": "struct Realitio_v2_1.Claim storage ref" + } + }, + "id": 8643, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "last_bond", + "nodeType": "MemberAccess", + "referencedDeclaration": 7275, + "src": "28740:38:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "28720:58:18" + }, + { + "assignments": [ + 8646 + ], + "declarations": [ + { + "constant": false, + "id": 8646, + "name": "queued_funds", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "28789:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8645, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "28789:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8651, + "initialValue": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8647, + "name": "question_claims", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7297, + "src": "28812:15:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Claim_$7278_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Claim storage ref)" + } + }, + "id": 8649, + "indexExpression": { + "argumentTypes": null, + "id": 8648, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "28828:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "28812:28:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Claim_$7278_storage", + "typeString": "struct Realitio_v2_1.Claim storage ref" + } + }, + "id": 8650, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "queued_funds", + "nodeType": "MemberAccess", + "referencedDeclaration": 7277, + "src": "28812:41:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "28789:64:18" + }, + { + "assignments": [ + 8653 + ], + "declarations": [ + { + "constant": false, + "id": 8653, + "name": "last_history_hash", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "29074:25:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8652, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "29074:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8658, + "initialValue": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8654, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "29102:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8656, + "indexExpression": { + "argumentTypes": null, + "id": 8655, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "29112:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "29102:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8657, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "history_hash", + "nodeType": "MemberAccess", + "referencedDeclaration": 7261, + "src": "29102:35:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "29074:63:18" + }, + { + "assignments": [ + 8660 + ], + "declarations": [ + { + "constant": false, + "id": 8660, + "name": "best_answer", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "29148:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8659, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "29148:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8665, + "initialValue": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8661, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "29170:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8663, + "indexExpression": { + "argumentTypes": null, + "id": 8662, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "29180:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "29170:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8664, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "best_answer", + "nodeType": "MemberAccess", + "referencedDeclaration": 7259, + "src": "29170:34:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "29148:56:18" + }, + { + "assignments": [], + "declarations": [ + { + "constant": false, + "id": 8667, + "name": "i", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "29215:9:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8666, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "29215:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8668, + "initialValue": null, + "nodeType": "VariableDeclarationStatement", + "src": "29215:9:18" + }, + { + "body": { + "id": 8755, + "nodeType": "Block", + "src": "29278:1075:18", + "statements": [ + { + "assignments": [ + 8681 + ], + "declarations": [ + { + "constant": false, + "id": 8681, + "name": "is_commitment", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "29412:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 8680, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "29412:4:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8697, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8683, + "name": "last_history_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8653, + "src": "29461:17:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8684, + "name": "history_hashes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8608, + "src": "29480:14:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 8686, + "indexExpression": { + "argumentTypes": null, + "id": 8685, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "29495:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "29480:17:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8687, + "name": "answers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8617, + "src": "29499:7:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 8689, + "indexExpression": { + "argumentTypes": null, + "id": 8688, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "29507:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "29499:10:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8690, + "name": "bonds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8614, + "src": "29511:5:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 8692, + "indexExpression": { + "argumentTypes": null, + "id": 8691, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "29517:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "29511:8:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8693, + "name": "addrs", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8611, + "src": "29521:5:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + "id": 8695, + "indexExpression": { + "argumentTypes": null, + "id": 8694, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "29527:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "29521:8:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 8682, + "name": "_verifyHistoryInputOrRevert", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8900, + "src": "29433:27:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes32_$_t_bytes32_$_t_bytes32_$_t_uint256_$_t_address_$returns$_t_bool_$", + "typeString": "function (bytes32,bytes32,bytes32,uint256,address) pure returns (bool)" + } + }, + "id": 8696, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "29433:97:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "29412:118:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8703, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 8698, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8646, + "src": "29557:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8701, + "name": "last_bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8639, + "src": "29589:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 8699, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8646, + "src": "29572:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8700, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 7080, + "src": "29572:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 8702, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "29572:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "29557:42:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8704, + "nodeType": "ExpressionStatement", + "src": "29557:42:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8724, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "id": 8705, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8646, + "src": "29615:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 8706, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8632, + "src": "29629:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "id": 8707, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "29614:21:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_address_$", + "typeString": "tuple(uint256,address)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8709, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "29675:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8710, + "name": "best_answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8660, + "src": "29688:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8711, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8646, + "src": "29701:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 8712, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8632, + "src": "29715:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8713, + "name": "addrs", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8611, + "src": "29739:5:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + "id": 8715, + "indexExpression": { + "argumentTypes": null, + "id": 8714, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "29745:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "29739:8:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8716, + "name": "bonds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8614, + "src": "29749:5:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 8718, + "indexExpression": { + "argumentTypes": null, + "id": 8717, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "29755:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "29749:8:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8719, + "name": "answers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8617, + "src": "29759:7:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 8721, + "indexExpression": { + "argumentTypes": null, + "id": 8720, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "29767:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "29759:10:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8722, + "name": "is_commitment", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8681, + "src": "29771:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 8708, + "name": "_processHistoryItem", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9027, + "src": "29638:19:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_uint256_$_t_address_$_t_address_$_t_uint256_$_t_bytes32_$_t_bool_$returns$_t_uint256_$_t_address_$", + "typeString": "function (bytes32,bytes32,uint256,address,address,uint256,bytes32,bool) returns (uint256,address)" + } + }, + "id": 8723, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "29638:147:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_address_$", + "typeString": "tuple(uint256,address)" + } + }, + "src": "29614:171:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8725, + "nodeType": "ExpressionStatement", + "src": "29614:171:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8730, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 8726, + "name": "last_bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8639, + "src": "29897:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8727, + "name": "bonds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8614, + "src": "29909:5:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 8729, + "indexExpression": { + "argumentTypes": null, + "id": 8728, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "29915:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "29909:8:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "29897:20:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8731, + "nodeType": "ExpressionStatement", + "src": "29897:20:18" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 8737, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8732, + "name": "last_bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8639, + "src": "30151:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8733, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "30164:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8735, + "indexExpression": { + "argumentTypes": null, + "id": 8734, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "30174:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "30164:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8736, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bond", + "nodeType": "MemberAccess", + "referencedDeclaration": 7263, + "src": "30164:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "30151:40:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 8748, + "nodeType": "IfStatement", + "src": "30147:143:18", + "trueBody": { + "id": 8747, + "nodeType": "Block", + "src": "30193:97:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 8745, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 8738, + "name": "last_bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8639, + "src": "30211:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 8743, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8741, + "name": "last_bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8639, + "src": "30237:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "/", + "rightExpression": { + "argumentTypes": null, + "id": 8742, + "name": "BOND_CLAIM_FEE_PROPORTION", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7143, + "src": "30249:25:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "30237:37:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 8739, + "name": "last_bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8639, + "src": "30223:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8740, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sub", + "nodeType": "MemberAccess", + "referencedDeclaration": 7056, + "src": "30223:13:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 8744, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "30223:52:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "30211:64:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8746, + "nodeType": "ExpressionStatement", + "src": "30211:64:18" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "id": 8753, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 8749, + "name": "last_history_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8653, + "src": "30304:17:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8750, + "name": "history_hashes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8608, + "src": "30324:14:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 8752, + "indexExpression": { + "argumentTypes": null, + "id": 8751, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "30339:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "30324:17:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "30304:37:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 8754, + "nodeType": "ExpressionStatement", + "src": "30304:37:18" + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 8676, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8673, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "29246:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 8674, + "name": "history_hashes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8608, + "src": "29250:14:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 8675, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "29250:21:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "29246:25:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 8756, + "initializationExpression": { + "expression": { + "argumentTypes": null, + "id": 8671, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 8669, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "29239:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "30", + "id": 8670, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "29243:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "29239:5:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8672, + "nodeType": "ExpressionStatement", + "src": "29239:5:18" + }, + "loopExpression": { + "expression": { + "argumentTypes": null, + "id": 8678, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "29273:3:18", + "subExpression": { + "argumentTypes": null, + "id": 8677, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "29273:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8679, + "nodeType": "ExpressionStatement", + "src": "29273:3:18" + }, + "nodeType": "ForStatement", + "src": "29234:1119:18" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 8759, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8757, + "name": "last_history_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8653, + "src": "30368:17:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "id": 8758, + "name": "NULL_HASH", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7131, + "src": "30389:9:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "30368:30:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 8811, + "nodeType": "Block", + "src": "31143:213:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8798, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "31248:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8799, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8632, + "src": "31261:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8802, + "name": "last_bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8639, + "src": "31285:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 8800, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8646, + "src": "31268:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8801, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 7080, + "src": "31268:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 8803, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "31268:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 8797, + "name": "_payPayee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8848, + "src": "31238:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (bytes32,address,uint256)" + } + }, + "id": 8804, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "31238:58:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8805, + "nodeType": "ExpressionStatement", + "src": "31238:58:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8809, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "delete", + "prefix": true, + "src": "31310:35:18", + "subExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8806, + "name": "question_claims", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7297, + "src": "31317:15:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Claim_$7278_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Claim storage ref)" + } + }, + "id": 8808, + "indexExpression": { + "argumentTypes": null, + "id": 8807, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "31333:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "31317:28:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Claim_$7278_storage", + "typeString": "struct Realitio_v2_1.Claim storage ref" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8810, + "nodeType": "ExpressionStatement", + "src": "31310:35:18" + } + ] + }, + "id": 8812, + "nodeType": "IfStatement", + "src": "30364:992:18", + "trueBody": { + "id": 8796, + "nodeType": "Block", + "src": "30400:737:18", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 8762, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8760, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8632, + "src": "30803:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "id": 8761, + "name": "NULL_ADDRESS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7126, + "src": "30812:12:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "30803:21:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 8774, + "nodeType": "IfStatement", + "src": "30799:137:18", + "trueBody": { + "id": 8773, + "nodeType": "Block", + "src": "30826:110:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8764, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "30854:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8765, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8632, + "src": "30867:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 8766, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8646, + "src": "30874:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 8763, + "name": "_payPayee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8848, + "src": "30844:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (bytes32,address,uint256)" + } + }, + "id": 8767, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "30844:43:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8768, + "nodeType": "ExpressionStatement", + "src": "30844:43:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8771, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 8769, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8646, + "src": "30905:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "30", + "id": 8770, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "30920:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "30905:16:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8772, + "nodeType": "ExpressionStatement", + "src": "30905:16:18" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "id": 8780, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8775, + "name": "question_claims", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7297, + "src": "30950:15:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Claim_$7278_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Claim storage ref)" + } + }, + "id": 8777, + "indexExpression": { + "argumentTypes": null, + "id": 8776, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "30966:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "30950:28:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Claim_$7278_storage", + "typeString": "struct Realitio_v2_1.Claim storage ref" + } + }, + "id": 8778, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "payee", + "nodeType": "MemberAccess", + "referencedDeclaration": 7273, + "src": "30950:34:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 8779, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8632, + "src": "30987:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "30950:42:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 8781, + "nodeType": "ExpressionStatement", + "src": "30950:42:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8787, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8782, + "name": "question_claims", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7297, + "src": "31006:15:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Claim_$7278_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Claim storage ref)" + } + }, + "id": 8784, + "indexExpression": { + "argumentTypes": null, + "id": 8783, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "31022:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "31006:28:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Claim_$7278_storage", + "typeString": "struct Realitio_v2_1.Claim storage ref" + } + }, + "id": 8785, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "last_bond", + "nodeType": "MemberAccess", + "referencedDeclaration": 7275, + "src": "31006:38:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 8786, + "name": "last_bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8639, + "src": "31047:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "31006:50:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8788, + "nodeType": "ExpressionStatement", + "src": "31006:50:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8794, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8789, + "name": "question_claims", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7297, + "src": "31070:15:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Claim_$7278_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Claim storage ref)" + } + }, + "id": 8791, + "indexExpression": { + "argumentTypes": null, + "id": 8790, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "31086:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "31070:28:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Claim_$7278_storage", + "typeString": "struct Realitio_v2_1.Claim storage ref" + } + }, + "id": 8792, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "queued_funds", + "nodeType": "MemberAccess", + "referencedDeclaration": 7277, + "src": "31070:41:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 8793, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8646, + "src": "31114:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "31070:56:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8795, + "nodeType": "ExpressionStatement", + "src": "31070:56:18" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "id": 8818, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8813, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "31366:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8815, + "indexExpression": { + "argumentTypes": null, + "id": 8814, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "31376:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "31366:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8816, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "history_hash", + "nodeType": "MemberAccess", + "referencedDeclaration": 7261, + "src": "31366:35:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 8817, + "name": "last_history_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8653, + "src": "31404:17:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "31366:55:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 8819, + "nodeType": "ExpressionStatement", + "src": "31366:55:18" + } + ] + }, + "documentation": "@notice Assigns the winnings (bounty and bonds) to everyone who gave the accepted answer\n Caller must provide the answer history, in reverse order\n @dev Works up the chain and assign bonds to the person who gave the right answer\n If someone gave the winning answer earlier, they must get paid from the higher bond\n That means we can't pay out the bond added at n until we have looked at n-1\n The first answer is authenticated by checking against the stored history_hash.\n One of the inputs to history_hash is the history_hash before it, so we use that to authenticate the next entry, etc\n Once we get to a null hash we'll know we're done and there are no more answers.\n Usually you would call the whole thing in a single transaction, but if not then the data is persisted to pick up later.\n @param question_id The ID of the question\n @param history_hashes Second-last-to-first, the hash of each history entry. (Final one should be empty).\n @param addrs Last-to-first, the address of each answerer or commitment sender\n @param bonds Last-to-first, the bond supplied with each answer or commitment\n @param answers Last-to-first, each answer supplied, or commitment ID if the answer was supplied with commit->reveal", + "id": 8821, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 8620, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "28447:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8621, + "modifierName": { + "argumentTypes": null, + "id": 8619, + "name": "stateFinalized", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7490, + "src": "28432:14:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "28432:27:18" + } + ], + "name": "claimWinnings", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8618, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8605, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "28309:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8604, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "28309:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8608, + "name": "history_hashes", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "28339:24:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[]" + }, + "typeName": { + "baseType": { + "id": 8606, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "28339:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 8607, + "length": null, + "nodeType": "ArrayTypeName", + "src": "28339:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8611, + "name": "addrs", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "28365:15:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[]" + }, + "typeName": { + "baseType": { + "id": 8609, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "28365:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 8610, + "length": null, + "nodeType": "ArrayTypeName", + "src": "28365:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", + "typeString": "address[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8614, + "name": "bonds", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "28382:15:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[]" + }, + "typeName": { + "baseType": { + "id": 8612, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "28382:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8613, + "length": null, + "nodeType": "ArrayTypeName", + "src": "28382:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8617, + "name": "answers", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "28399:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[]" + }, + "typeName": { + "baseType": { + "id": 8615, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "28399:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 8616, + "length": null, + "nodeType": "ArrayTypeName", + "src": "28399:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "28299:123:18" + }, + "payable": false, + "returnParameters": { + "id": 8622, + "nodeType": "ParameterList", + "parameters": [], + "src": "28471:0:18" + }, + "scope": 9314, + "src": "28277:3152:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 8847, + "nodeType": "Block", + "src": "31519:113:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 8839, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8830, + "name": "balanceOf", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 396, + "src": "31529:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 8832, + "indexExpression": { + "argumentTypes": null, + "id": 8831, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8825, + "src": "31539:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "31529:16:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8837, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8827, + "src": "31569:5:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8833, + "name": "balanceOf", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 396, + "src": "31548:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 8835, + "indexExpression": { + "argumentTypes": null, + "id": 8834, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8825, + "src": "31558:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "31548:16:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8836, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 7080, + "src": "31548:20:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 8838, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "31548:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "31529:46:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8840, + "nodeType": "ExpressionStatement", + "src": "31529:46:18" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8842, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8823, + "src": "31599:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8843, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8825, + "src": "31612:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 8844, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8827, + "src": "31619:5:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 8841, + "name": "LogClaim", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7243, + "src": "31590:8:18", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (bytes32,address,uint256)" + } + }, + "id": 8845, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "31590:35:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8846, + "nodeType": "EmitStatement", + "src": "31585:40:18" + } + ] + }, + "documentation": null, + "id": 8848, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "_payPayee", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8828, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8823, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8848, + "src": "31454:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8822, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "31454:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8825, + "name": "payee", + "nodeType": "VariableDeclaration", + "scope": 8848, + "src": "31475:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8824, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "31475:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8827, + "name": "value", + "nodeType": "VariableDeclaration", + "scope": 8848, + "src": "31490:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8826, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "31490:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "31453:51:18" + }, + "payable": false, + "returnParameters": { + "id": 8829, + "nodeType": "ParameterList", + "parameters": [], + "src": "31519:0:18" + }, + "scope": 9314, + "src": "31435:197:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 8899, + "nodeType": "Block", + "src": "31823:364:18", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 8874, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8863, + "name": "last_history_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8850, + "src": "31837:17:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8867, + "name": "history_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8852, + "src": "31885:12:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8868, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8854, + "src": "31899:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8869, + "name": "bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8856, + "src": "31907:4:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 8870, + "name": "addr", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8858, + "src": "31913:4:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "hexValue": "74727565", + "id": 8871, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "31919:4:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "expression": { + "argumentTypes": null, + "id": 8865, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9703, + "src": "31868:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 8866, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "31868:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 8872, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "31868:56:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 8864, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9710, + "src": "31858:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 8873, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "31858:67:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "31837:88:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 8878, + "nodeType": "IfStatement", + "src": "31833:131:18", + "trueBody": { + "id": 8877, + "nodeType": "Block", + "src": "31928:36:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 8875, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "31949:4:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "functionReturnParameters": 8862, + "id": 8876, + "nodeType": "Return", + "src": "31942:11:18" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 8890, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8879, + "name": "last_history_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8850, + "src": "31977:17:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8883, + "name": "history_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8852, + "src": "32025:12:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8884, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8854, + "src": "32039:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8885, + "name": "bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8856, + "src": "32047:4:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 8886, + "name": "addr", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8858, + "src": "32053:4:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 8887, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "32059:5:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "expression": { + "argumentTypes": null, + "id": 8881, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9703, + "src": "32008:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 8882, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "32008:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 8888, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "32008:57:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 8880, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9710, + "src": "31998:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 8889, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "31998:68:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "31977:89:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 8894, + "nodeType": "IfStatement", + "src": "31973:133:18", + "trueBody": { + "id": 8893, + "nodeType": "Block", + "src": "32069:37:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 8891, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "32090:5:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "functionReturnParameters": 8862, + "id": 8892, + "nodeType": "Return", + "src": "32083:12:18" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "486973746f727920696e7075742070726f766964656420646964206e6f74206d61746368207468652065787065637465642068617368", + "id": 8896, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "32123:56:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_105eb464ca1766d0405b5fa901151a4c75699ccc5e522facb7c8a5407d6bd553", + "typeString": "literal_string \"History input provided did not match the expected hash\"" + }, + "value": "History input provided did not match the expected hash" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_105eb464ca1766d0405b5fa901151a4c75699ccc5e522facb7c8a5407d6bd553", + "typeString": "literal_string \"History input provided did not match the expected hash\"" + } + ], + "id": 8895, + "name": "revert", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9721, + 9722 + ], + "referencedDeclaration": 9722, + "src": "32116:6:18", + "typeDescriptions": { + "typeIdentifier": "t_function_revert_pure$_t_string_memory_ptr_$returns$__$", + "typeString": "function (string memory) pure" + } + }, + "id": 8897, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "32116:64:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8898, + "nodeType": "ExpressionStatement", + "src": "32116:64:18" + } + ] + }, + "documentation": null, + "id": 8900, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "_verifyHistoryInputOrRevert", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8859, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8850, + "name": "last_history_hash", + "nodeType": "VariableDeclaration", + "scope": 8900, + "src": "31684:25:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8849, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "31684:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8852, + "name": "history_hash", + "nodeType": "VariableDeclaration", + "scope": 8900, + "src": "31719:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8851, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "31719:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8854, + "name": "answer", + "nodeType": "VariableDeclaration", + "scope": 8900, + "src": "31741:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8853, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "31741:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8856, + "name": "bond", + "nodeType": "VariableDeclaration", + "scope": 8900, + "src": "31757:12:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8855, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "31757:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8858, + "name": "addr", + "nodeType": "VariableDeclaration", + "scope": 8900, + "src": "31771:12:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8857, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "31771:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "31674:115:18" + }, + "payable": false, + "returnParameters": { + "id": 8862, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8861, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 8900, + "src": "31817:4:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 8860, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "31817:4:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "31816:6:18" + }, + "scope": 9314, + "src": "31638:549:18", + "stateMutability": "pure", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 9026, + "nodeType": "Block", + "src": "32437:2167:18", + "statements": [ + { + "condition": { + "argumentTypes": null, + "id": 8923, + "name": "is_commitment", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8916, + "src": "32636:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 8958, + "nodeType": "IfStatement", + "src": "32632:482:18", + "trueBody": { + "id": 8957, + "nodeType": "Block", + "src": "32651:463:18", + "statements": [ + { + "assignments": [ + 8925 + ], + "declarations": [ + { + "constant": false, + "id": 8925, + "name": "commitment_id", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "32665:21:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8924, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "32665:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8927, + "initialValue": { + "argumentTypes": null, + "id": 8926, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8914, + "src": "32689:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "32665:30:18" + }, + { + "condition": { + "argumentTypes": null, + "id": 8932, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "32810:39:18", + "subExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8928, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "32811:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 8930, + "indexExpression": { + "argumentTypes": null, + "id": 8929, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8925, + "src": "32823:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "32811:26:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "id": 8931, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "is_revealed", + "nodeType": "MemberAccess", + "referencedDeclaration": 7268, + "src": "32811:38:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 8955, + "nodeType": "Block", + "src": "32969:135:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 8948, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 8943, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8914, + "src": "32987:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8944, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "32996:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 8946, + "indexExpression": { + "argumentTypes": null, + "id": 8945, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8925, + "src": "33008:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "32996:26:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "id": 8947, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "revealed_answer", + "nodeType": "MemberAccess", + "referencedDeclaration": 7270, + "src": "32996:42:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "32987:51:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 8949, + "nodeType": "ExpressionStatement", + "src": "32987:51:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8953, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "delete", + "prefix": true, + "src": "33056:33:18", + "subExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8950, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "33063:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 8952, + "indexExpression": { + "argumentTypes": null, + "id": 8951, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8925, + "src": "33075:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "33063:26:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8954, + "nodeType": "ExpressionStatement", + "src": "33056:33:18" + } + ] + }, + "id": 8956, + "nodeType": "IfStatement", + "src": "32806:298:18", + "trueBody": { + "id": 8942, + "nodeType": "Block", + "src": "32851:112:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 8936, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "delete", + "prefix": true, + "src": "32869:33:18", + "subExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8933, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "32876:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 8935, + "indexExpression": { + "argumentTypes": null, + "id": 8934, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8925, + "src": "32888:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "32876:26:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8937, + "nodeType": "ExpressionStatement", + "src": "32869:33:18" + }, + { + "expression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "id": 8938, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8906, + "src": "32928:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 8939, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8908, + "src": "32942:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "id": 8940, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "32927:21:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_address_$", + "typeString": "tuple(uint256,address)" + } + }, + "functionReturnParameters": 8922, + "id": 8941, + "nodeType": "Return", + "src": "32920:28:18" + } + ] + } + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 8961, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8959, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8914, + "src": "33128:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 8960, + "name": "best_answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8904, + "src": "33138:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "33128:21:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 9021, + "nodeType": "IfStatement", + "src": "33124:1434:18", + "trueBody": { + "id": 9020, + "nodeType": "Block", + "src": "33151:1407:18", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 8964, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8962, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8908, + "src": "33170:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 8963, + "name": "NULL_ADDRESS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7126, + "src": "33179:12:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "33170:21:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 8989, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8987, + "name": "addr", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8910, + "src": "33509:4:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "id": 8988, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8908, + "src": "33517:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "33509:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 9018, + "nodeType": "IfStatement", + "src": "33505:1042:18", + "trueBody": { + "id": 9017, + "nodeType": "Block", + "src": "33524:1023:18", + "statements": [ + { + "assignments": [ + 8991 + ], + "declarations": [ + { + "constant": false, + "id": 8991, + "name": "answer_takeover_fee", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "34143:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8990, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "34143:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8999, + "initialValue": { + "argumentTypes": null, + "condition": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 8994, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8992, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8906, + "src": "34174:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": { + "argumentTypes": null, + "id": 8993, + "name": "bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8912, + "src": "34190:4:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "34174:20:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 8995, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "34173:22:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "argumentTypes": null, + "id": 8997, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8906, + "src": "34205:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8998, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "34173:44:18", + "trueExpression": { + "argumentTypes": null, + "id": 8996, + "name": "bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8912, + "src": "34198:4:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "34143:74:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 9001, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8902, + "src": "34309:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 9002, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8908, + "src": "34322:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 9005, + "name": "answer_takeover_fee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8991, + "src": "34346:19:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 9003, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8906, + "src": "34329:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9004, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sub", + "nodeType": "MemberAccess", + "referencedDeclaration": 7056, + "src": "34329:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 9006, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "34329:37:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 9000, + "name": "_payPayee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8848, + "src": "34299:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (bytes32,address,uint256)" + } + }, + "id": 9007, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "34299:68:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 9008, + "nodeType": "ExpressionStatement", + "src": "34299:68:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 9011, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 9009, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8908, + "src": "34467:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 9010, + "name": "addr", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8910, + "src": "34475:4:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "34467:12:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 9012, + "nodeType": "ExpressionStatement", + "src": "34467:12:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 9015, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 9013, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8906, + "src": "34497:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 9014, + "name": "answer_takeover_fee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8991, + "src": "34512:19:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "34497:34:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9016, + "nodeType": "ExpressionStatement", + "src": "34497:34:18" + } + ] + } + }, + "id": 9019, + "nodeType": "IfStatement", + "src": "33166:1381:18", + "trueBody": { + "id": 8986, + "nodeType": "Block", + "src": "33193:306:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 8967, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 8965, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8908, + "src": "33340:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 8966, + "name": "addr", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8910, + "src": "33348:4:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "33340:12:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 8968, + "nodeType": "ExpressionStatement", + "src": "33340:12:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8977, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 8969, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8906, + "src": "33370:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8972, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "33402:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8974, + "indexExpression": { + "argumentTypes": null, + "id": 8973, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8902, + "src": "33412:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "33402:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8975, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bounty", + "nodeType": "MemberAccess", + "referencedDeclaration": 7257, + "src": "33402:29:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 8970, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8906, + "src": "33385:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8971, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 7080, + "src": "33385:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 8976, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "33385:47:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "33370:62:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8978, + "nodeType": "ExpressionStatement", + "src": "33370:62:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8984, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8979, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "33450:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8981, + "indexExpression": { + "argumentTypes": null, + "id": 8980, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8902, + "src": "33460:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "33450:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8982, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "bounty", + "nodeType": "MemberAccess", + "referencedDeclaration": 7257, + "src": "33450:29:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "30", + "id": 8983, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "33482:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "33450:33:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8985, + "nodeType": "ExpressionStatement", + "src": "33450:33:18" + } + ] + } + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "id": 9022, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8906, + "src": "34576:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 9023, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8908, + "src": "34590:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "id": 9024, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "34575:21:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_address_$", + "typeString": "tuple(uint256,address)" + } + }, + "functionReturnParameters": 8922, + "id": 9025, + "nodeType": "Return", + "src": "34568:28:18" + } + ] + }, + "documentation": null, + "id": 9027, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "_processHistoryItem", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8917, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8902, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "32231:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8901, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "32231:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8904, + "name": "best_answer", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "32252:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8903, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "32252:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8906, + "name": "queued_funds", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "32282:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8905, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "32282:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8908, + "name": "payee", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "32304:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8907, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "32304:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8910, + "name": "addr", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "32328:12:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8909, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "32328:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8912, + "name": "bond", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "32342:12:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8911, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "32342:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8914, + "name": "answer", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "32356:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8913, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "32356:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8916, + "name": "is_commitment", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "32372:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 8915, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "32372:4:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "32221:175:18" + }, + "payable": false, + "returnParameters": { + "id": 8922, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8919, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "32419:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8918, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "32419:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8921, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "32428:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8920, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "32428:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "32418:18:18" + }, + "scope": 9314, + "src": "32193:2411:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 9182, + "nodeType": "Block", + "src": "35829:723:18", + "statements": [ + { + "assignments": [], + "declarations": [ + { + "constant": false, + "id": 9051, + "name": "qi", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "35848:10:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 9050, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "35848:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 9052, + "initialValue": null, + "nodeType": "VariableDeclarationStatement", + "src": "35848:10:18" + }, + { + "assignments": [], + "declarations": [ + { + "constant": false, + "id": 9054, + "name": "i", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "35868:9:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 9053, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "35868:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 9055, + "initialValue": null, + "nodeType": "VariableDeclarationStatement", + "src": "35868:9:18" + }, + { + "body": { + "id": 9177, + "nodeType": "Block", + "src": "35932:594:18", + "statements": [ + { + "assignments": [ + 9068 + ], + "declarations": [ + { + "constant": false, + "id": 9068, + "name": "qid", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "35946:11:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9067, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "35946:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 9072, + "initialValue": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9069, + "name": "question_ids", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9030, + "src": "35960:12:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 9071, + "indexExpression": { + "argumentTypes": null, + "id": 9070, + "name": "qi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9051, + "src": "35973:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "35960:16:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "35946:30:18" + }, + { + "assignments": [ + 9074 + ], + "declarations": [ + { + "constant": false, + "id": 9074, + "name": "ln", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "35990:10:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 9073, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "35990:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 9078, + "initialValue": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9075, + "name": "lengths", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9033, + "src": "36003:7:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 9077, + "indexExpression": { + "argumentTypes": null, + "id": 9076, + "name": "qi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9051, + "src": "36011:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "36003:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "35990:24:18" + }, + { + "assignments": [ + 9082 + ], + "declarations": [ + { + "constant": false, + "id": 9082, + "name": "hh", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "36028:19:18", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[]" + }, + "typeName": { + "baseType": { + "id": 9080, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "36028:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 9081, + "length": null, + "nodeType": "ArrayTypeName", + "src": "36028:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 9088, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 9086, + "name": "ln", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9074, + "src": "36064:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 9085, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "NewExpression", + "src": "36050:13:18", + "typeDescriptions": { + "typeIdentifier": "t_function_objectcreation_pure$_t_uint256_$returns$_t_array$_t_bytes32_$dyn_memory_$", + "typeString": "function (uint256) pure returns (bytes32[] memory)" + }, + "typeName": { + "baseType": { + "id": 9083, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "36054:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 9084, + "length": null, + "nodeType": "ArrayTypeName", + "src": "36054:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + } + }, + "id": 9087, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "36050:17:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory", + "typeString": "bytes32[] memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "36028:39:18" + }, + { + "assignments": [ + 9092 + ], + "declarations": [ + { + "constant": false, + "id": 9092, + "name": "ad", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "36081:19:18", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[]" + }, + "typeName": { + "baseType": { + "id": 9090, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "36081:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 9091, + "length": null, + "nodeType": "ArrayTypeName", + "src": "36081:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", + "typeString": "address[]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 9098, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 9096, + "name": "ln", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9074, + "src": "36117:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 9095, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "NewExpression", + "src": "36103:13:18", + "typeDescriptions": { + "typeIdentifier": "t_function_objectcreation_pure$_t_uint256_$returns$_t_array$_t_address_$dyn_memory_$", + "typeString": "function (uint256) pure returns (address[] memory)" + }, + "typeName": { + "baseType": { + "id": 9093, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "36107:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 9094, + "length": null, + "nodeType": "ArrayTypeName", + "src": "36107:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", + "typeString": "address[]" + } + } + }, + "id": 9097, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "36103:17:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory", + "typeString": "address[] memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "36081:39:18" + }, + { + "assignments": [ + 9102 + ], + "declarations": [ + { + "constant": false, + "id": 9102, + "name": "bo", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "36134:19:18", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[]" + }, + "typeName": { + "baseType": { + "id": 9100, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "36134:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9101, + "length": null, + "nodeType": "ArrayTypeName", + "src": "36134:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 9108, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 9106, + "name": "ln", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9074, + "src": "36170:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 9105, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "NewExpression", + "src": "36156:13:18", + "typeDescriptions": { + "typeIdentifier": "t_function_objectcreation_pure$_t_uint256_$returns$_t_array$_t_uint256_$dyn_memory_$", + "typeString": "function (uint256) pure returns (uint256[] memory)" + }, + "typeName": { + "baseType": { + "id": 9103, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "36160:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9104, + "length": null, + "nodeType": "ArrayTypeName", + "src": "36160:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + } + }, + "id": 9107, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "36156:17:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory", + "typeString": "uint256[] memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "36134:39:18" + }, + { + "assignments": [ + 9112 + ], + "declarations": [ + { + "constant": false, + "id": 9112, + "name": "an", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "36187:19:18", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[]" + }, + "typeName": { + "baseType": { + "id": 9110, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "36187:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 9111, + "length": null, + "nodeType": "ArrayTypeName", + "src": "36187:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 9118, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 9116, + "name": "ln", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9074, + "src": "36223:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 9115, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "NewExpression", + "src": "36209:13:18", + "typeDescriptions": { + "typeIdentifier": "t_function_objectcreation_pure$_t_uint256_$returns$_t_array$_t_bytes32_$dyn_memory_$", + "typeString": "function (uint256) pure returns (bytes32[] memory)" + }, + "typeName": { + "baseType": { + "id": 9113, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "36213:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 9114, + "length": null, + "nodeType": "ArrayTypeName", + "src": "36213:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + } + }, + "id": 9117, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "36209:17:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory", + "typeString": "bytes32[] memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "36187:39:18" + }, + { + "assignments": [], + "declarations": [ + { + "constant": false, + "id": 9120, + "name": "j", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "36240:9:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 9119, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "36240:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 9121, + "initialValue": null, + "nodeType": "VariableDeclarationStatement", + "src": "36240:9:18" + }, + { + "body": { + "id": 9167, + "nodeType": "Block", + "src": "36288:180:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 9138, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9132, + "name": "hh", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9082, + "src": "36306:2:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 9134, + "indexExpression": { + "argumentTypes": null, + "id": 9133, + "name": "j", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9120, + "src": "36309:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "36306:5:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9135, + "name": "hist_hashes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9036, + "src": "36314:11:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 9137, + "indexExpression": { + "argumentTypes": null, + "id": 9136, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9054, + "src": "36326:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "36314:14:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "36306:22:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 9139, + "nodeType": "ExpressionStatement", + "src": "36306:22:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 9146, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9140, + "name": "ad", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9092, + "src": "36346:2:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + "id": 9142, + "indexExpression": { + "argumentTypes": null, + "id": 9141, + "name": "j", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9120, + "src": "36349:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "36346:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9143, + "name": "addrs", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9039, + "src": "36354:5:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + "id": 9145, + "indexExpression": { + "argumentTypes": null, + "id": 9144, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9054, + "src": "36360:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "36354:8:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "36346:16:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 9147, + "nodeType": "ExpressionStatement", + "src": "36346:16:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 9154, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9148, + "name": "bo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9102, + "src": "36380:2:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 9150, + "indexExpression": { + "argumentTypes": null, + "id": 9149, + "name": "j", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9120, + "src": "36383:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "36380:5:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9151, + "name": "bonds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9042, + "src": "36388:5:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 9153, + "indexExpression": { + "argumentTypes": null, + "id": 9152, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9054, + "src": "36394:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "36388:8:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "36380:16:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9155, + "nodeType": "ExpressionStatement", + "src": "36380:16:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 9162, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9156, + "name": "an", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9112, + "src": "36414:2:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 9158, + "indexExpression": { + "argumentTypes": null, + "id": 9157, + "name": "j", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9120, + "src": "36417:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "36414:5:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9159, + "name": "answers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9045, + "src": "36422:7:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 9161, + "indexExpression": { + "argumentTypes": null, + "id": 9160, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9054, + "src": "36430:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "36422:10:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "36414:18:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 9163, + "nodeType": "ExpressionStatement", + "src": "36414:18:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 9165, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "36450:3:18", + "subExpression": { + "argumentTypes": null, + "id": 9164, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9054, + "src": "36450:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9166, + "nodeType": "ExpressionStatement", + "src": "36450:3:18" + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 9128, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 9126, + "name": "j", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9120, + "src": "36275:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "id": 9127, + "name": "ln", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9074, + "src": "36279:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "36275:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 9168, + "initializationExpression": { + "expression": { + "argumentTypes": null, + "id": 9124, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 9122, + "name": "j", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9120, + "src": "36268:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "30", + "id": 9123, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "36272:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "36268:5:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9125, + "nodeType": "ExpressionStatement", + "src": "36268:5:18" + }, + "loopExpression": { + "expression": { + "argumentTypes": null, + "id": 9130, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "36283:3:18", + "subExpression": { + "argumentTypes": null, + "id": 9129, + "name": "j", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9120, + "src": "36283:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9131, + "nodeType": "ExpressionStatement", + "src": "36283:3:18" + }, + "nodeType": "ForStatement", + "src": "36263:205:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 9170, + "name": "qid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9068, + "src": "36495:3:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 9171, + "name": "hh", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9082, + "src": "36500:2:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + { + "argumentTypes": null, + "id": 9172, + "name": "ad", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9092, + "src": "36504:2:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + { + "argumentTypes": null, + "id": 9173, + "name": "bo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9102, + "src": "36508:2:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + { + "argumentTypes": null, + "id": 9174, + "name": "an", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9112, + "src": "36512:2:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + }, + { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + }, + { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + }, + { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + ], + "id": 9169, + "name": "claimWinnings", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8821, + "src": "36481:13:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_array$_t_bytes32_$dyn_memory_ptr_$_t_array$_t_address_$dyn_memory_ptr_$_t_array$_t_uint256_$dyn_memory_ptr_$_t_array$_t_bytes32_$dyn_memory_ptr_$returns$__$", + "typeString": "function (bytes32,bytes32[] memory,address[] memory,uint256[] memory,bytes32[] memory)" + } + }, + "id": 9175, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "36481:34:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 9176, + "nodeType": "ExpressionStatement", + "src": "36481:34:18" + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 9063, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 9060, + "name": "qi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9051, + "src": "35900:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 9061, + "name": "question_ids", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9030, + "src": "35905:12:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 9062, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "35905:19:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "35900:24:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 9178, + "initializationExpression": { + "expression": { + "argumentTypes": null, + "id": 9058, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 9056, + "name": "qi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9051, + "src": "35892:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "30", + "id": 9057, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "35897:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "35892:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9059, + "nodeType": "ExpressionStatement", + "src": "35892:6:18" + }, + "loopExpression": { + "expression": { + "argumentTypes": null, + "id": 9065, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "35926:4:18", + "subExpression": { + "argumentTypes": null, + "id": 9064, + "name": "qi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9051, + "src": "35926:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9066, + "nodeType": "ExpressionStatement", + "src": "35926:4:18" + }, + "nodeType": "ForStatement", + "src": "35887:639:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 9179, + "name": "withdraw", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 434, + "src": "36535:8:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 9180, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "36535:10:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 9181, + "nodeType": "ExpressionStatement", + "src": "36535:10:18" + } + ] + }, + "documentation": "@notice Convenience function to assign bounties/bonds for multiple questions in one go, then withdraw all your funds.\n Caller must provide the answer history for each question, in reverse order\n @dev Can be called by anyone to assign bonds/bounties, but funds are only withdrawn for the user making the call.\n @param question_ids The IDs of the questions you want to claim for\n @param lengths The number of history entries you will supply for each question ID\n @param hist_hashes In a single list for all supplied questions, the hash of each history entry.\n @param addrs In a single list for all supplied questions, the address of each answerer or commitment sender\n @param bonds In a single list for all supplied questions, the bond supplied with each answer or commitment\n @param answers In a single list for all supplied questions, each answer supplied, or commitment ID ", + "id": 9183, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [], + "id": 9048, + "modifierName": { + "argumentTypes": null, + "id": 9047, + "name": "stateAny", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7326, + "src": "35741:8:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "35741:10:18" + } + ], + "name": "claimMultipleAndWithdrawBalance", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 9046, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9030, + "name": "question_ids", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "35599:22:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[]" + }, + "typeName": { + "baseType": { + "id": 9028, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "35599:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 9029, + "length": null, + "nodeType": "ArrayTypeName", + "src": "35599:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 9033, + "name": "lengths", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "35623:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[]" + }, + "typeName": { + "baseType": { + "id": 9031, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "35623:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9032, + "length": null, + "nodeType": "ArrayTypeName", + "src": "35623:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 9036, + "name": "hist_hashes", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "35651:21:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[]" + }, + "typeName": { + "baseType": { + "id": 9034, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "35651:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 9035, + "length": null, + "nodeType": "ArrayTypeName", + "src": "35651:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 9039, + "name": "addrs", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "35674:15:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[]" + }, + "typeName": { + "baseType": { + "id": 9037, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "35674:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 9038, + "length": null, + "nodeType": "ArrayTypeName", + "src": "35674:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", + "typeString": "address[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 9042, + "name": "bonds", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "35691:15:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[]" + }, + "typeName": { + "baseType": { + "id": 9040, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "35691:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9041, + "length": null, + "nodeType": "ArrayTypeName", + "src": "35691:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 9045, + "name": "answers", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "35708:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[]" + }, + "typeName": { + "baseType": { + "id": 9043, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "35708:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 9044, + "length": null, + "nodeType": "ArrayTypeName", + "src": "35708:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "35589:142:18" + }, + "payable": false, + "returnParameters": { + "id": 9049, + "nodeType": "ParameterList", + "parameters": [], + "src": "35829:0:18" + }, + "scope": 9314, + "src": "35549:1003:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 9195, + "nodeType": "Block", + "src": "36775:59:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9190, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "36792:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 9192, + "indexExpression": { + "argumentTypes": null, + "id": 9191, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9185, + "src": "36802:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "36792:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 9193, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "content_hash", + "nodeType": "MemberAccess", + "referencedDeclaration": 7245, + "src": "36792:35:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 9189, + "id": 9194, + "nodeType": "Return", + "src": "36785:42:18" + } + ] + }, + "documentation": "@notice Returns the questions's content hash, identifying the question content\n @param question_id The ID of the question ", + "id": 9196, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getContentHash", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 9186, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9185, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 9196, + "src": "36720:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9184, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "36720:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "36719:21:18" + }, + "payable": false, + "returnParameters": { + "id": 9189, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9188, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9196, + "src": "36766:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9187, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "36766:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "36765:9:18" + }, + "scope": 9314, + "src": "36696:138:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 9208, + "nodeType": "Block", + "src": "37033:57:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9203, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "37050:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 9205, + "indexExpression": { + "argumentTypes": null, + "id": 9204, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9198, + "src": "37060:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "37050:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 9206, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "arbitrator", + "nodeType": "MemberAccess", + "referencedDeclaration": 7247, + "src": "37050:33:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "functionReturnParameters": 9202, + "id": 9207, + "nodeType": "Return", + "src": "37043:40:18" + } + ] + }, + "documentation": "@notice Returns the arbitrator address for the question\n @param question_id The ID of the question ", + "id": 9209, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getArbitrator", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 9199, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9198, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 9209, + "src": "36978:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9197, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "36978:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "36977:21:18" + }, + "payable": false, + "returnParameters": { + "id": 9202, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9201, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9209, + "src": "37024:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 9200, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "37024:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "37023:9:18" + }, + "scope": 9314, + "src": "36955:135:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 9221, + "nodeType": "Block", + "src": "37301:57:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9216, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "37318:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 9218, + "indexExpression": { + "argumentTypes": null, + "id": 9217, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9211, + "src": "37328:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "37318:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 9219, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "opening_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7249, + "src": "37318:33:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "functionReturnParameters": 9215, + "id": 9220, + "nodeType": "Return", + "src": "37311:40:18" + } + ] + }, + "documentation": "@notice Returns the timestamp when the question can first be answered\n @param question_id The ID of the question ", + "id": 9222, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getOpeningTS", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 9212, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9211, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 9222, + "src": "37247:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9210, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "37247:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "37246:21:18" + }, + "payable": false, + "returnParameters": { + "id": 9215, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9214, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9222, + "src": "37293:6:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 9213, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "37293:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "37292:8:18" + }, + "scope": 9314, + "src": "37225:133:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 9234, + "nodeType": "Block", + "src": "37559:54:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9229, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "37576:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 9231, + "indexExpression": { + "argumentTypes": null, + "id": 9230, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9224, + "src": "37586:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "37576:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 9232, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timeout", + "nodeType": "MemberAccess", + "referencedDeclaration": 7251, + "src": "37576:30:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "functionReturnParameters": 9228, + "id": 9233, + "nodeType": "Return", + "src": "37569:37:18" + } + ] + }, + "documentation": "@notice Returns the timeout in seconds used after each answer\n @param question_id The ID of the question ", + "id": 9235, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getTimeout", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 9225, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9224, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 9235, + "src": "37505:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9223, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "37505:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "37504:21:18" + }, + "payable": false, + "returnParameters": { + "id": 9228, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9227, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9235, + "src": "37551:6:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 9226, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "37551:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "37550:8:18" + }, + "scope": 9314, + "src": "37485:128:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 9247, + "nodeType": "Block", + "src": "37829:58:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9242, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "37846:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 9244, + "indexExpression": { + "argumentTypes": null, + "id": 9243, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9237, + "src": "37856:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "37846:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 9245, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "finalize_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7253, + "src": "37846:34:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "functionReturnParameters": 9241, + "id": 9246, + "nodeType": "Return", + "src": "37839:41:18" + } + ] + }, + "documentation": "@notice Returns the timestamp at which the question will be/was finalized\n @param question_id The ID of the question ", + "id": 9248, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getFinalizeTS", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 9238, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9237, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 9248, + "src": "37775:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9236, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "37775:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "37774:21:18" + }, + "payable": false, + "returnParameters": { + "id": 9241, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9240, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9248, + "src": "37821:6:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 9239, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "37821:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "37820:8:18" + }, + "scope": 9314, + "src": "37752:135:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 9260, + "nodeType": "Block", + "src": "38094:69:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9255, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "38111:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 9257, + "indexExpression": { + "argumentTypes": null, + "id": 9256, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9250, + "src": "38121:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "38111:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 9258, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "is_pending_arbitration", + "nodeType": "MemberAccess", + "referencedDeclaration": 7255, + "src": "38111:45:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "functionReturnParameters": 9254, + "id": 9259, + "nodeType": "Return", + "src": "38104:52:18" + } + ] + }, + "documentation": "@notice Returns whether the question is pending arbitration\n @param question_id The ID of the question ", + "id": 9261, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "isPendingArbitration", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 9251, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9250, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 9261, + "src": "38042:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9249, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "38042:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "38041:21:18" + }, + "payable": false, + "returnParameters": { + "id": 9254, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9253, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9261, + "src": "38088:4:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 9252, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "38088:4:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "38087:6:18" + }, + "scope": 9314, + "src": "38012:151:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 9273, + "nodeType": "Block", + "src": "38416:53:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9268, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "38433:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 9270, + "indexExpression": { + "argumentTypes": null, + "id": 9269, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9263, + "src": "38443:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "38433:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 9271, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bounty", + "nodeType": "MemberAccess", + "referencedDeclaration": 7257, + "src": "38433:29:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 9267, + "id": 9272, + "nodeType": "Return", + "src": "38426:36:18" + } + ] + }, + "documentation": "@notice Returns the current total unclaimed bounty\n @dev Set back to zero once the bounty has been claimed\n @param question_id The ID of the question ", + "id": 9274, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getBounty", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 9264, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9263, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 9274, + "src": "38361:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9262, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "38361:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "38360:21:18" + }, + "payable": false, + "returnParameters": { + "id": 9267, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9266, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9274, + "src": "38407:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 9265, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "38407:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "38406:9:18" + }, + "scope": 9314, + "src": "38342:127:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 9286, + "nodeType": "Block", + "src": "38652:58:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9281, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "38669:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 9283, + "indexExpression": { + "argumentTypes": null, + "id": 9282, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9276, + "src": "38679:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "38669:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 9284, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "best_answer", + "nodeType": "MemberAccess", + "referencedDeclaration": 7259, + "src": "38669:34:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 9280, + "id": 9285, + "nodeType": "Return", + "src": "38662:41:18" + } + ] + }, + "documentation": "@notice Returns the current best answer\n @param question_id The ID of the question ", + "id": 9287, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getBestAnswer", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 9277, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9276, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 9287, + "src": "38597:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9275, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "38597:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "38596:21:18" + }, + "payable": false, + "returnParameters": { + "id": 9280, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9279, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9287, + "src": "38643:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9278, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "38643:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "38642:9:18" + }, + "scope": 9314, + "src": "38574:136:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 9299, + "nodeType": "Block", + "src": "38973:59:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9294, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "38990:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 9296, + "indexExpression": { + "argumentTypes": null, + "id": 9295, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9289, + "src": "39000:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "38990:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 9297, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "history_hash", + "nodeType": "MemberAccess", + "referencedDeclaration": 7261, + "src": "38990:35:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 9293, + "id": 9298, + "nodeType": "Return", + "src": "38983:42:18" + } + ] + }, + "documentation": "@notice Returns the history hash of the question \n @param question_id The ID of the question \n @dev Updated on each answer, then rewound as each is claimed", + "id": 9300, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getHistoryHash", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 9290, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9289, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 9300, + "src": "38918:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9288, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "38918:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "38917:21:18" + }, + "payable": false, + "returnParameters": { + "id": 9293, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9292, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9300, + "src": "38964:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9291, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "38964:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "38963:9:18" + }, + "scope": 9314, + "src": "38894:138:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 9312, + "nodeType": "Block", + "src": "39231:51:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9307, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "39248:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 9309, + "indexExpression": { + "argumentTypes": null, + "id": 9308, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9302, + "src": "39258:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "39248:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 9310, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bond", + "nodeType": "MemberAccess", + "referencedDeclaration": 7263, + "src": "39248:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 9306, + "id": 9311, + "nodeType": "Return", + "src": "39241:34:18" + } + ] + }, + "documentation": "@notice Returns the highest bond posted so far for a question\n @param question_id The ID of the question ", + "id": 9313, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getBond", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 9303, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9302, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 9313, + "src": "39176:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9301, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "39176:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "39175:21:18" + }, + "payable": false, + "returnParameters": { + "id": 9306, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9305, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9313, + "src": "39222:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 9304, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "39222:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "39221:9:18" + }, + "scope": 9314, + "src": "39159:123:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 9315, + "src": "306:38979:18" + } + ], + "src": "0:39286:18" + }, + "legacyAST": { + "absolutePath": "/home/ed/working/realitio-contracts/truffle/contracts/Realitio_v2_1.sol", + "exportedSymbols": { + "Realitio_v2_1": [ + 9314 + ] + }, + "id": 9315, + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 7110, + "literals": [ + "solidity", + "^", + "0.4", + ".25" + ], + "nodeType": "PragmaDirective", + "src": "0:24:18" + }, + { + "absolutePath": "/home/ed/working/realitio-contracts/truffle/contracts/RealitioSafeMath256.sol", + "file": "./RealitioSafeMath256.sol", + "id": 7111, + "nodeType": "ImportDirective", + "scope": 9315, + "sourceUnit": 7082, + "src": "26:35:18", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/home/ed/working/realitio-contracts/truffle/contracts/RealitioSafeMath32.sol", + "file": "./RealitioSafeMath32.sol", + "id": 7112, + "nodeType": "ImportDirective", + "scope": 9315, + "sourceUnit": 7109, + "src": "62:34:18", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/home/ed/working/realitio-contracts/truffle/contracts/BalanceHolder.sol", + "file": "./BalanceHolder.sol", + "id": 7113, + "nodeType": "ImportDirective", + "scope": 9315, + "sourceUnit": 436, + "src": "97:29:18", + "symbolAliases": [], + "unitAlias": "" + }, + { + "baseContracts": [ + { + "arguments": null, + "baseName": { + "contractScope": null, + "id": 7114, + "name": "BalanceHolder", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 435, + "src": "332:13:18", + "typeDescriptions": { + "typeIdentifier": "t_contract$_BalanceHolder_$435", + "typeString": "contract BalanceHolder" + } + }, + "id": 7115, + "nodeType": "InheritanceSpecifier", + "src": "332:13:18" + } + ], + "contractDependencies": [ + 435 + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 9314, + "linearizedBaseContracts": [ + 9314, + 435 + ], + "name": "Realitio_v2_1", + "nodeType": "ContractDefinition", + "nodes": [ + { + "id": 7118, + "libraryName": { + "contractScope": null, + "id": 7116, + "name": "RealitioSafeMath256", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 7081, + "src": "359:19:18", + "typeDescriptions": { + "typeIdentifier": "t_contract$_RealitioSafeMath256_$7081", + "typeString": "library RealitioSafeMath256" + } + }, + "nodeType": "UsingForDirective", + "src": "353:38:18", + "typeName": { + "id": 7117, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "383:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + }, + { + "id": 7121, + "libraryName": { + "contractScope": null, + "id": 7119, + "name": "RealitioSafeMath32", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 7108, + "src": "402:18:18", + "typeDescriptions": { + "typeIdentifier": "t_contract$_RealitioSafeMath32_$7108", + "typeString": "library RealitioSafeMath32" + } + }, + "nodeType": "UsingForDirective", + "src": "396:36:18", + "typeName": { + "id": 7120, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "425:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + } + }, + { + "constant": true, + "id": 7126, + "name": "NULL_ADDRESS", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "438:42:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7122, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "438:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 7124, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "478:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 7123, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "470:7:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 7125, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "470:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": true, + "id": 7131, + "name": "NULL_HASH", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "563:39:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7127, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "563:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 7129, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "600:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 7128, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "592:7:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": "bytes32" + }, + "id": 7130, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "592:10:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": true, + "id": 7134, + "name": "UNANSWERED", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "697:30:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7132, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "697:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "30", + "id": 7133, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "726:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "visibility": "internal" + }, + { + "constant": true, + "id": 7137, + "name": "COMMITMENT_NON_EXISTENT", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "820:44:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7135, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "820:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "30", + "id": 7136, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "863:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "visibility": "internal" + }, + { + "constant": true, + "id": 7140, + "name": "COMMITMENT_TIMEOUT_RATIO", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "948:44:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7138, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "948:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "38", + "id": 7139, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "991:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_8_by_1", + "typeString": "int_const 8" + }, + "value": "8" + }, + "visibility": "internal" + }, + { + "constant": true, + "id": 7143, + "name": "BOND_CLAIM_FEE_PROPORTION", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "1058:47:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7141, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1058:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "3430", + "id": 7142, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1103:2:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_40_by_1", + "typeString": "int_const 40" + }, + "value": "40" + }, + "visibility": "internal" + }, + { + "anonymous": false, + "documentation": null, + "id": 7149, + "name": "LogSetQuestionFee", + "nodeType": "EventDefinition", + "parameters": { + "id": 7148, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7145, + "indexed": false, + "name": "arbitrator", + "nodeType": "VariableDeclaration", + "scope": 7149, + "src": "1165:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7144, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1165:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7147, + "indexed": false, + "name": "amount", + "nodeType": "VariableDeclaration", + "scope": 7149, + "src": "1193:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7146, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1193:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "1155:58:18" + }, + "src": "1132:82:18" + }, + { + "anonymous": false, + "documentation": null, + "id": 7157, + "name": "LogNewTemplate", + "nodeType": "EventDefinition", + "parameters": { + "id": 7156, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7151, + "indexed": true, + "name": "template_id", + "nodeType": "VariableDeclaration", + "scope": 7157, + "src": "1250:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7150, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1250:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7153, + "indexed": true, + "name": "user", + "nodeType": "VariableDeclaration", + "scope": 7157, + "src": "1287:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7152, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1287:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7155, + "indexed": false, + "name": "question_text", + "nodeType": "VariableDeclaration", + "scope": 7157, + "src": "1318:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 7154, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "1318:6:18", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "1240:104:18" + }, + "src": "1220:125:18" + }, + { + "anonymous": false, + "documentation": null, + "id": 7179, + "name": "LogNewQuestion", + "nodeType": "EventDefinition", + "parameters": { + "id": 7178, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7159, + "indexed": true, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7179, + "src": "1381:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7158, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1381:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7161, + "indexed": true, + "name": "user", + "nodeType": "VariableDeclaration", + "scope": 7179, + "src": "1418:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7160, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1418:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7163, + "indexed": false, + "name": "template_id", + "nodeType": "VariableDeclaration", + "scope": 7179, + "src": "1449:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7162, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1449:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7165, + "indexed": false, + "name": "question", + "nodeType": "VariableDeclaration", + "scope": 7179, + "src": "1478:15:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 7164, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "1478:6:18", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7167, + "indexed": true, + "name": "content_hash", + "nodeType": "VariableDeclaration", + "scope": 7179, + "src": "1503:28:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7166, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1503:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7169, + "indexed": false, + "name": "arbitrator", + "nodeType": "VariableDeclaration", + "scope": 7179, + "src": "1541:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7168, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1541:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7171, + "indexed": false, + "name": "timeout", + "nodeType": "VariableDeclaration", + "scope": 7179, + "src": "1570:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7170, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "1570:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7173, + "indexed": false, + "name": "opening_ts", + "nodeType": "VariableDeclaration", + "scope": 7179, + "src": "1594:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7172, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "1594:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7175, + "indexed": false, + "name": "nonce", + "nodeType": "VariableDeclaration", + "scope": 7179, + "src": "1621:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7174, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1621:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7177, + "indexed": false, + "name": "created", + "nodeType": "VariableDeclaration", + "scope": 7179, + "src": "1644:15:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7176, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1644:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "1371:294:18" + }, + "src": "1351:315:18" + }, + { + "anonymous": false, + "documentation": null, + "id": 7189, + "name": "LogFundAnswerBounty", + "nodeType": "EventDefinition", + "parameters": { + "id": 7188, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7181, + "indexed": true, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7189, + "src": "1707:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7180, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1707:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7183, + "indexed": false, + "name": "bounty_added", + "nodeType": "VariableDeclaration", + "scope": 7189, + "src": "1744:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7182, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1744:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7185, + "indexed": false, + "name": "bounty", + "nodeType": "VariableDeclaration", + "scope": 7189, + "src": "1774:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7184, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1774:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7187, + "indexed": true, + "name": "user", + "nodeType": "VariableDeclaration", + "scope": 7189, + "src": "1798:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7186, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1798:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "1697:128:18" + }, + "src": "1672:154:18" + }, + { + "anonymous": false, + "documentation": null, + "id": 7205, + "name": "LogNewAnswer", + "nodeType": "EventDefinition", + "parameters": { + "id": 7204, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7191, + "indexed": false, + "name": "answer", + "nodeType": "VariableDeclaration", + "scope": 7205, + "src": "1860:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7190, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1860:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7193, + "indexed": true, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7205, + "src": "1884:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7192, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1884:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7195, + "indexed": false, + "name": "history_hash", + "nodeType": "VariableDeclaration", + "scope": 7205, + "src": "1921:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7194, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1921:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7197, + "indexed": true, + "name": "user", + "nodeType": "VariableDeclaration", + "scope": 7205, + "src": "1951:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7196, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1951:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7199, + "indexed": false, + "name": "bond", + "nodeType": "VariableDeclaration", + "scope": 7205, + "src": "1981:12:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7198, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1981:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7201, + "indexed": false, + "name": "ts", + "nodeType": "VariableDeclaration", + "scope": 7205, + "src": "2003:10:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7200, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2003:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7203, + "indexed": false, + "name": "is_commitment", + "nodeType": "VariableDeclaration", + "scope": 7205, + "src": "2023:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 7202, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2023:4:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "1850:197:18" + }, + "src": "1832:216:18" + }, + { + "anonymous": false, + "documentation": null, + "id": 7219, + "name": "LogAnswerReveal", + "nodeType": "EventDefinition", + "parameters": { + "id": 7218, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7207, + "indexed": true, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7219, + "src": "2085:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7206, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2085:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7209, + "indexed": true, + "name": "user", + "nodeType": "VariableDeclaration", + "scope": 7219, + "src": "2123:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7208, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2123:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7211, + "indexed": true, + "name": "answer_hash", + "nodeType": "VariableDeclaration", + "scope": 7219, + "src": "2154:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7210, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2154:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7213, + "indexed": false, + "name": "answer", + "nodeType": "VariableDeclaration", + "scope": 7219, + "src": "2192:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7212, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2192:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7215, + "indexed": false, + "name": "nonce", + "nodeType": "VariableDeclaration", + "scope": 7219, + "src": "2217:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7214, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2217:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7217, + "indexed": false, + "name": "bond", + "nodeType": "VariableDeclaration", + "scope": 7219, + "src": "2241:12:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7216, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2241:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2075:184:18" + }, + "src": "2054:206:18" + }, + { + "anonymous": false, + "documentation": null, + "id": 7225, + "name": "LogNotifyOfArbitrationRequest", + "nodeType": "EventDefinition", + "parameters": { + "id": 7224, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7221, + "indexed": true, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7225, + "src": "2311:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7220, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2311:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7223, + "indexed": true, + "name": "user", + "nodeType": "VariableDeclaration", + "scope": 7225, + "src": "2348:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7222, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2348:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2301:74:18" + }, + "src": "2266:110:18" + }, + { + "anonymous": false, + "documentation": null, + "id": 7229, + "name": "LogCancelArbitration", + "nodeType": "EventDefinition", + "parameters": { + "id": 7228, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7227, + "indexed": true, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7229, + "src": "2418:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7226, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2418:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2408:43:18" + }, + "src": "2382:70:18" + }, + { + "anonymous": false, + "documentation": null, + "id": 7235, + "name": "LogFinalize", + "nodeType": "EventDefinition", + "parameters": { + "id": 7234, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7231, + "indexed": true, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7235, + "src": "2485:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7230, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2485:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7233, + "indexed": true, + "name": "answer", + "nodeType": "VariableDeclaration", + "scope": 7235, + "src": "2522:22:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7232, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2522:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2475:75:18" + }, + "src": "2458:93:18" + }, + { + "anonymous": false, + "documentation": null, + "id": 7243, + "name": "LogClaim", + "nodeType": "EventDefinition", + "parameters": { + "id": 7242, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7237, + "indexed": true, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7243, + "src": "2581:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7236, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2581:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7239, + "indexed": true, + "name": "user", + "nodeType": "VariableDeclaration", + "scope": 7243, + "src": "2618:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7238, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2618:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7241, + "indexed": false, + "name": "amount", + "nodeType": "VariableDeclaration", + "scope": 7243, + "src": "2648:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7240, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2648:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2571:97:18" + }, + "src": "2557:112:18" + }, + { + "canonicalName": "Realitio_v2_1.Question", + "id": 7264, + "members": [ + { + "constant": false, + "id": 7245, + "name": "content_hash", + "nodeType": "VariableDeclaration", + "scope": 7264, + "src": "2701:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7244, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2701:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7247, + "name": "arbitrator", + "nodeType": "VariableDeclaration", + "scope": 7264, + "src": "2731:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7246, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2731:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7249, + "name": "opening_ts", + "nodeType": "VariableDeclaration", + "scope": 7264, + "src": "2759:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7248, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "2759:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7251, + "name": "timeout", + "nodeType": "VariableDeclaration", + "scope": 7264, + "src": "2786:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7250, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "2786:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7253, + "name": "finalize_ts", + "nodeType": "VariableDeclaration", + "scope": 7264, + "src": "2810:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7252, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "2810:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7255, + "name": "is_pending_arbitration", + "nodeType": "VariableDeclaration", + "scope": 7264, + "src": "2838:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 7254, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2838:4:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7257, + "name": "bounty", + "nodeType": "VariableDeclaration", + "scope": 7264, + "src": "2875:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7256, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2875:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7259, + "name": "best_answer", + "nodeType": "VariableDeclaration", + "scope": 7264, + "src": "2899:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7258, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2899:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7261, + "name": "history_hash", + "nodeType": "VariableDeclaration", + "scope": 7264, + "src": "2928:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7260, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2928:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7263, + "name": "bond", + "nodeType": "VariableDeclaration", + "scope": 7264, + "src": "2958:12:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7262, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2958:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "name": "Question", + "nodeType": "StructDefinition", + "scope": 9314, + "src": "2675:302:18", + "visibility": "public" + }, + { + "canonicalName": "Realitio_v2_1.Commitment", + "id": 7271, + "members": [ + { + "constant": false, + "id": 7266, + "name": "reveal_ts", + "nodeType": "VariableDeclaration", + "scope": 7271, + "src": "3108:16:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7265, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "3108:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7268, + "name": "is_revealed", + "nodeType": "VariableDeclaration", + "scope": 7271, + "src": "3134:16:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 7267, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "3134:4:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7270, + "name": "revealed_answer", + "nodeType": "VariableDeclaration", + "scope": 7271, + "src": "3160:23:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7269, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3160:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "name": "Commitment", + "nodeType": "StructDefinition", + "scope": 9314, + "src": "3080:110:18", + "visibility": "public" + }, + { + "canonicalName": "Realitio_v2_1.Claim", + "id": 7278, + "members": [ + { + "constant": false, + "id": 7273, + "name": "payee", + "nodeType": "VariableDeclaration", + "scope": 7278, + "src": "3341:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7272, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3341:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7275, + "name": "last_bond", + "nodeType": "VariableDeclaration", + "scope": 7278, + "src": "3364:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7274, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3364:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7277, + "name": "queued_funds", + "nodeType": "VariableDeclaration", + "scope": 7278, + "src": "3391:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7276, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3391:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "name": "Claim", + "nodeType": "StructDefinition", + "scope": 9314, + "src": "3318:100:18", + "visibility": "public" + }, + { + "constant": false, + "id": 7281, + "name": "nextTemplateID", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "3424:26:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7279, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3424:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "30", + "id": 7280, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3449:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 7285, + "name": "templates", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "3456:44:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint256_$_t_uint256_$", + "typeString": "mapping(uint256 => uint256)" + }, + "typeName": { + "id": 7284, + "keyType": { + "id": 7282, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3464:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Mapping", + "src": "3456:27:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint256_$_t_uint256_$", + "typeString": "mapping(uint256 => uint256)" + }, + "valueType": { + "id": 7283, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3475:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": false, + "id": 7289, + "name": "template_hashes", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "3506:50:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint256_$_t_bytes32_$", + "typeString": "mapping(uint256 => bytes32)" + }, + "typeName": { + "id": 7288, + "keyType": { + "id": 7286, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3514:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Mapping", + "src": "3506:27:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint256_$_t_bytes32_$", + "typeString": "mapping(uint256 => bytes32)" + }, + "valueType": { + "id": 7287, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3525:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": false, + "id": 7293, + "name": "questions", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "3562:45:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question)" + }, + "typeName": { + "id": 7292, + "keyType": { + "id": 7290, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3570:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Mapping", + "src": "3562:28:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question)" + }, + "valueType": { + "contractScope": null, + "id": 7291, + "name": "Question", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 7264, + "src": "3581:8:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage_ptr", + "typeString": "struct Realitio_v2_1.Question" + } + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": false, + "id": 7297, + "name": "question_claims", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "3613:48:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Claim_$7278_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Claim)" + }, + "typeName": { + "id": 7296, + "keyType": { + "id": 7294, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3621:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Mapping", + "src": "3613:25:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Claim_$7278_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Claim)" + }, + "valueType": { + "contractScope": null, + "id": 7295, + "name": "Claim", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 7278, + "src": "3632:5:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Claim_$7278_storage_ptr", + "typeString": "struct Realitio_v2_1.Claim" + } + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": false, + "id": 7301, + "name": "commitments", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "3667:49:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment)" + }, + "typeName": { + "id": 7300, + "keyType": { + "id": 7298, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3675:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Mapping", + "src": "3667:30:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment)" + }, + "valueType": { + "contractScope": null, + "id": 7299, + "name": "Commitment", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 7271, + "src": "3686:10:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage_ptr", + "typeString": "struct Realitio_v2_1.Commitment" + } + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": false, + "id": 7305, + "name": "arbitrator_question_fees", + "nodeType": "VariableDeclaration", + "scope": 9314, + "src": "3722:59:18", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + }, + "typeName": { + "id": 7304, + "keyType": { + "id": 7302, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3730:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Mapping", + "src": "3722:27:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + }, + "valueType": { + "id": 7303, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3741:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + }, + "value": null, + "visibility": "public" + }, + { + "body": { + "id": 7321, + "nodeType": "Block", + "src": "3834:117:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 7316, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7310, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "3852:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7311, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "3852:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7312, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "3866:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7314, + "indexExpression": { + "argumentTypes": null, + "id": 7313, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7307, + "src": "3876:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "3866:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7315, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "arbitrator", + "nodeType": "MemberAccess", + "referencedDeclaration": 7247, + "src": "3866:33:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "3852:47:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "6d73672e73656e646572206d7573742062652061726269747261746f72", + "id": 7317, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3901:31:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_5af564fa249397c704c7c39694db25de233707a7dfa60dd4e063a5865f683bf0", + "typeString": "literal_string \"msg.sender must be arbitrator\"" + }, + "value": "msg.sender must be arbitrator" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_5af564fa249397c704c7c39694db25de233707a7dfa60dd4e063a5865f683bf0", + "typeString": "literal_string \"msg.sender must be arbitrator\"" + } + ], + "id": 7309, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "3844:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7318, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3844:89:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7319, + "nodeType": "ExpressionStatement", + "src": "3844:89:18" + }, + { + "id": 7320, + "nodeType": "PlaceholderStatement", + "src": "3943:1:18" + } + ] + }, + "documentation": null, + "id": 7322, + "name": "onlyArbitrator", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 7308, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7307, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7322, + "src": "3813:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7306, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3813:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "3812:21:18" + }, + "src": "3789:162:18", + "visibility": "internal" + }, + { + "body": { + "id": 7325, + "nodeType": "Block", + "src": "3977:18:18", + "statements": [ + { + "id": 7324, + "nodeType": "PlaceholderStatement", + "src": "3987:1:18" + } + ] + }, + "documentation": null, + "id": 7326, + "name": "stateAny", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 7323, + "nodeType": "ParameterList", + "parameters": [], + "src": "3974:2:18" + }, + "src": "3957:38:18", + "visibility": "internal" + }, + { + "body": { + "id": 7341, + "nodeType": "Block", + "src": "4047:99:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7336, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7331, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "4065:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7333, + "indexExpression": { + "argumentTypes": null, + "id": 7332, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7328, + "src": "4075:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "4065:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7334, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timeout", + "nodeType": "MemberAccess", + "referencedDeclaration": 7251, + "src": "4065:30:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 7335, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4099:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "4065:35:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "7175657374696f6e206d757374206e6f74206578697374", + "id": 7337, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4102:25:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_9422abd8923f5fcae9417fb15deac6177aedec6abb4620f33db030efb4ed0419", + "typeString": "literal_string \"question must not exist\"" + }, + "value": "question must not exist" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_9422abd8923f5fcae9417fb15deac6177aedec6abb4620f33db030efb4ed0419", + "typeString": "literal_string \"question must not exist\"" + } + ], + "id": 7330, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "4057:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7338, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4057:71:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7339, + "nodeType": "ExpressionStatement", + "src": "4057:71:18" + }, + { + "id": 7340, + "nodeType": "PlaceholderStatement", + "src": "4138:1:18" + } + ] + }, + "documentation": null, + "id": 7342, + "name": "stateNotCreated", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 7329, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7328, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7342, + "src": "4026:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7327, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "4026:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "4025:21:18" + }, + "src": "4001:145:18", + "visibility": "internal" + }, + { + "body": { + "id": 7406, + "nodeType": "Block", + "src": "4192:547:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7352, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7347, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "4210:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7349, + "indexExpression": { + "argumentTypes": null, + "id": 7348, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7344, + "src": "4220:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "4210:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7350, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timeout", + "nodeType": "MemberAccess", + "referencedDeclaration": 7251, + "src": "4210:30:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 7351, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4243:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "4210:34:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "7175657374696f6e206d757374206578697374", + "id": 7353, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4246:21:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_472769862e940c55535785d7e47562583d0c118be9a62024347d29ed8338806b", + "typeString": "literal_string \"question must exist\"" + }, + "value": "question must exist" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_472769862e940c55535785d7e47562583d0c118be9a62024347d29ed8338806b", + "typeString": "literal_string \"question must exist\"" + } + ], + "id": 7346, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "4202:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7354, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4202:66:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7355, + "nodeType": "ExpressionStatement", + "src": "4202:66:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7361, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "4286:46:18", + "subExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7357, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "4287:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7359, + "indexExpression": { + "argumentTypes": null, + "id": 7358, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7344, + "src": "4297:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "4287:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7360, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "is_pending_arbitration", + "nodeType": "MemberAccess", + "referencedDeclaration": 7255, + "src": "4287:45:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "7175657374696f6e206d757374206e6f742062652070656e64696e67206172626974726174696f6e", + "id": 7362, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4334:42:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_e0d7c56d5455922671038afc010672319828847765f75d021ca63b233340fb79", + "typeString": "literal_string \"question must not be pending arbitration\"" + }, + "value": "question must not be pending arbitration" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_e0d7c56d5455922671038afc010672319828847765f75d021ca63b233340fb79", + "typeString": "literal_string \"question must not be pending arbitration\"" + } + ], + "id": 7356, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "4278:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7363, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4278:99:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7364, + "nodeType": "ExpressionStatement", + "src": "4278:99:18" + }, + { + "assignments": [ + 7366 + ], + "declarations": [ + { + "constant": false, + "id": 7366, + "name": "finalize_ts", + "nodeType": "VariableDeclaration", + "scope": 7407, + "src": "4387:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7365, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "4387:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 7371, + "initialValue": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7367, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "4408:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7369, + "indexExpression": { + "argumentTypes": null, + "id": 7368, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7344, + "src": "4418:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "4408:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7370, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "finalize_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7253, + "src": "4408:34:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "4387:55:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 7381, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7375, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7373, + "name": "finalize_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7366, + "src": "4460:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 7374, + "name": "UNANSWERED", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7134, + "src": "4475:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "4460:25:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "||", + "rightExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7380, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7376, + "name": "finalize_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7366, + "src": "4489:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7378, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "4510:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 7377, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "4503:6:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint32_$", + "typeString": "type(uint32)" + }, + "typeName": "uint32" + }, + "id": 7379, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4503:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "4489:25:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "4460:54:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "66696e616c697a6174696f6e20646561646c696e65206d757374206e6f74206861766520706173736564", + "id": 7382, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4516:44:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_381ca4d13deaf278dc64e461f023657740bec9f7b7a71cf63c10807ee5f2d777", + "typeString": "literal_string \"finalization deadline must not have passed\"" + }, + "value": "finalization deadline must not have passed" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_381ca4d13deaf278dc64e461f023657740bec9f7b7a71cf63c10807ee5f2d777", + "typeString": "literal_string \"finalization deadline must not have passed\"" + } + ], + "id": 7372, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "4452:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7383, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4452:109:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7384, + "nodeType": "ExpressionStatement", + "src": "4452:109:18" + }, + { + "assignments": [ + 7386 + ], + "declarations": [ + { + "constant": false, + "id": 7386, + "name": "opening_ts", + "nodeType": "VariableDeclaration", + "scope": 7407, + "src": "4571:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7385, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "4571:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 7391, + "initialValue": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7387, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "4591:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7389, + "indexExpression": { + "argumentTypes": null, + "id": 7388, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7344, + "src": "4601:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "4591:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7390, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "opening_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7249, + "src": "4591:33:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "4571:53:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 7401, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7395, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7393, + "name": "opening_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7386, + "src": "4642:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 7394, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4656:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "4642:15:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "||", + "rightExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7400, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7396, + "name": "opening_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7386, + "src": "4661:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7398, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "4682:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 7397, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "4675:6:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint32_$", + "typeString": "type(uint32)" + }, + "typeName": "uint32" + }, + "id": 7399, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4675:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "4661:25:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "4642:44:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "6f70656e696e672064617465206d757374206861766520706173736564", + "id": 7402, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4688:31:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_5963fbf852ce76142d772c6ce4c8614e81ba76b348890013b4cd0addd58b31b3", + "typeString": "literal_string \"opening date must have passed\"" + }, + "value": "opening date must have passed" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_5963fbf852ce76142d772c6ce4c8614e81ba76b348890013b4cd0addd58b31b3", + "typeString": "literal_string \"opening date must have passed\"" + } + ], + "id": 7392, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "4634:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7403, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4634:86:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7404, + "nodeType": "ExpressionStatement", + "src": "4634:86:18" + }, + { + "id": 7405, + "nodeType": "PlaceholderStatement", + "src": "4731:1:18" + } + ] + }, + "documentation": null, + "id": 7407, + "name": "stateOpen", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 7345, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7344, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7407, + "src": "4171:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7343, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "4171:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "4170:21:18" + }, + "src": "4152:587:18", + "visibility": "internal" + }, + { + "body": { + "id": 7420, + "nodeType": "Block", + "src": "4799:122:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7412, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "4817:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7414, + "indexExpression": { + "argumentTypes": null, + "id": 7413, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7409, + "src": "4827:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "4817:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7415, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "is_pending_arbitration", + "nodeType": "MemberAccess", + "referencedDeclaration": 7255, + "src": "4817:45:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "7175657374696f6e206d7573742062652070656e64696e67206172626974726174696f6e", + "id": 7416, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4864:38:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_4f7d8d6d43d9c6b0643db0ab03bfd160dd192eaa68b6c3b38d0d94803ffac248", + "typeString": "literal_string \"question must be pending arbitration\"" + }, + "value": "question must be pending arbitration" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_4f7d8d6d43d9c6b0643db0ab03bfd160dd192eaa68b6c3b38d0d94803ffac248", + "typeString": "literal_string \"question must be pending arbitration\"" + } + ], + "id": 7411, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "4809:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7417, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4809:94:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7418, + "nodeType": "ExpressionStatement", + "src": "4809:94:18" + }, + { + "id": 7419, + "nodeType": "PlaceholderStatement", + "src": "4913:1:18" + } + ] + }, + "documentation": null, + "id": 7421, + "name": "statePendingArbitration", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 7410, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7409, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7421, + "src": "4778:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7408, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "4778:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "4777:21:18" + }, + "src": "4745:176:18", + "visibility": "internal" + }, + { + "body": { + "id": 7476, + "nodeType": "Block", + "src": "4987:437:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7431, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7426, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "5005:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7428, + "indexExpression": { + "argumentTypes": null, + "id": 7427, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7423, + "src": "5015:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "5005:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7429, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timeout", + "nodeType": "MemberAccess", + "referencedDeclaration": 7251, + "src": "5005:30:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 7430, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5038:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "5005:34:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "7175657374696f6e206d757374206578697374", + "id": 7432, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5041:21:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_472769862e940c55535785d7e47562583d0c118be9a62024347d29ed8338806b", + "typeString": "literal_string \"question must exist\"" + }, + "value": "question must exist" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_472769862e940c55535785d7e47562583d0c118be9a62024347d29ed8338806b", + "typeString": "literal_string \"question must exist\"" + } + ], + "id": 7425, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "4997:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7433, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4997:66:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7434, + "nodeType": "ExpressionStatement", + "src": "4997:66:18" + }, + { + "assignments": [ + 7436 + ], + "declarations": [ + { + "constant": false, + "id": 7436, + "name": "finalize_ts", + "nodeType": "VariableDeclaration", + "scope": 7477, + "src": "5073:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7435, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "5073:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 7441, + "initialValue": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7437, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "5094:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7439, + "indexExpression": { + "argumentTypes": null, + "id": 7438, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7423, + "src": "5104:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "5094:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7440, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "finalize_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7253, + "src": "5094:34:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "5073:55:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 7451, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7445, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7443, + "name": "finalize_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7436, + "src": "5146:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 7444, + "name": "UNANSWERED", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7134, + "src": "5161:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "5146:25:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "||", + "rightExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7450, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7446, + "name": "finalize_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7436, + "src": "5175:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7448, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "5196:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 7447, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "5189:6:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint32_$", + "typeString": "type(uint32)" + }, + "typeName": "uint32" + }, + "id": 7449, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5189:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "5175:25:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "5146:54:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "66696e616c697a6174696f6e206465616c696e65206d757374206e6f74206861766520706173736564", + "id": 7452, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5202:43:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_8f540895d8d15453e87897307cb8351f2857abfee4e235e10c3b3c286692a622", + "typeString": "literal_string \"finalization dealine must not have passed\"" + }, + "value": "finalization dealine must not have passed" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_8f540895d8d15453e87897307cb8351f2857abfee4e235e10c3b3c286692a622", + "typeString": "literal_string \"finalization dealine must not have passed\"" + } + ], + "id": 7442, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "5138:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7453, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5138:108:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7454, + "nodeType": "ExpressionStatement", + "src": "5138:108:18" + }, + { + "assignments": [ + 7456 + ], + "declarations": [ + { + "constant": false, + "id": 7456, + "name": "opening_ts", + "nodeType": "VariableDeclaration", + "scope": 7477, + "src": "5256:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7455, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "5256:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 7461, + "initialValue": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7457, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "5276:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7459, + "indexExpression": { + "argumentTypes": null, + "id": 7458, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7423, + "src": "5286:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "5276:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7460, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "opening_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7249, + "src": "5276:33:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "5256:53:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 7471, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7465, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7463, + "name": "opening_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7456, + "src": "5327:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 7464, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5341:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "5327:15:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "||", + "rightExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7470, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7466, + "name": "opening_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7456, + "src": "5346:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7468, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "5367:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 7467, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "5360:6:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint32_$", + "typeString": "type(uint32)" + }, + "typeName": "uint32" + }, + "id": 7469, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5360:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "5346:25:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "5327:44:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "6f70656e696e672064617465206d757374206861766520706173736564", + "id": 7472, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5373:31:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_5963fbf852ce76142d772c6ce4c8614e81ba76b348890013b4cd0addd58b31b3", + "typeString": "literal_string \"opening date must have passed\"" + }, + "value": "opening date must have passed" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_5963fbf852ce76142d772c6ce4c8614e81ba76b348890013b4cd0addd58b31b3", + "typeString": "literal_string \"opening date must have passed\"" + } + ], + "id": 7462, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "5319:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7473, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5319:86:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7474, + "nodeType": "ExpressionStatement", + "src": "5319:86:18" + }, + { + "id": 7475, + "nodeType": "PlaceholderStatement", + "src": "5416:1:18" + } + ] + }, + "documentation": null, + "id": 7477, + "name": "stateOpenOrPendingArbitration", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 7424, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7423, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7477, + "src": "4966:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7422, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "4966:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "4965:21:18" + }, + "src": "4927:497:18", + "visibility": "internal" + }, + { + "body": { + "id": 7489, + "nodeType": "Block", + "src": "5475:91:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7483, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7479, + "src": "5505:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 7482, + "name": "isFinalized", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8507, + "src": "5493:11:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$returns$_t_bool_$", + "typeString": "function (bytes32) view returns (bool)" + } + }, + "id": 7484, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5493:24:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "7175657374696f6e206d7573742062652066696e616c697a6564", + "id": 7485, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5519:28:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_7678ea862d4110864dbd24145ec43051bb85f78d8eeb3bbb14a3533dd60847c8", + "typeString": "literal_string \"question must be finalized\"" + }, + "value": "question must be finalized" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_7678ea862d4110864dbd24145ec43051bb85f78d8eeb3bbb14a3533dd60847c8", + "typeString": "literal_string \"question must be finalized\"" + } + ], + "id": 7481, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "5485:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7486, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5485:63:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7487, + "nodeType": "ExpressionStatement", + "src": "5485:63:18" + }, + { + "id": 7488, + "nodeType": "PlaceholderStatement", + "src": "5558:1:18" + } + ] + }, + "documentation": null, + "id": 7490, + "name": "stateFinalized", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 7480, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7479, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7490, + "src": "5454:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7478, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "5454:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "5453:21:18" + }, + "src": "5430:136:18", + "visibility": "internal" + }, + { + "body": { + "id": 7518, + "nodeType": "Block", + "src": "5617:190:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 7498, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7495, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "5635:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7496, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "5635:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 7497, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5647:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "5635:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "626f6e64206d75737420626520706f736974697665", + "id": 7499, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5650:23:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_b3c9ee472042e2067e6f11b009a7238c6ed21a4872f0b12d2abbe4092d3c0b88", + "typeString": "literal_string \"bond must be positive\"" + }, + "value": "bond must be positive" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_b3c9ee472042e2067e6f11b009a7238c6ed21a4872f0b12d2abbe4092d3c0b88", + "typeString": "literal_string \"bond must be positive\"" + } + ], + "id": 7494, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "5627:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7500, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5627:47:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7501, + "nodeType": "ExpressionStatement", + "src": "5627:47:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 7513, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7503, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "5693:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7504, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "5693:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "32", + "id": 7510, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5739:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + } + ], + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7505, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "5707:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7507, + "indexExpression": { + "argumentTypes": null, + "id": 7506, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7492, + "src": "5717:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "5707:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7508, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bond", + "nodeType": "MemberAccess", + "referencedDeclaration": 7263, + "src": "5707:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7509, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "mul", + "nodeType": "MemberAccess", + "referencedDeclaration": 7018, + "src": "5707:31:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 7511, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5707:34:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 7512, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "5706:36:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "5693:49:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "626f6e64206d75737420626520646f75626c65206174206c656173742070726576696f757320626f6e64", + "id": 7514, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5744:44:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_65ffa1219e4f08f995c93eadfebcd61b4db428d3222f9b65896f079b3b960d3d", + "typeString": "literal_string \"bond must be double at least previous bond\"" + }, + "value": "bond must be double at least previous bond" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_65ffa1219e4f08f995c93eadfebcd61b4db428d3222f9b65896f079b3b960d3d", + "typeString": "literal_string \"bond must be double at least previous bond\"" + } + ], + "id": 7502, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "5685:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7515, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5685:104:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7516, + "nodeType": "ExpressionStatement", + "src": "5685:104:18" + }, + { + "id": 7517, + "nodeType": "PlaceholderStatement", + "src": "5799:1:18" + } + ] + }, + "documentation": null, + "id": 7519, + "name": "bondMustDouble", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 7493, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7492, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7519, + "src": "5596:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7491, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "5596:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "5595:21:18" + }, + "src": "5572:235:18", + "visibility": "internal" + }, + { + "body": { + "id": 7541, + "nodeType": "Block", + "src": "5900:159:18", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 7527, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7525, + "name": "max_previous", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7523, + "src": "5914:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 7526, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5929:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "5914:16:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 7539, + "nodeType": "IfStatement", + "src": "5910:132:18", + "trueBody": { + "id": 7538, + "nodeType": "Block", + "src": "5932:110:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 7534, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7529, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "5954:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7531, + "indexExpression": { + "argumentTypes": null, + "id": 7530, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7521, + "src": "5964:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "5954:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7532, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bond", + "nodeType": "MemberAccess", + "referencedDeclaration": 7263, + "src": "5954:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "id": 7533, + "name": "max_previous", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7523, + "src": "5985:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "5954:43:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "626f6e64206d75737420657863656564206d61785f70726576696f7573", + "id": 7535, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5999:31:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_86da50f4411a4001f63186489f5e9177ab1df516512e13b6a709fd5c2385c100", + "typeString": "literal_string \"bond must exceed max_previous\"" + }, + "value": "bond must exceed max_previous" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_86da50f4411a4001f63186489f5e9177ab1df516512e13b6a709fd5c2385c100", + "typeString": "literal_string \"bond must exceed max_previous\"" + } + ], + "id": 7528, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "5946:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7536, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5946:85:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7537, + "nodeType": "ExpressionStatement", + "src": "5946:85:18" + } + ] + } + }, + { + "id": 7540, + "nodeType": "PlaceholderStatement", + "src": "6051:1:18" + } + ] + }, + "documentation": null, + "id": 7542, + "name": "previousBondMustNotBeatMaxPrevious", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 7524, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7521, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7542, + "src": "5857:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7520, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "5857:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7523, + "name": "max_previous", + "nodeType": "VariableDeclaration", + "scope": 7542, + "src": "5878:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7522, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "5878:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "5856:43:18" + }, + "src": "5813:246:18", + "visibility": "internal" + }, + { + "body": { + "id": 7565, + "nodeType": "Block", + "src": "6246:538:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "7b227469746c65223a20222573222c202274797065223a2022626f6f6c222c202263617465676f7279223a20222573222c20226c616e67223a20222573227d", + "id": 7546, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6271:65:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_2630d91f54445fa42ec6738610b1a4c52b08a197156ab2ed97e4e17201528f2f", + "typeString": "literal_string \"{\"title\": \"%s\", \"type\": \"bool\", \"category\": \"%s\", \"lang\": \"%s\"}\"" + }, + "value": "{\"title\": \"%s\", \"type\": \"bool\", \"category\": \"%s\", \"lang\": \"%s\"}" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_2630d91f54445fa42ec6738610b1a4c52b08a197156ab2ed97e4e17201528f2f", + "typeString": "literal_string \"{\"title\": \"%s\", \"type\": \"bool\", \"category\": \"%s\", \"lang\": \"%s\"}\"" + } + ], + "id": 7545, + "name": "createTemplate", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7635, + "src": "6256:14:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_string_memory_ptr_$returns$_t_uint256_$", + "typeString": "function (string memory) returns (uint256)" + } + }, + "id": 7547, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "6256:81:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7548, + "nodeType": "ExpressionStatement", + "src": "6256:81:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "7b227469746c65223a20222573222c202274797065223a202275696e74222c2022646563696d616c73223a2031382c202263617465676f7279223a20222573222c20226c616e67223a20222573227d", + "id": 7550, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6362:81:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_f006792a99a5de2495a30060356c53fdfd8cd04c53ad3402c5353035dc6b9589", + "typeString": "literal_string \"{\"title\": \"%s\", \"type\": \"uint\", \"decimals\": 18, \"category\": \"%s\", \"lang\": \"%s\"}\"" + }, + "value": "{\"title\": \"%s\", \"type\": \"uint\", \"decimals\": 18, \"category\": \"%s\", \"lang\": \"%s\"}" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_f006792a99a5de2495a30060356c53fdfd8cd04c53ad3402c5353035dc6b9589", + "typeString": "literal_string \"{\"title\": \"%s\", \"type\": \"uint\", \"decimals\": 18, \"category\": \"%s\", \"lang\": \"%s\"}\"" + } + ], + "id": 7549, + "name": "createTemplate", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7635, + "src": "6347:14:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_string_memory_ptr_$returns$_t_uint256_$", + "typeString": "function (string memory) returns (uint256)" + } + }, + "id": 7551, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "6347:97:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7552, + "nodeType": "ExpressionStatement", + "src": "6347:97:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "7b227469746c65223a20222573222c202274797065223a202273696e676c652d73656c656374222c20226f7574636f6d6573223a205b25735d2c202263617465676f7279223a20222573222c20226c616e67223a20222573227d", + "id": 7554, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6469:92:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_e49d22c3fb3eac70dc2d9d76aa17b7e4b487f2f4b7c683f3705b638453520000", + "typeString": "literal_string \"{\"title\": \"%s\", \"type\": \"single-select\", \"outcomes\": [%s], \"category\": \"%s\", \"lang\": \"%s\"}\"" + }, + "value": "{\"title\": \"%s\", \"type\": \"single-select\", \"outcomes\": [%s], \"category\": \"%s\", \"lang\": \"%s\"}" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_e49d22c3fb3eac70dc2d9d76aa17b7e4b487f2f4b7c683f3705b638453520000", + "typeString": "literal_string \"{\"title\": \"%s\", \"type\": \"single-select\", \"outcomes\": [%s], \"category\": \"%s\", \"lang\": \"%s\"}\"" + } + ], + "id": 7553, + "name": "createTemplate", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7635, + "src": "6454:14:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_string_memory_ptr_$returns$_t_uint256_$", + "typeString": "function (string memory) returns (uint256)" + } + }, + "id": 7555, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "6454:108:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7556, + "nodeType": "ExpressionStatement", + "src": "6454:108:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "7b227469746c65223a20222573222c202274797065223a20226d756c7469706c652d73656c656374222c20226f7574636f6d6573223a205b25735d2c202263617465676f7279223a20222573222c20226c616e67223a20222573227d", + "id": 7558, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6587:94:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_1d41a41b7d3550c01209c10495988bfa01dd2e86c5a3fae5f9dbc2ccde20c1a9", + "typeString": "literal_string \"{\"title\": \"%s\", \"type\": \"multiple-select\", \"outcomes\": [%s], \"category\": \"%s\", \"lang\": \"%s\"}\"" + }, + "value": "{\"title\": \"%s\", \"type\": \"multiple-select\", \"outcomes\": [%s], \"category\": \"%s\", \"lang\": \"%s\"}" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_1d41a41b7d3550c01209c10495988bfa01dd2e86c5a3fae5f9dbc2ccde20c1a9", + "typeString": "literal_string \"{\"title\": \"%s\", \"type\": \"multiple-select\", \"outcomes\": [%s], \"category\": \"%s\", \"lang\": \"%s\"}\"" + } + ], + "id": 7557, + "name": "createTemplate", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7635, + "src": "6572:14:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_string_memory_ptr_$returns$_t_uint256_$", + "typeString": "function (string memory) returns (uint256)" + } + }, + "id": 7559, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "6572:110:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7560, + "nodeType": "ExpressionStatement", + "src": "6572:110:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "7b227469746c65223a20222573222c202274797065223a20226461746574696d65222c202263617465676f7279223a20222573222c20226c616e67223a20222573227d", + "id": 7562, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6707:69:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_5b13a2ad9e4dfbf057ecf2c35d4152b61718a3ab46a14db63feb17b1515749ba", + "typeString": "literal_string \"{\"title\": \"%s\", \"type\": \"datetime\", \"category\": \"%s\", \"lang\": \"%s\"}\"" + }, + "value": "{\"title\": \"%s\", \"type\": \"datetime\", \"category\": \"%s\", \"lang\": \"%s\"}" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_5b13a2ad9e4dfbf057ecf2c35d4152b61718a3ab46a14db63feb17b1515749ba", + "typeString": "literal_string \"{\"title\": \"%s\", \"type\": \"datetime\", \"category\": \"%s\", \"lang\": \"%s\"}\"" + } + ], + "id": 7561, + "name": "createTemplate", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7635, + "src": "6692:14:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_string_memory_ptr_$returns$_t_uint256_$", + "typeString": "function (string memory) returns (uint256)" + } + }, + "id": 7563, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "6692:85:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7564, + "nodeType": "ExpressionStatement", + "src": "6692:85:18" + } + ] + }, + "documentation": "@notice Constructor, sets up some initial templates\n @dev Creates some generalized templates for different question types used in the DApp.", + "id": 7566, + "implemented": true, + "isConstructor": true, + "isDeclaredConst": false, + "modifiers": [], + "name": "", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 7543, + "nodeType": "ParameterList", + "parameters": [], + "src": "6231:2:18" + }, + "payable": false, + "returnParameters": { + "id": 7544, + "nodeType": "ParameterList", + "parameters": [], + "src": "6246:0:18" + }, + "scope": 9314, + "src": "6220:564:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 7586, + "nodeType": "Block", + "src": "7129:108:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 7578, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7573, + "name": "arbitrator_question_fees", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7305, + "src": "7139:24:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 7576, + "indexExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7574, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "7164:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7575, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7164:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "7139:36:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 7577, + "name": "fee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7568, + "src": "7178:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7139:42:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7579, + "nodeType": "ExpressionStatement", + "src": "7139:42:18" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7581, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "7214:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7582, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7214:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 7583, + "name": "fee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7568, + "src": "7226:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 7580, + "name": "LogSetQuestionFee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7149, + "src": "7196:17:18", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,uint256)" + } + }, + "id": 7584, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7196:34:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7585, + "nodeType": "EmitStatement", + "src": "7191:39:18" + } + ] + }, + "documentation": "@notice Function for arbitrator to set an optional per-question fee. \n @dev The per-question fee, charged when a question is asked, is intended as an anti-spam measure.\n @param fee The fee to be charged by the arbitrator when a question is asked", + "id": 7587, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [], + "id": 7571, + "modifierName": { + "argumentTypes": null, + "id": 7570, + "name": "stateAny", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7326, + "src": "7104:8:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "7104:10:18" + } + ], + "name": "setQuestionFee", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 7569, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7568, + "name": "fee", + "nodeType": "VariableDeclaration", + "scope": 7587, + "src": "7082:11:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7567, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "7082:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "7081:13:18" + }, + "payable": false, + "returnParameters": { + "id": 7572, + "nodeType": "ParameterList", + "parameters": [], + "src": "7129:0:18" + }, + "scope": 9314, + "src": "7058:179:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 7634, + "nodeType": "Block", + "src": "7706:259:18", + "statements": [ + { + "assignments": [ + 7597 + ], + "declarations": [ + { + "constant": false, + "id": 7597, + "name": "id", + "nodeType": "VariableDeclaration", + "scope": 7635, + "src": "7716:10:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7596, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "7716:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 7599, + "initialValue": { + "argumentTypes": null, + "id": 7598, + "name": "nextTemplateID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7281, + "src": "7729:14:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "7716:27:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 7605, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7600, + "name": "templates", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7285, + "src": "7753:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint256_$_t_uint256_$", + "typeString": "mapping(uint256 => uint256)" + } + }, + "id": 7602, + "indexExpression": { + "argumentTypes": null, + "id": 7601, + "name": "id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7597, + "src": "7763:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "7753:13:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7603, + "name": "block", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9706, + "src": "7769:5:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_block", + "typeString": "block" + } + }, + "id": 7604, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "number", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7769:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7753:28:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7606, + "nodeType": "ExpressionStatement", + "src": "7753:28:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 7616, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7607, + "name": "template_hashes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7289, + "src": "7791:15:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint256_$_t_bytes32_$", + "typeString": "mapping(uint256 => bytes32)" + } + }, + "id": 7609, + "indexExpression": { + "argumentTypes": null, + "id": 7608, + "name": "id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7597, + "src": "7807:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "7791:19:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7613, + "name": "content", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7589, + "src": "7840:7:18", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + ], + "expression": { + "argumentTypes": null, + "id": 7611, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9703, + "src": "7823:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 7612, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7823:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 7614, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7823:25:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 7610, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9710, + "src": "7813:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 7615, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7813:36:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "7791:58:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 7617, + "nodeType": "ExpressionStatement", + "src": "7791:58:18" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7619, + "name": "id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7597, + "src": "7879:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7620, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "7883:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7621, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7883:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 7622, + "name": "content", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7589, + "src": "7895:7:18", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + ], + "id": 7618, + "name": "LogNewTemplate", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7157, + "src": "7864:14:18", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_uint256_$_t_address_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (uint256,address,string memory)" + } + }, + "id": 7623, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7864:39:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7624, + "nodeType": "EmitStatement", + "src": "7859:44:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 7630, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 7625, + "name": "nextTemplateID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7281, + "src": "7913:14:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "31", + "id": 7628, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7937:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + } + ], + "expression": { + "argumentTypes": null, + "id": 7626, + "name": "id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7597, + "src": "7930:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7627, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 7080, + "src": "7930:6:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 7629, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7930:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7913:26:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7631, + "nodeType": "ExpressionStatement", + "src": "7913:26:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 7632, + "name": "id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7597, + "src": "7956:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 7595, + "id": 7633, + "nodeType": "Return", + "src": "7949:9:18" + } + ] + }, + "documentation": "@notice Create a reusable template, which should be a JSON document.\n Placeholders should use gettext() syntax, eg %s.\n @dev Template data is only stored in the event logs, but its block number is kept in contract storage.\n @param content The template content\n @return The ID of the newly-created template, which is created sequentially.", + "id": 7635, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [], + "id": 7592, + "modifierName": { + "argumentTypes": null, + "id": 7591, + "name": "stateAny", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7326, + "src": "7666:8:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "7666:10:18" + } + ], + "name": "createTemplate", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 7590, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7589, + "name": "content", + "nodeType": "VariableDeclaration", + "scope": 7635, + "src": "7641:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 7588, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "7641:6:18", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "7640:16:18" + }, + "payable": false, + "returnParameters": { + "id": 7595, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7594, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 7635, + "src": "7697:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7593, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "7697:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "7696:9:18" + }, + "scope": 9314, + "src": "7617:348:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 7667, + "nodeType": "Block", + "src": "9110:153:18", + "statements": [ + { + "assignments": [ + 7653 + ], + "declarations": [ + { + "constant": false, + "id": 7653, + "name": "template_id", + "nodeType": "VariableDeclaration", + "scope": 7668, + "src": "9120:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7652, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "9120:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 7657, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7655, + "name": "content", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7637, + "src": "9157:7:18", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + ], + "id": 7654, + "name": "createTemplate", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7635, + "src": "9142:14:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_string_memory_ptr_$returns$_t_uint256_$", + "typeString": "function (string memory) returns (uint256)" + } + }, + "id": 7656, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "9142:23:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "9120:45:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7659, + "name": "template_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7653, + "src": "9194:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 7660, + "name": "question", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7639, + "src": "9207:8:18", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + }, + { + "argumentTypes": null, + "id": 7661, + "name": "arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7641, + "src": "9217:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 7662, + "name": "timeout", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7643, + "src": "9229:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + { + "argumentTypes": null, + "id": 7663, + "name": "opening_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7645, + "src": "9238:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + { + "argumentTypes": null, + "id": 7664, + "name": "nonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7647, + "src": "9250:5:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 7658, + "name": "askQuestion", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7744, + "src": "9182:11:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_uint256_$_t_string_memory_ptr_$_t_address_$_t_uint32_$_t_uint32_$_t_uint256_$returns$_t_bytes32_$", + "typeString": "function (uint256,string memory,address,uint32,uint32,uint256) returns (bytes32)" + } + }, + "id": 7665, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "9182:74:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 7651, + "id": 7666, + "nodeType": "Return", + "src": "9175:81:18" + } + ] + }, + "documentation": "@notice Create a new reusable template and use it to ask a question\n @dev Template data is only stored in the event logs, but its block number is kept in contract storage.\n @param content The template content\n @param question A string containing the parameters that will be passed into the template to make the question\n @param arbitrator The arbitration contract that will have the final word on the answer if there is a dispute\n @param timeout How long the contract should wait after the answer is changed before finalizing on that answer\n @param opening_ts If set, the earliest time it should be possible to answer the question.\n @param nonce A user-specified nonce used in the question ID. Change it to repeat a question.\n @return The ID of the newly-created template, which is created sequentially.", + "id": 7668, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "createTemplateAndAskQuestion", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 7648, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7637, + "name": "content", + "nodeType": "VariableDeclaration", + "scope": 7668, + "src": "8886:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 7636, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "8886:6:18", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7639, + "name": "question", + "nodeType": "VariableDeclaration", + "scope": 7668, + "src": "8911:15:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 7638, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "8911:6:18", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7641, + "name": "arbitrator", + "nodeType": "VariableDeclaration", + "scope": 7668, + "src": "8928:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7640, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "8928:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7643, + "name": "timeout", + "nodeType": "VariableDeclaration", + "scope": 7668, + "src": "8948:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7642, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "8948:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7645, + "name": "opening_ts", + "nodeType": "VariableDeclaration", + "scope": 7668, + "src": "8964:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7644, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "8964:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7647, + "name": "nonce", + "nodeType": "VariableDeclaration", + "scope": 7668, + "src": "8983:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7646, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "8983:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "8876:127:18" + }, + "payable": true, + "returnParameters": { + "id": 7651, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7650, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 7668, + "src": "9101:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7649, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "9101:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "9100:9:18" + }, + "scope": 9314, + "src": "8839:424:18", + "stateMutability": "payable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 7743, + "nodeType": "Block", + "src": "10380:533:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 7690, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7686, + "name": "templates", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7285, + "src": "10399:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint256_$_t_uint256_$", + "typeString": "mapping(uint256 => uint256)" + } + }, + "id": 7688, + "indexExpression": { + "argumentTypes": null, + "id": 7687, + "name": "template_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7670, + "src": "10409:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10399:22:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 7689, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10424:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "10399:26:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "74656d706c617465206d757374206578697374", + "id": 7691, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10427:21:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_6b763f6fbc16e7da696107f42e85f1f46703aa651f9e70e97d489e8899582b16", + "typeString": "literal_string \"template must exist\"" + }, + "value": "template must exist" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_6b763f6fbc16e7da696107f42e85f1f46703aa651f9e70e97d489e8899582b16", + "typeString": "literal_string \"template must exist\"" + } + ], + "id": 7685, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "10391:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7692, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10391:58:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7693, + "nodeType": "ExpressionStatement", + "src": "10391:58:18" + }, + { + "assignments": [ + 7695 + ], + "declarations": [ + { + "constant": false, + "id": 7695, + "name": "content_hash", + "nodeType": "VariableDeclaration", + "scope": 7744, + "src": "10460:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7694, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "10460:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 7704, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7699, + "name": "template_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7670, + "src": "10510:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 7700, + "name": "opening_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7678, + "src": "10523:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + { + "argumentTypes": null, + "id": 7701, + "name": "question", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7672, + "src": "10535:8:18", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + ], + "expression": { + "argumentTypes": null, + "id": 7697, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9703, + "src": "10493:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 7698, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "10493:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 7702, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10493:51:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 7696, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9710, + "src": "10483:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 7703, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10483:62:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "10460:85:18" + }, + { + "assignments": [ + 7706 + ], + "declarations": [ + { + "constant": false, + "id": 7706, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7744, + "src": "10555:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7705, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "10555:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 7718, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7710, + "name": "content_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7695, + "src": "10604:12:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 7711, + "name": "arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7674, + "src": "10618:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 7712, + "name": "timeout", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7676, + "src": "10630:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7713, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "10639:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7714, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "10639:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 7715, + "name": "nonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7680, + "src": "10651:5:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 7708, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9703, + "src": "10587:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 7709, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "10587:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 7716, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10587:70:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 7707, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9710, + "src": "10577:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 7717, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10577:81:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "10555:103:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7720, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7706, + "src": "10682:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 7721, + "name": "content_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7695, + "src": "10695:12:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 7722, + "name": "arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7674, + "src": "10709:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 7723, + "name": "timeout", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7676, + "src": "10721:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + { + "argumentTypes": null, + "id": 7724, + "name": "opening_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7678, + "src": "10730:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + ], + "id": 7719, + "name": "_askQuestion", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7859, + "src": "10669:12:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_address_$_t_uint32_$_t_uint32_$returns$__$", + "typeString": "function (bytes32,bytes32,address,uint32,uint32)" + } + }, + "id": 7725, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10669:72:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7726, + "nodeType": "ExpressionStatement", + "src": "10669:72:18" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7728, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7706, + "src": "10771:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7729, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "10784:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7730, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "10784:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 7731, + "name": "template_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7670, + "src": "10796:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 7732, + "name": "question", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7672, + "src": "10809:8:18", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + }, + { + "argumentTypes": null, + "id": 7733, + "name": "content_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7695, + "src": "10819:12:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 7734, + "name": "arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7674, + "src": "10833:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 7735, + "name": "timeout", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7676, + "src": "10845:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + { + "argumentTypes": null, + "id": 7736, + "name": "opening_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7678, + "src": "10854:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + { + "argumentTypes": null, + "id": 7737, + "name": "nonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7680, + "src": "10866:5:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 7738, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "10873:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 7727, + "name": "LogNewQuestion", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7179, + "src": "10756:14:18", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_address_$_t_uint256_$_t_string_memory_ptr_$_t_bytes32_$_t_address_$_t_uint32_$_t_uint32_$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (bytes32,address,uint256,string memory,bytes32,address,uint32,uint32,uint256,uint256)" + } + }, + "id": 7739, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10756:121:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7740, + "nodeType": "EmitStatement", + "src": "10751:126:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 7741, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7706, + "src": "10895:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 7684, + "id": 7742, + "nodeType": "Return", + "src": "10888:18:18" + } + ] + }, + "documentation": "@notice Ask a new question and return the ID\n @dev Template data is only stored in the event logs, but its block number is kept in contract storage.\n @param template_id The ID number of the template the question will use\n @param question A string containing the parameters that will be passed into the template to make the question\n @param arbitrator The arbitration contract that will have the final word on the answer if there is a dispute\n @param timeout How long the contract should wait after the answer is changed before finalizing on that answer\n @param opening_ts If set, the earliest time it should be possible to answer the question.\n @param nonce A user-specified nonce used in the question ID. Change it to repeat a question.\n @return The ID of the newly-created question, created deterministically.", + "id": 7744, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "askQuestion", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 7681, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7670, + "name": "template_id", + "nodeType": "VariableDeclaration", + "scope": 7744, + "src": "10166:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7669, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "10166:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7672, + "name": "question", + "nodeType": "VariableDeclaration", + "scope": 7744, + "src": "10187:15:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 7671, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "10187:6:18", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7674, + "name": "arbitrator", + "nodeType": "VariableDeclaration", + "scope": 7744, + "src": "10204:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7673, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "10204:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7676, + "name": "timeout", + "nodeType": "VariableDeclaration", + "scope": 7744, + "src": "10224:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7675, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "10224:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7678, + "name": "opening_ts", + "nodeType": "VariableDeclaration", + "scope": 7744, + "src": "10240:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7677, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "10240:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7680, + "name": "nonce", + "nodeType": "VariableDeclaration", + "scope": 7744, + "src": "10259:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7679, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "10259:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "10165:108:18" + }, + "payable": true, + "returnParameters": { + "id": 7684, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7683, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 7744, + "src": "10371:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7682, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "10371:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "10370:9:18" + }, + "scope": 9314, + "src": "10145:768:18", + "stateMutability": "payable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 7858, + "nodeType": "Block", + "src": "11090:1316:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7763, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7761, + "name": "timeout", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7752, + "src": "11191:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 7762, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11201:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "11191:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "74696d656f7574206d75737420626520706f736974697665", + "id": 7764, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11204:26:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_21a6e8d6041a43652989cb6df398a64082bcb4cf008fb5cf0deefa1dfb00eaf0", + "typeString": "literal_string \"timeout must be positive\"" + }, + "value": "timeout must be positive" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_21a6e8d6041a43652989cb6df398a64082bcb4cf008fb5cf0deefa1dfb00eaf0", + "typeString": "literal_string \"timeout must be positive\"" + } + ], + "id": 7760, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "11183:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7765, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11183:48:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7766, + "nodeType": "ExpressionStatement", + "src": "11183:48:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 7770, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7768, + "name": "timeout", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7752, + "src": "11250:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "hexValue": "333635", + "id": 7769, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11260:8:18", + "subdenomination": "days", + "typeDescriptions": { + "typeIdentifier": "t_rational_31536000_by_1", + "typeString": "int_const 31536000" + }, + "value": "365" + }, + "src": "11250:18:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "74696d656f7574206d757374206265206c657373207468616e203336352064617973", + "id": 7771, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11270:36:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_d41c7cd8b163218b0d4e0b8fc4fae3eb6e53b50e3a40bd3b56ca7bc1b684a1e9", + "typeString": "literal_string \"timeout must be less than 365 days\"" + }, + "value": "timeout must be less than 365 days" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_d41c7cd8b163218b0d4e0b8fc4fae3eb6e53b50e3a40bd3b56ca7bc1b684a1e9", + "typeString": "literal_string \"timeout must be less than 365 days\"" + } + ], + "id": 7767, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "11242:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7772, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11242:65:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7773, + "nodeType": "ExpressionStatement", + "src": "11242:65:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 7777, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7775, + "name": "arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7750, + "src": "11326:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "id": 7776, + "name": "NULL_ADDRESS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7126, + "src": "11340:12:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "11326:26:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "61726269747261746f72206d75737420626520736574", + "id": 7778, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11354:24:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_41e3ac7303a8b1456ede85d1facc68e58dc10ca71a9ec24a5bab787499ac2a73", + "typeString": "literal_string \"arbitrator must be set\"" + }, + "value": "arbitrator must be set" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_41e3ac7303a8b1456ede85d1facc68e58dc10ca71a9ec24a5bab787499ac2a73", + "typeString": "literal_string \"arbitrator must be set\"" + } + ], + "id": 7774, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "11318:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7779, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11318:61:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7780, + "nodeType": "ExpressionStatement", + "src": "11318:61:18" + }, + { + "assignments": [ + 7782 + ], + "declarations": [ + { + "constant": false, + "id": 7782, + "name": "bounty", + "nodeType": "VariableDeclaration", + "scope": 7859, + "src": "11390:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7781, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11390:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 7785, + "initialValue": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7783, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "11407:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7784, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "11407:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "11390:26:18" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 7789, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7786, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "11808:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7787, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "11808:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "id": 7788, + "name": "arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7750, + "src": "11822:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "11808:24:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 7822, + "nodeType": "IfStatement", + "src": "11804:324:18", + "trueBody": { + "id": 7821, + "nodeType": "Block", + "src": "11834:294:18", + "statements": [ + { + "assignments": [ + 7791 + ], + "declarations": [ + { + "constant": false, + "id": 7791, + "name": "question_fee", + "nodeType": "VariableDeclaration", + "scope": 7859, + "src": "11848:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7790, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11848:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 7795, + "initialValue": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7792, + "name": "arbitrator_question_fees", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7305, + "src": "11871:24:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 7794, + "indexExpression": { + "argumentTypes": null, + "id": 7793, + "name": "arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7750, + "src": "11896:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "11871:36:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "11848:59:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 7799, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7797, + "name": "bounty", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7782, + "src": "11929:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": { + "argumentTypes": null, + "id": 7798, + "name": "question_fee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7791, + "src": "11939:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "11929:22:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4554482070726f7669646564206d75737420636f766572207175657374696f6e20666565", + "id": 7800, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11953:38:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_f563467593cc476b2eaa9803db9a434ac560eec51474d9492a841a55aff9878c", + "typeString": "literal_string \"ETH provided must cover question fee\"" + }, + "value": "ETH provided must cover question fee" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_f563467593cc476b2eaa9803db9a434ac560eec51474d9492a841a55aff9878c", + "typeString": "literal_string \"ETH provided must cover question fee\"" + } + ], + "id": 7796, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "11921:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7801, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11921:71:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7802, + "nodeType": "ExpressionStatement", + "src": "11921:71:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 7808, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 7803, + "name": "bounty", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7782, + "src": "12007:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7806, + "name": "question_fee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7791, + "src": "12027:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 7804, + "name": "bounty", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7782, + "src": "12016:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7805, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sub", + "nodeType": "MemberAccess", + "referencedDeclaration": 7056, + "src": "12016:10:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 7807, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12016:24:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "12007:33:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7809, + "nodeType": "ExpressionStatement", + "src": "12007:33:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 7819, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7810, + "name": "balanceOf", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 396, + "src": "12054:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 7812, + "indexExpression": { + "argumentTypes": null, + "id": 7811, + "name": "arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7750, + "src": "12064:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "12054:21:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7817, + "name": "question_fee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7791, + "src": "12104:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7813, + "name": "balanceOf", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 396, + "src": "12078:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 7815, + "indexExpression": { + "argumentTypes": null, + "id": 7814, + "name": "arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7750, + "src": "12088:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12078:21:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7816, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 7080, + "src": "12078:25:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 7818, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12078:39:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "12054:63:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7820, + "nodeType": "ExpressionStatement", + "src": "12054:63:18" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "id": 7828, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7823, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "12138:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7825, + "indexExpression": { + "argumentTypes": null, + "id": 7824, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7746, + "src": "12148:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12138:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7826, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "content_hash", + "nodeType": "MemberAccess", + "referencedDeclaration": 7245, + "src": "12138:35:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 7827, + "name": "content_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7748, + "src": "12176:12:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "12138:50:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 7829, + "nodeType": "ExpressionStatement", + "src": "12138:50:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 7835, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7830, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "12198:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7832, + "indexExpression": { + "argumentTypes": null, + "id": 7831, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7746, + "src": "12208:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12198:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7833, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "arbitrator", + "nodeType": "MemberAccess", + "referencedDeclaration": 7247, + "src": "12198:33:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 7834, + "name": "arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7750, + "src": "12234:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "12198:46:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 7836, + "nodeType": "ExpressionStatement", + "src": "12198:46:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 7842, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7837, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "12254:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7839, + "indexExpression": { + "argumentTypes": null, + "id": 7838, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7746, + "src": "12264:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12254:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7840, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "opening_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7249, + "src": "12254:33:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 7841, + "name": "opening_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7754, + "src": "12290:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "12254:46:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "id": 7843, + "nodeType": "ExpressionStatement", + "src": "12254:46:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 7849, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7844, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "12310:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7846, + "indexExpression": { + "argumentTypes": null, + "id": 7845, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7746, + "src": "12320:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12310:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7847, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "timeout", + "nodeType": "MemberAccess", + "referencedDeclaration": 7251, + "src": "12310:30:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 7848, + "name": "timeout", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7752, + "src": "12343:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "12310:40:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "id": 7850, + "nodeType": "ExpressionStatement", + "src": "12310:40:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 7856, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7851, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "12360:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7853, + "indexExpression": { + "argumentTypes": null, + "id": 7852, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7746, + "src": "12370:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12360:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7854, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "bounty", + "nodeType": "MemberAccess", + "referencedDeclaration": 7257, + "src": "12360:29:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 7855, + "name": "bounty", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7782, + "src": "12392:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "12360:38:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7857, + "nodeType": "ExpressionStatement", + "src": "12360:38:18" + } + ] + }, + "documentation": null, + "id": 7859, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 7757, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7746, + "src": "11064:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 7758, + "modifierName": { + "argumentTypes": null, + "id": 7756, + "name": "stateNotCreated", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7342, + "src": "11048:15:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "11048:28:18" + } + ], + "name": "_askQuestion", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 7755, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7746, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7859, + "src": "10941:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7745, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "10941:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7748, + "name": "content_hash", + "nodeType": "VariableDeclaration", + "scope": 7859, + "src": "10962:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7747, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "10962:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7750, + "name": "arbitrator", + "nodeType": "VariableDeclaration", + "scope": 7859, + "src": "10984:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7749, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "10984:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7752, + "name": "timeout", + "nodeType": "VariableDeclaration", + "scope": 7859, + "src": "11004:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7751, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "11004:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7754, + "name": "opening_ts", + "nodeType": "VariableDeclaration", + "scope": 7859, + "src": "11020:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7753, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "11020:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "10940:98:18" + }, + "payable": false, + "returnParameters": { + "id": 7759, + "nodeType": "ParameterList", + "parameters": [], + "src": "11090:0:18" + }, + "scope": 9314, + "src": "10919:1487:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 7893, + "nodeType": "Block", + "src": "12755:194:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 7879, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7867, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "12765:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7869, + "indexExpression": { + "argumentTypes": null, + "id": 7868, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7861, + "src": "12775:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12765:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7870, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "bounty", + "nodeType": "MemberAccess", + "referencedDeclaration": 7257, + "src": "12765:29:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7876, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "12831:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7877, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "12831:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7871, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "12797:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7873, + "indexExpression": { + "argumentTypes": null, + "id": 7872, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7861, + "src": "12807:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12797:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7874, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bounty", + "nodeType": "MemberAccess", + "referencedDeclaration": 7257, + "src": "12797:29:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7875, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 7080, + "src": "12797:33:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 7878, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12797:44:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "12765:76:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 7880, + "nodeType": "ExpressionStatement", + "src": "12765:76:18" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7882, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7861, + "src": "12876:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7883, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "12889:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7884, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "12889:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7885, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "12900:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7887, + "indexExpression": { + "argumentTypes": null, + "id": 7886, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7861, + "src": "12910:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12900:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7888, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bounty", + "nodeType": "MemberAccess", + "referencedDeclaration": 7257, + "src": "12900:29:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7889, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "12931:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7890, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "12931:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 7881, + "name": "LogFundAnswerBounty", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7189, + "src": "12856:19:18", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_uint256_$_t_uint256_$_t_address_$returns$__$", + "typeString": "function (bytes32,uint256,uint256,address)" + } + }, + "id": 7891, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12856:86:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7892, + "nodeType": "EmitStatement", + "src": "12851:91:18" + } + ] + }, + "documentation": "@notice Add funds to the bounty for a question\n @dev Add bounty funds after the initial question creation. Can be done any time until the question is finalized.\n @param question_id The ID of the question you wish to fund", + "id": 7894, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 7864, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7861, + "src": "12721:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 7865, + "modifierName": { + "argumentTypes": null, + "id": 7863, + "name": "stateOpen", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7407, + "src": "12711:9:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "12711:22:18" + } + ], + "name": "fundAnswerBounty", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 7862, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7861, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7894, + "src": "12681:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7860, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "12681:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "12680:21:18" + }, + "payable": true, + "returnParameters": { + "id": 7866, + "nodeType": "ParameterList", + "parameters": [], + "src": "12755:0:18" + }, + "scope": 9314, + "src": "12655:294:18", + "stateMutability": "payable", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 7932, + "nodeType": "Block", + "src": "13680:170:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7914, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7896, + "src": "13710:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 7915, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7898, + "src": "13723:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7916, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "13731:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7917, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "13731:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7918, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "13743:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7919, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "13743:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 7920, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13754:5:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 7913, + "name": "_addAnswerToHistory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8235, + "src": "13690:19:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_address_$_t_uint256_$_t_bool_$returns$__$", + "typeString": "function (bytes32,bytes32,address,uint256,bool)" + } + }, + "id": 7921, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13690:70:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7922, + "nodeType": "ExpressionStatement", + "src": "13690:70:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7924, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7896, + "src": "13791:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 7925, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7898, + "src": "13804:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7926, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "13812:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7928, + "indexExpression": { + "argumentTypes": null, + "id": 7927, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7896, + "src": "13822:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "13812:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7929, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timeout", + "nodeType": "MemberAccess", + "referencedDeclaration": 7251, + "src": "13812:30:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + ], + "id": 7923, + "name": "_updateCurrentAnswer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8264, + "src": "13770:20:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_uint32_$returns$__$", + "typeString": "function (bytes32,bytes32,uint32)" + } + }, + "id": 7930, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13770:73:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7931, + "nodeType": "ExpressionStatement", + "src": "13770:73:18" + } + ] + }, + "documentation": "@notice Submit an answer for a question.\n @dev Adds the answer to the history and updates the current \"best\" answer.\n May be subject to front-running attacks; Substitute submitAnswerCommitment()->submitAnswerReveal() to prevent them.\n @param question_id The ID of the question\n @param answer The answer, encoded into bytes32\n @param max_previous If specified, reverts if a bond higher than this was submitted after you sent your transaction.", + "id": 7933, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 7903, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7896, + "src": "13540:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 7904, + "modifierName": { + "argumentTypes": null, + "id": 7902, + "name": "stateOpen", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7407, + "src": "13530:9:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "13530:22:18" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 7906, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7896, + "src": "13576:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 7907, + "modifierName": { + "argumentTypes": null, + "id": 7905, + "name": "bondMustDouble", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7519, + "src": "13561:14:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "13561:27:18" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 7909, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7896, + "src": "13632:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 7910, + "name": "max_previous", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7900, + "src": "13645:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 7911, + "modifierName": { + "argumentTypes": null, + "id": 7908, + "name": "previousBondMustNotBeatMaxPrevious", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7542, + "src": "13597:34:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$_t_uint256_$", + "typeString": "modifier (bytes32,uint256)" + } + }, + "nodeType": "ModifierInvocation", + "src": "13597:61:18" + } + ], + "name": "submitAnswer", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 7901, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7896, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7933, + "src": "13462:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7895, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "13462:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7898, + "name": "answer", + "nodeType": "VariableDeclaration", + "scope": 7933, + "src": "13483:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7897, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "13483:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7900, + "name": "max_previous", + "nodeType": "VariableDeclaration", + "scope": 7933, + "src": "13499:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7899, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "13499:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "13461:59:18" + }, + "payable": true, + "returnParameters": { + "id": 7912, + "nodeType": "ParameterList", + "parameters": [], + "src": "13680:0:18" + }, + "scope": 9314, + "src": "13440:410:18", + "stateMutability": "payable", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 7979, + "nodeType": "Block", + "src": "14715:240:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 7957, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 7955, + "name": "answerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7941, + "src": "14733:8:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "id": 7956, + "name": "NULL_ADDRESS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7126, + "src": "14745:12:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "14733:24:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "616e737765726572206d757374206265206e6f6e2d7a65726f", + "id": 7958, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14759:27:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_1a11019cd9d1425a5b8b53e98d98a4940adc356e8b64f2a44d399cf8bb21778b", + "typeString": "literal_string \"answerer must be non-zero\"" + }, + "value": "answerer must be non-zero" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_1a11019cd9d1425a5b8b53e98d98a4940adc356e8b64f2a44d399cf8bb21778b", + "typeString": "literal_string \"answerer must be non-zero\"" + } + ], + "id": 7954, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "14725:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7959, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "14725:62:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7960, + "nodeType": "ExpressionStatement", + "src": "14725:62:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7962, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7935, + "src": "14817:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 7963, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7937, + "src": "14830:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 7964, + "name": "answerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7941, + "src": "14838:8:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 7965, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "14848:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 7966, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "14848:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 7967, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14859:5:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 7961, + "name": "_addAnswerToHistory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8235, + "src": "14797:19:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_address_$_t_uint256_$_t_bool_$returns$__$", + "typeString": "function (bytes32,bytes32,address,uint256,bool)" + } + }, + "id": 7968, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "14797:68:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7969, + "nodeType": "ExpressionStatement", + "src": "14797:68:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 7971, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7935, + "src": "14896:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 7972, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7937, + "src": "14909:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7973, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "14917:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 7975, + "indexExpression": { + "argumentTypes": null, + "id": 7974, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7935, + "src": "14927:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "14917:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 7976, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timeout", + "nodeType": "MemberAccess", + "referencedDeclaration": 7251, + "src": "14917:30:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + ], + "id": 7970, + "name": "_updateCurrentAnswer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8264, + "src": "14875:20:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_uint32_$returns$__$", + "typeString": "function (bytes32,bytes32,uint32)" + } + }, + "id": 7977, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "14875:73:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7978, + "nodeType": "ExpressionStatement", + "src": "14875:73:18" + } + ] + }, + "documentation": "@notice Submit an answer for a question, crediting it to the specified account.\n @dev Adds the answer to the history and updates the current \"best\" answer.\n May be subject to front-running attacks; Substitute submitAnswerCommitment()->submitAnswerReveal() to prevent them.\n @param question_id The ID of the question\n @param answer The answer, encoded into bytes32\n @param max_previous If specified, reverts if a bond higher than this was submitted after you sent your transaction.\n @param answerer The account to which the answer should be credited", + "id": 7980, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 7944, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7935, + "src": "14575:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 7945, + "modifierName": { + "argumentTypes": null, + "id": 7943, + "name": "stateOpen", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7407, + "src": "14565:9:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "14565:22:18" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 7947, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7935, + "src": "14611:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 7948, + "modifierName": { + "argumentTypes": null, + "id": 7946, + "name": "bondMustDouble", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7519, + "src": "14596:14:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "14596:27:18" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 7950, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7935, + "src": "14667:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 7951, + "name": "max_previous", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7939, + "src": "14680:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 7952, + "modifierName": { + "argumentTypes": null, + "id": 7949, + "name": "previousBondMustNotBeatMaxPrevious", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7542, + "src": "14632:34:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$_t_uint256_$", + "typeString": "modifier (bytes32,uint256)" + } + }, + "nodeType": "ModifierInvocation", + "src": "14632:61:18" + } + ], + "name": "submitAnswerFor", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 7942, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7935, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 7980, + "src": "14480:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7934, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "14480:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7937, + "name": "answer", + "nodeType": "VariableDeclaration", + "scope": 7980, + "src": "14501:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7936, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "14501:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7939, + "name": "max_previous", + "nodeType": "VariableDeclaration", + "scope": 7980, + "src": "14517:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7938, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "14517:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7941, + "name": "answerer", + "nodeType": "VariableDeclaration", + "scope": 7980, + "src": "14539:16:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 7940, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "14539:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "14479:77:18" + }, + "payable": true, + "returnParameters": { + "id": 7953, + "nodeType": "ParameterList", + "parameters": [], + "src": "14715:0:18" + }, + "scope": 9314, + "src": "14455:500:18", + "stateMutability": "payable", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 8018, + "nodeType": "Block", + "src": "15236:306:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 7993, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7988, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "15254:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 7990, + "indexExpression": { + "argumentTypes": null, + "id": 7989, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7984, + "src": "15266:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "15254:26:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "id": 7991, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "reveal_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7266, + "src": "15254:36:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 7992, + "name": "COMMITMENT_NON_EXISTENT", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7137, + "src": "15294:23:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "15254:63:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "636f6d6d69746d656e74206d757374206e6f7420616c7265616479206578697374", + "id": 7994, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "15319:35:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c2878907358507a98137b5e459ef2a610f3aa0fc728f22215b4a187d8849acf0", + "typeString": "literal_string \"commitment must not already exist\"" + }, + "value": "commitment must not already exist" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_c2878907358507a98137b5e459ef2a610f3aa0fc728f22215b4a187d8849acf0", + "typeString": "literal_string \"commitment must not already exist\"" + } + ], + "id": 7987, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "15246:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 7995, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "15246:109:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7996, + "nodeType": "ExpressionStatement", + "src": "15246:109:18" + }, + { + "assignments": [ + 7998 + ], + "declarations": [ + { + "constant": false, + "id": 7998, + "name": "commitment_timeout", + "nodeType": "VariableDeclaration", + "scope": 8019, + "src": "15366:25:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 7997, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "15366:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8005, + "initialValue": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 8004, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 7999, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "15394:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8001, + "indexExpression": { + "argumentTypes": null, + "id": 8000, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7982, + "src": "15404:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "15394:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8002, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timeout", + "nodeType": "MemberAccess", + "referencedDeclaration": 7251, + "src": "15394:30:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "/", + "rightExpression": { + "argumentTypes": null, + "id": 8003, + "name": "COMMITMENT_TIMEOUT_RATIO", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7140, + "src": "15427:24:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "15394:57:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "15366:85:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8016, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8006, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "15461:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 8008, + "indexExpression": { + "argumentTypes": null, + "id": 8007, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7984, + "src": "15473:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "15461:26:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "id": 8009, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "reveal_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7266, + "src": "15461:36:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8014, + "name": "commitment_timeout", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7998, + "src": "15516:18:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8011, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "15507:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 8010, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "15500:6:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint32_$", + "typeString": "type(uint32)" + }, + "typeName": "uint32" + }, + "id": 8012, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "15500:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "id": 8013, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 7107, + "src": "15500:15:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint32_$_t_uint32_$returns$_t_uint32_$bound_to$_t_uint32_$", + "typeString": "function (uint32,uint32) pure returns (uint32)" + } + }, + "id": 8015, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "15500:35:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "15461:74:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "id": 8017, + "nodeType": "ExpressionStatement", + "src": "15461:74:18" + } + ] + }, + "documentation": null, + "id": 8019, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "_storeCommitment", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 7985, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 7982, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8019, + "src": "15174:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7981, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "15174:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 7984, + "name": "commitment_id", + "nodeType": "VariableDeclaration", + "scope": 8019, + "src": "15195:21:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 7983, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "15195:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "15173:44:18" + }, + "payable": false, + "returnParameters": { + "id": 7986, + "nodeType": "ParameterList", + "parameters": [], + "src": "15236:0:18" + }, + "scope": 9314, + "src": "15148:394:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 8077, + "nodeType": "Block", + "src": "16753:326:18", + "statements": [ + { + "assignments": [ + 8041 + ], + "declarations": [ + { + "constant": false, + "id": 8041, + "name": "commitment_id", + "nodeType": "VariableDeclaration", + "scope": 8078, + "src": "16764:21:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8040, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "16764:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8051, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8045, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8021, + "src": "16815:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8046, + "name": "answer_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8023, + "src": "16828:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 8047, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "16841:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 8048, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "16841:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 8043, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9703, + "src": "16798:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 8044, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "16798:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 8049, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "16798:53:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 8042, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9710, + "src": "16788:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 8050, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "16788:64:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "16764:88:18" + }, + { + "assignments": [ + 8053 + ], + "declarations": [ + { + "constant": false, + "id": 8053, + "name": "answerer", + "nodeType": "VariableDeclaration", + "scope": 8078, + "src": "16862:16:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8052, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "16862:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8062, + "initialValue": { + "argumentTypes": null, + "condition": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 8056, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8054, + "name": "_answerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8027, + "src": "16882:9:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 8055, + "name": "NULL_ADDRESS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7126, + "src": "16895:12:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "16882:25:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 8057, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "16881:27:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "argumentTypes": null, + "id": 8060, + "name": "_answerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8027, + "src": "16924:9:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 8061, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "16881:52:18", + "trueExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 8058, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "16911:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 8059, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "16911:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "16862:71:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8064, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8021, + "src": "16960:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8065, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8041, + "src": "16973:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 8063, + "name": "_storeCommitment", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8019, + "src": "16943:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$returns$__$", + "typeString": "function (bytes32,bytes32)" + } + }, + "id": 8066, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "16943:44:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8067, + "nodeType": "ExpressionStatement", + "src": "16943:44:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8069, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8021, + "src": "17017:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8070, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8041, + "src": "17030:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8071, + "name": "answerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8053, + "src": "17045:8:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 8072, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "17055:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 8073, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "17055:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "hexValue": "74727565", + "id": 8074, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "17066:4:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 8068, + "name": "_addAnswerToHistory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8235, + "src": "16997:19:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_address_$_t_uint256_$_t_bool_$returns$__$", + "typeString": "function (bytes32,bytes32,address,uint256,bool)" + } + }, + "id": 8075, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "16997:74:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8076, + "nodeType": "ExpressionStatement", + "src": "16997:74:18" + } + ] + }, + "documentation": "@notice Submit the hash of an answer, laying your claim to that answer if you reveal it in a subsequent transaction.\n @dev Creates a hash, commitment_id, uniquely identifying this answer, to this question, with this bond.\n The commitment_id is stored in the answer history where the answer would normally go.\n Does not update the current best answer - this is left to the later submitAnswerReveal() transaction.\n @param question_id The ID of the question\n @param answer_hash The hash of your answer, plus a nonce that you will later reveal\n @param max_previous If specified, reverts if a bond higher than this was submitted after you sent your transaction.\n @param _answerer If specified, the address to be given as the question answerer. Defaults to the sender.\n @dev Specifying the answerer is useful if you want to delegate the commit-and-reveal to a third-party.", + "id": 8078, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 8030, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8021, + "src": "16613:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8031, + "modifierName": { + "argumentTypes": null, + "id": 8029, + "name": "stateOpen", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7407, + "src": "16603:9:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "16603:22:18" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 8033, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8021, + "src": "16649:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8034, + "modifierName": { + "argumentTypes": null, + "id": 8032, + "name": "bondMustDouble", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7519, + "src": "16634:14:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "16634:27:18" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 8036, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8021, + "src": "16705:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8037, + "name": "max_previous", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8025, + "src": "16718:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 8038, + "modifierName": { + "argumentTypes": null, + "id": 8035, + "name": "previousBondMustNotBeatMaxPrevious", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7542, + "src": "16670:34:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$_t_uint256_$", + "typeString": "modifier (bytes32,uint256)" + } + }, + "nodeType": "ModifierInvocation", + "src": "16670:61:18" + } + ], + "name": "submitAnswerCommitment", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8028, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8021, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8078, + "src": "16511:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8020, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "16511:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8023, + "name": "answer_hash", + "nodeType": "VariableDeclaration", + "scope": 8078, + "src": "16532:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8022, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "16532:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8025, + "name": "max_previous", + "nodeType": "VariableDeclaration", + "scope": 8078, + "src": "16553:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8024, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "16553:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8027, + "name": "_answerer", + "nodeType": "VariableDeclaration", + "scope": 8078, + "src": "16575:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8026, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "16575:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "16510:83:18" + }, + "payable": true, + "returnParameters": { + "id": 8039, + "nodeType": "ParameterList", + "parameters": [], + "src": "16753:0:18" + }, + "scope": 9314, + "src": "16479:600:18", + "stateMutability": "payable", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 8175, + "nodeType": "Block", + "src": "18213:746:18", + "statements": [ + { + "assignments": [ + 8093 + ], + "declarations": [ + { + "constant": false, + "id": 8093, + "name": "answer_hash", + "nodeType": "VariableDeclaration", + "scope": 8176, + "src": "18224:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8092, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "18224:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8101, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8097, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8082, + "src": "18273:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8098, + "name": "nonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8084, + "src": "18281:5:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 8095, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9703, + "src": "18256:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 8096, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "18256:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 8099, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18256:31:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 8094, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9710, + "src": "18246:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 8100, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18246:42:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "18224:64:18" + }, + { + "assignments": [ + 8103 + ], + "declarations": [ + { + "constant": false, + "id": 8103, + "name": "commitment_id", + "nodeType": "VariableDeclaration", + "scope": 8176, + "src": "18298:21:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8102, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "18298:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8112, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8107, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8080, + "src": "18349:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8108, + "name": "answer_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8093, + "src": "18362:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8109, + "name": "bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8086, + "src": "18375:4:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 8105, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9703, + "src": "18332:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 8106, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "18332:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 8110, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18332:48:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 8104, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9710, + "src": "18322:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 8111, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18322:59:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "18298:83:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8118, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "18400:39:18", + "subExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8114, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "18401:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 8116, + "indexExpression": { + "argumentTypes": null, + "id": 8115, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8103, + "src": "18413:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "18401:26:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "id": 8117, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "is_revealed", + "nodeType": "MemberAccess", + "referencedDeclaration": 7268, + "src": "18401:38:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "636f6d6d69746d656e74206d757374206e6f742068617665206265656e2072657665616c656420796574", + "id": 8119, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "18441:44:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_6dc39b75299a8c5d94f5d4fe4d23fcb2fa3f298c414cad40577eebdbf4fb5bba", + "typeString": "literal_string \"commitment must not have been revealed yet\"" + }, + "value": "commitment must not have been revealed yet" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_6dc39b75299a8c5d94f5d4fe4d23fcb2fa3f298c414cad40577eebdbf4fb5bba", + "typeString": "literal_string \"commitment must not have been revealed yet\"" + } + ], + "id": 8113, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "18392:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 8120, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18392:94:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8121, + "nodeType": "ExpressionStatement", + "src": "18392:94:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 8130, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8123, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "18504:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 8125, + "indexExpression": { + "argumentTypes": null, + "id": 8124, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8103, + "src": "18516:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "18504:26:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "id": 8126, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "reveal_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7266, + "src": "18504:36:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8128, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "18550:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 8127, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "18543:6:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint32_$", + "typeString": "type(uint32)" + }, + "typeName": "uint32" + }, + "id": 8129, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18543:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "18504:50:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "72657665616c20646561646c696e65206d757374206e6f74206861766520706173736564", + "id": 8131, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "18556:38:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c0aef0f9c54528968b7d0aecff5e54568fd8cfc861f8c854eb9d7453b7f722c0", + "typeString": "literal_string \"reveal deadline must not have passed\"" + }, + "value": "reveal deadline must not have passed" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_c0aef0f9c54528968b7d0aecff5e54568fd8cfc861f8c854eb9d7453b7f722c0", + "typeString": "literal_string \"reveal deadline must not have passed\"" + } + ], + "id": 8122, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "18496:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 8132, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18496:99:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8133, + "nodeType": "ExpressionStatement", + "src": "18496:99:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8139, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8134, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "18606:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 8136, + "indexExpression": { + "argumentTypes": null, + "id": 8135, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8103, + "src": "18618:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "18606:26:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "id": 8137, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "revealed_answer", + "nodeType": "MemberAccess", + "referencedDeclaration": 7270, + "src": "18606:42:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 8138, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8082, + "src": "18651:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "18606:51:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 8140, + "nodeType": "ExpressionStatement", + "src": "18606:51:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8146, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8141, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "18667:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 8143, + "indexExpression": { + "argumentTypes": null, + "id": 8142, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8103, + "src": "18679:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "18667:26:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "id": 8144, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "is_revealed", + "nodeType": "MemberAccess", + "referencedDeclaration": 7268, + "src": "18667:38:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 8145, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "18708:4:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "18667:45:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 8147, + "nodeType": "ExpressionStatement", + "src": "18667:45:18" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 8153, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8148, + "name": "bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8086, + "src": "18727:4:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8149, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "18735:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8151, + "indexExpression": { + "argumentTypes": null, + "id": 8150, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8080, + "src": "18745:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "18735:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8152, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bond", + "nodeType": "MemberAccess", + "referencedDeclaration": 7263, + "src": "18735:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "18727:35:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 8164, + "nodeType": "IfStatement", + "src": "18723:139:18", + "trueBody": { + "id": 8163, + "nodeType": "Block", + "src": "18764:98:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8155, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8080, + "src": "18799:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8156, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8082, + "src": "18812:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8157, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "18820:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8159, + "indexExpression": { + "argumentTypes": null, + "id": 8158, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8080, + "src": "18830:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "18820:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8160, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timeout", + "nodeType": "MemberAccess", + "referencedDeclaration": 7251, + "src": "18820:30:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + ], + "id": 8154, + "name": "_updateCurrentAnswer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8264, + "src": "18778:20:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_uint32_$returns$__$", + "typeString": "function (bytes32,bytes32,uint32)" + } + }, + "id": 8161, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18778:73:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8162, + "nodeType": "ExpressionStatement", + "src": "18778:73:18" + } + ] + } + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8166, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8080, + "src": "18893:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 8167, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9716, + "src": "18906:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 8168, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "18906:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 8169, + "name": "answer_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8093, + "src": "18918:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8170, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8082, + "src": "18931:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8171, + "name": "nonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8084, + "src": "18939:5:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 8172, + "name": "bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8086, + "src": "18946:4:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 8165, + "name": "LogAnswerReveal", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7219, + "src": "18877:15:18", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_address_$_t_bytes32_$_t_bytes32_$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (bytes32,address,bytes32,bytes32,uint256,uint256)" + } + }, + "id": 8173, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18877:74:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8174, + "nodeType": "EmitStatement", + "src": "18872:79:18" + } + ] + }, + "documentation": "@notice Submit the answer whose hash you sent in a previous submitAnswerCommitment() transaction\n @dev Checks the parameters supplied recreate an existing commitment, and stores the revealed answer\n Updates the current answer unless someone has since supplied a new answer with a higher bond\n msg.sender is intentionally not restricted to the user who originally sent the commitment; \n For example, the user may want to provide the answer+nonce to a third-party service and let them send the tx\n NB If we are pending arbitration, it will be up to the arbitrator to wait and see any outstanding reveal is sent\n @param question_id The ID of the question\n @param answer The answer, encoded as bytes32\n @param nonce The nonce that, combined with the answer, recreates the answer_hash you gave in submitAnswerCommitment()\n @param bond The bond that you paid in your submitAnswerCommitment() transaction", + "id": 8176, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 8089, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8080, + "src": "18187:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8090, + "modifierName": { + "argumentTypes": null, + "id": 8088, + "name": "stateOpenOrPendingArbitration", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7477, + "src": "18157:29:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "18157:42:18" + } + ], + "name": "submitAnswerReveal", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8087, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8080, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8176, + "src": "18082:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8079, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "18082:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8082, + "name": "answer", + "nodeType": "VariableDeclaration", + "scope": 8176, + "src": "18103:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8081, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "18103:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8084, + "name": "nonce", + "nodeType": "VariableDeclaration", + "scope": 8176, + "src": "18119:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8083, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "18119:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8086, + "name": "bond", + "nodeType": "VariableDeclaration", + "scope": 8176, + "src": "18134:12:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8085, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "18134:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "18081:66:18" + }, + "payable": false, + "returnParameters": { + "id": 8091, + "nodeType": "ParameterList", + "parameters": [], + "src": "18213:0:18" + }, + "scope": 9314, + "src": "18054:905:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 8234, + "nodeType": "Block", + "src": "19119:524:18", + "statements": [ + { + "assignments": [ + 8190 + ], + "declarations": [ + { + "constant": false, + "id": 8190, + "name": "new_history_hash", + "nodeType": "VariableDeclaration", + "scope": 8235, + "src": "19129:24:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8189, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "19129:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8204, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8194, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "19183:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8196, + "indexExpression": { + "argumentTypes": null, + "id": 8195, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8178, + "src": "19193:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "19183:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8197, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "history_hash", + "nodeType": "MemberAccess", + "referencedDeclaration": 7261, + "src": "19183:35:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8198, + "name": "answer_or_commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8180, + "src": "19220:23:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8199, + "name": "bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8184, + "src": "19245:4:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 8200, + "name": "answerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8182, + "src": "19251:8:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 8201, + "name": "is_commitment", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8186, + "src": "19261:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "expression": { + "argumentTypes": null, + "id": 8192, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9703, + "src": "19166:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 8193, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "19166:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 8202, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "19166:109:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 8191, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9710, + "src": "19156:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 8203, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "19156:120:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "19129:147:18" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 8207, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8205, + "name": "bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8184, + "src": "19384:4:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 8206, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19391:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "19384:8:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 8216, + "nodeType": "IfStatement", + "src": "19380:73:18", + "trueBody": { + "id": 8215, + "nodeType": "Block", + "src": "19394:59:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 8213, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8208, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "19408:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8210, + "indexExpression": { + "argumentTypes": null, + "id": 8209, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8178, + "src": "19418:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "19408:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8211, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "bond", + "nodeType": "MemberAccess", + "referencedDeclaration": 7263, + "src": "19408:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 8212, + "name": "bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8184, + "src": "19438:4:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "19408:34:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8214, + "nodeType": "ExpressionStatement", + "src": "19408:34:18" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "id": 8222, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8217, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "19462:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8219, + "indexExpression": { + "argumentTypes": null, + "id": 8218, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8178, + "src": "19472:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "19462:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8220, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "history_hash", + "nodeType": "MemberAccess", + "referencedDeclaration": 7261, + "src": "19462:35:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 8221, + "name": "new_history_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8190, + "src": "19500:16:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "19462:54:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 8223, + "nodeType": "ExpressionStatement", + "src": "19462:54:18" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8225, + "name": "answer_or_commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8180, + "src": "19545:23:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8226, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8178, + "src": "19570:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8227, + "name": "new_history_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8190, + "src": "19583:16:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8228, + "name": "answerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8182, + "src": "19601:8:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 8229, + "name": "bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8184, + "src": "19611:4:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 8230, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "19617:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 8231, + "name": "is_commitment", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8186, + "src": "19622:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 8224, + "name": "LogNewAnswer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7205, + "src": "19532:12:18", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_bytes32_$_t_bytes32_$_t_address_$_t_uint256_$_t_uint256_$_t_bool_$returns$__$", + "typeString": "function (bytes32,bytes32,bytes32,address,uint256,uint256,bool)" + } + }, + "id": 8232, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "19532:104:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8233, + "nodeType": "EmitStatement", + "src": "19527:109:18" + } + ] + }, + "documentation": null, + "id": 8235, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "_addAnswerToHistory", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8187, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8178, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8235, + "src": "18994:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8177, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "18994:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8180, + "name": "answer_or_commitment_id", + "nodeType": "VariableDeclaration", + "scope": 8235, + "src": "19015:31:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8179, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "19015:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8182, + "name": "answerer", + "nodeType": "VariableDeclaration", + "scope": 8235, + "src": "19048:16:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8181, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "19048:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8184, + "name": "bond", + "nodeType": "VariableDeclaration", + "scope": 8235, + "src": "19066:12:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8183, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "19066:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8186, + "name": "is_commitment", + "nodeType": "VariableDeclaration", + "scope": 8235, + "src": "19080:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 8185, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "19080:4:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "18993:106:18" + }, + "payable": false, + "returnParameters": { + "id": 8188, + "nodeType": "ParameterList", + "parameters": [], + "src": "19119:0:18" + }, + "scope": 9314, + "src": "18965:678:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 8263, + "nodeType": "Block", + "src": "19750:136:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 8249, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8244, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "19760:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8246, + "indexExpression": { + "argumentTypes": null, + "id": 8245, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8237, + "src": "19770:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "19760:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8247, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "best_answer", + "nodeType": "MemberAccess", + "referencedDeclaration": 7259, + "src": "19760:34:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 8248, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8239, + "src": "19797:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "19760:43:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 8250, + "nodeType": "ExpressionStatement", + "src": "19760:43:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8261, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8251, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "19813:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8253, + "indexExpression": { + "argumentTypes": null, + "id": 8252, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8237, + "src": "19823:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "19813:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8254, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "finalize_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7253, + "src": "19813:34:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8259, + "name": "timeout_secs", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8241, + "src": "19866:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8256, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "19857:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 8255, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "19850:6:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint32_$", + "typeString": "type(uint32)" + }, + "typeName": "uint32" + }, + "id": 8257, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "19850:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "id": 8258, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 7107, + "src": "19850:15:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint32_$_t_uint32_$returns$_t_uint32_$bound_to$_t_uint32_$", + "typeString": "function (uint32,uint32) pure returns (uint32)" + } + }, + "id": 8260, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "19850:29:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "19813:66:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "id": 8262, + "nodeType": "ExpressionStatement", + "src": "19813:66:18" + } + ] + }, + "documentation": null, + "id": 8264, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "_updateCurrentAnswer", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8242, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8237, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8264, + "src": "19679:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8236, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "19679:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8239, + "name": "answer", + "nodeType": "VariableDeclaration", + "scope": 8264, + "src": "19700:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8238, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "19700:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8241, + "name": "timeout_secs", + "nodeType": "VariableDeclaration", + "scope": 8264, + "src": "19716:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 8240, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "19716:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "19678:58:18" + }, + "payable": false, + "returnParameters": { + "id": 8243, + "nodeType": "ParameterList", + "parameters": [], + "src": "19750:0:18" + }, + "scope": 9314, + "src": "19649:237:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 8305, + "nodeType": "Block", + "src": "20616:257:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 8289, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8284, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "20634:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8286, + "indexExpression": { + "argumentTypes": null, + "id": 8285, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8266, + "src": "20644:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "20634:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8287, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bond", + "nodeType": "MemberAccess", + "referencedDeclaration": 7263, + "src": "20634:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 8288, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "20664:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "20634:31:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "5175657374696f6e206d75737420616c7265616479206861766520616e20616e73776572207768656e206172626974726174696f6e20697320726571756573746564", + "id": 8290, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "20667:68:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_7fdaca9206a1cc3ce5480327eab94eaea78ffd196334cab0e144479eb0ad45d4", + "typeString": "literal_string \"Question must already have an answer when arbitration is requested\"" + }, + "value": "Question must already have an answer when arbitration is requested" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_7fdaca9206a1cc3ce5480327eab94eaea78ffd196334cab0e144479eb0ad45d4", + "typeString": "literal_string \"Question must already have an answer when arbitration is requested\"" + } + ], + "id": 8283, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "20626:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 8291, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "20626:110:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8292, + "nodeType": "ExpressionStatement", + "src": "20626:110:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8298, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8293, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "20746:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8295, + "indexExpression": { + "argumentTypes": null, + "id": 8294, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8266, + "src": "20756:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "20746:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8296, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "is_pending_arbitration", + "nodeType": "MemberAccess", + "referencedDeclaration": 7255, + "src": "20746:45:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 8297, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "20794:4:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "20746:52:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 8299, + "nodeType": "ExpressionStatement", + "src": "20746:52:18" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8301, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8266, + "src": "20843:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8302, + "name": "requester", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8268, + "src": "20856:9:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 8300, + "name": "LogNotifyOfArbitrationRequest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7225, + "src": "20813:29:18", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_address_$returns$__$", + "typeString": "function (bytes32,address)" + } + }, + "id": 8303, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "20813:53:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8304, + "nodeType": "EmitStatement", + "src": "20808:58:18" + } + ] + }, + "documentation": "@notice Notify the contract that the arbitrator has been paid for a question, freezing it pending their decision.\n @dev The arbitrator contract is trusted to only call this if they've been paid, and tell us who paid them.\n @param question_id The ID of the question\n @param requester The account that requested arbitration\n @param max_previous If specified, reverts if a bond higher than this was submitted after you sent your transaction.", + "id": 8306, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 8273, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8266, + "src": "20489:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8274, + "modifierName": { + "argumentTypes": null, + "id": 8272, + "name": "onlyArbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7322, + "src": "20474:14:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "20474:27:18" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 8276, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8266, + "src": "20520:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8277, + "modifierName": { + "argumentTypes": null, + "id": 8275, + "name": "stateOpen", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7407, + "src": "20510:9:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "20510:22:18" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 8279, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8266, + "src": "20576:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8280, + "name": "max_previous", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8270, + "src": "20589:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 8281, + "modifierName": { + "argumentTypes": null, + "id": 8278, + "name": "previousBondMustNotBeatMaxPrevious", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7542, + "src": "20541:34:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$_t_uint256_$", + "typeString": "modifier (bytes32,uint256)" + } + }, + "nodeType": "ModifierInvocation", + "src": "20541:61:18" + } + ], + "name": "notifyOfArbitrationRequest", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8271, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8266, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8306, + "src": "20403:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8265, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "20403:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8268, + "name": "requester", + "nodeType": "VariableDeclaration", + "scope": 8306, + "src": "20424:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8267, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "20424:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8270, + "name": "max_previous", + "nodeType": "VariableDeclaration", + "scope": 8306, + "src": "20443:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8269, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "20443:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "20402:62:18" + }, + "payable": false, + "returnParameters": { + "id": 8282, + "nodeType": "ParameterList", + "parameters": [], + "src": "20616:0:18" + }, + "scope": 9314, + "src": "20367:506:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 8343, + "nodeType": "Block", + "src": "21245:212:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 8322, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8317, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "21255:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8319, + "indexExpression": { + "argumentTypes": null, + "id": 8318, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8308, + "src": "21265:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "21255:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8320, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "is_pending_arbitration", + "nodeType": "MemberAccess", + "referencedDeclaration": 7255, + "src": "21255:45:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 8321, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "21303:5:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "src": "21255:53:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 8323, + "nodeType": "ExpressionStatement", + "src": "21255:53:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8337, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8324, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "21318:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8326, + "indexExpression": { + "argumentTypes": null, + "id": 8325, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8308, + "src": "21328:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "21318:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8327, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "finalize_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7253, + "src": "21318:34:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8332, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "21371:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8334, + "indexExpression": { + "argumentTypes": null, + "id": 8333, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8308, + "src": "21381:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "21371:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8335, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timeout", + "nodeType": "MemberAccess", + "referencedDeclaration": 7251, + "src": "21371:30:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8329, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "21362:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 8328, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "21355:6:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint32_$", + "typeString": "type(uint32)" + }, + "typeName": "uint32" + }, + "id": 8330, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21355:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "id": 8331, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 7107, + "src": "21355:15:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint32_$_t_uint32_$returns$_t_uint32_$bound_to$_t_uint32_$", + "typeString": "function (uint32,uint32) pure returns (uint32)" + } + }, + "id": 8336, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21355:47:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "21318:84:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "id": 8338, + "nodeType": "ExpressionStatement", + "src": "21318:84:18" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8340, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8308, + "src": "21438:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 8339, + "name": "LogCancelArbitration", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7229, + "src": "21417:20:18", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$returns$__$", + "typeString": "function (bytes32)" + } + }, + "id": 8341, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21417:33:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8342, + "nodeType": "EmitStatement", + "src": "21412:38:18" + } + ] + }, + "documentation": "@notice Cancel a previously-requested arbitration and extend the timeout\n @dev Useful when doing arbitration across chains that can't be requested atomically\n @param question_id The ID of the question", + "id": 8344, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 8311, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8308, + "src": "21174:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8312, + "modifierName": { + "argumentTypes": null, + "id": 8310, + "name": "onlyArbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7322, + "src": "21159:14:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "21159:27:18" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 8314, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8308, + "src": "21219:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8315, + "modifierName": { + "argumentTypes": null, + "id": 8313, + "name": "statePendingArbitration", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7421, + "src": "21195:23:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "21195:36:18" + } + ], + "name": "cancelArbitration", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8309, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8308, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8344, + "src": "21129:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8307, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "21129:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "21128:21:18" + }, + "payable": false, + "returnParameters": { + "id": 8316, + "nodeType": "ParameterList", + "parameters": [], + "src": "21245:0:18" + }, + "scope": 9314, + "src": "21102:355:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 8392, + "nodeType": "Block", + "src": "22235:316:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 8362, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8360, + "name": "answerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8350, + "src": "22254:8:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "id": 8361, + "name": "NULL_ADDRESS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7126, + "src": "22266:12:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "22254:24:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "616e737765726572206d7573742062652070726f7669646564", + "id": 8363, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "22280:27:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_b2034904ed959e3f06daceb4dada259b4f13c4f11a1b4edcc62492a9fc76ce84", + "typeString": "literal_string \"answerer must be provided\"" + }, + "value": "answerer must be provided" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_b2034904ed959e3f06daceb4dada259b4f13c4f11a1b4edcc62492a9fc76ce84", + "typeString": "literal_string \"answerer must be provided\"" + } + ], + "id": 8359, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "22246:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 8364, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "22246:62:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8365, + "nodeType": "ExpressionStatement", + "src": "22246:62:18" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8367, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8346, + "src": "22335:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8368, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8348, + "src": "22348:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 8366, + "name": "LogFinalize", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7235, + "src": "22323:11:18", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_bytes32_$returns$__$", + "typeString": "function (bytes32,bytes32)" + } + }, + "id": 8369, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "22323:32:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8370, + "nodeType": "EmitStatement", + "src": "22318:37:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8376, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8371, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "22366:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8373, + "indexExpression": { + "argumentTypes": null, + "id": 8372, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8346, + "src": "22376:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "22366:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8374, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "is_pending_arbitration", + "nodeType": "MemberAccess", + "referencedDeclaration": 7255, + "src": "22366:45:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 8375, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "22414:5:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "src": "22366:53:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 8377, + "nodeType": "ExpressionStatement", + "src": "22366:53:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8379, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8346, + "src": "22449:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8380, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8348, + "src": "22462:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8381, + "name": "answerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8350, + "src": "22470:8:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "hexValue": "30", + "id": 8382, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "22480:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 8383, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "22483:5:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 8378, + "name": "_addAnswerToHistory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8235, + "src": "22429:19:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_address_$_t_uint256_$_t_bool_$returns$__$", + "typeString": "function (bytes32,bytes32,address,uint256,bool)" + } + }, + "id": 8384, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "22429:60:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8385, + "nodeType": "ExpressionStatement", + "src": "22429:60:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8387, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8346, + "src": "22520:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8388, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8348, + "src": "22533:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "hexValue": "30", + "id": 8389, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "22541:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 8386, + "name": "_updateCurrentAnswer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8264, + "src": "22499:20:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_uint32_$returns$__$", + "typeString": "function (bytes32,bytes32,uint32)" + } + }, + "id": 8390, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "22499:44:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8391, + "nodeType": "ExpressionStatement", + "src": "22499:44:18" + } + ] + }, + "documentation": "@notice Submit the answer for a question, for use by the arbitrator.\n @dev Doesn't require (or allow) a bond.\n If the current final answer is correct, the account should be whoever submitted it.\n If the current final answer is wrong, the account should be whoever paid for arbitration.\n However, the answerer stipulations are not enforced by the contract.\n @param question_id The ID of the question\n @param answer The answer, encoded into bytes32\n @param answerer The account credited with this answer for the purpose of bond claims", + "id": 8393, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 8353, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8346, + "src": "22166:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8354, + "modifierName": { + "argumentTypes": null, + "id": 8352, + "name": "onlyArbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7322, + "src": "22151:14:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "22151:27:18" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 8356, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8346, + "src": "22211:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8357, + "modifierName": { + "argumentTypes": null, + "id": 8355, + "name": "statePendingArbitration", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7421, + "src": "22187:23:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "22187:36:18" + } + ], + "name": "submitAnswerByArbitrator", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8351, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8346, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8393, + "src": "22087:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8345, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "22087:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8348, + "name": "answer", + "nodeType": "VariableDeclaration", + "scope": 8393, + "src": "22108:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8347, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "22108:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8350, + "name": "answerer", + "nodeType": "VariableDeclaration", + "scope": 8393, + "src": "22124:16:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8349, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "22124:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "22086:55:18" + }, + "payable": false, + "returnParameters": { + "id": 8358, + "nodeType": "ParameterList", + "parameters": [], + "src": "22235:0:18" + }, + "scope": 9314, + "src": "22053:498:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 8472, + "nodeType": "Block", + "src": "23469:867:18", + "statements": [ + { + "assignments": [ + 8409 + ], + "declarations": [ + { + "constant": false, + "id": 8409, + "name": "is_commitment", + "nodeType": "VariableDeclaration", + "scope": 8473, + "src": "23479:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 8408, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "23479:4:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8423, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8411, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "23528:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8413, + "indexExpression": { + "argumentTypes": null, + "id": 8412, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8395, + "src": "23538:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "23528:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8414, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "history_hash", + "nodeType": "MemberAccess", + "referencedDeclaration": 7261, + "src": "23528:35:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8415, + "name": "last_history_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8401, + "src": "23565:17:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8416, + "name": "last_answer_or_commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8403, + "src": "23584:28:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8417, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "23614:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8419, + "indexExpression": { + "argumentTypes": null, + "id": 8418, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8395, + "src": "23624:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "23614:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8420, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bond", + "nodeType": "MemberAccess", + "referencedDeclaration": 7263, + "src": "23614:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 8421, + "name": "last_answerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8405, + "src": "23643:13:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 8410, + "name": "_verifyHistoryInputOrRevert", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8900, + "src": "23500:27:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes32_$_t_bytes32_$_t_bytes32_$_t_uint256_$_t_address_$returns$_t_bool_$", + "typeString": "function (bytes32,bytes32,bytes32,uint256,address) pure returns (bool)" + } + }, + "id": 8422, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "23500:157:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "23479:178:18" + }, + { + "assignments": [], + "declarations": [ + { + "constant": false, + "id": 8425, + "name": "payee", + "nodeType": "VariableDeclaration", + "scope": 8473, + "src": "23668:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8424, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "23668:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8426, + "initialValue": null, + "nodeType": "VariableDeclarationStatement", + "src": "23668:13:18" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 8433, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8427, + "name": "is_commitment", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8409, + "src": "23883:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "id": 8432, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "23900:54:18", + "subExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8428, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "23901:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 8430, + "indexExpression": { + "argumentTypes": null, + "id": 8429, + "name": "last_answer_or_commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8403, + "src": "23913:28:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "23901:41:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "id": 8431, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "is_revealed", + "nodeType": "MemberAccess", + "referencedDeclaration": 7268, + "src": "23901:53:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "23883:71:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 8464, + "nodeType": "Block", + "src": "24156:112:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 8462, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 8451, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8425, + "src": "24170:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "condition": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 8457, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8452, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "24179:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8454, + "indexExpression": { + "argumentTypes": null, + "id": 8453, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8395, + "src": "24189:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "24179:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8455, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "best_answer", + "nodeType": "MemberAccess", + "referencedDeclaration": 7259, + "src": "24179:34:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 8456, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8397, + "src": "24217:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "24179:44:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 8458, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "24178:46:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "argumentTypes": null, + "id": 8460, + "name": "payee_if_wrong", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8399, + "src": "24243:14:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 8461, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "24178:79:18", + "trueExpression": { + "argumentTypes": null, + "id": 8459, + "name": "last_answerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8405, + "src": "24227:13:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "24170:87:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 8463, + "nodeType": "ExpressionStatement", + "src": "24170:87:18" + } + ] + }, + "id": 8465, + "nodeType": "IfStatement", + "src": "23879:389:18", + "trueBody": { + "id": 8450, + "nodeType": "Block", + "src": "23956:194:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 8442, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8435, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "23978:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 8437, + "indexExpression": { + "argumentTypes": null, + "id": 8436, + "name": "last_answer_or_commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8403, + "src": "23990:28:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "23978:41:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "id": 8438, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "reveal_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7266, + "src": "23978:51:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8440, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "24039:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 8439, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "24032:6:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint32_$", + "typeString": "type(uint32)" + }, + "typeName": "uint32" + }, + "id": 8441, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24032:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "23978:65:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "596f75206d757374207761697420666f72207468652072657665616c20646561646c696e65206265666f72652066696e616c697a696e67", + "id": 8443, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "24045:57:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_59906a33bbcf0bc176ce61cc097b3e9182f12a3fed11d73df0b39558e782f100", + "typeString": "literal_string \"You must wait for the reveal deadline before finalizing\"" + }, + "value": "You must wait for the reveal deadline before finalizing" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_59906a33bbcf0bc176ce61cc097b3e9182f12a3fed11d73df0b39558e782f100", + "typeString": "literal_string \"You must wait for the reveal deadline before finalizing\"" + } + ], + "id": 8434, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "23970:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 8444, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "23970:133:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8445, + "nodeType": "ExpressionStatement", + "src": "23970:133:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8448, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 8446, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8425, + "src": "24117:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 8447, + "name": "payee_if_wrong", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8399, + "src": "24125:14:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "24117:22:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 8449, + "nodeType": "ExpressionStatement", + "src": "24117:22:18" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8467, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8395, + "src": "24302:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8468, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8397, + "src": "24315:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8469, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8425, + "src": "24323:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 8466, + "name": "submitAnswerByArbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8393, + "src": "24277:24:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_address_$returns$__$", + "typeString": "function (bytes32,bytes32,address)" + } + }, + "id": 8470, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24277:52:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8471, + "nodeType": "ExpressionStatement", + "src": "24277:52:18" + } + ] + }, + "documentation": "@notice Submit the answer for a question, for use by the arbitrator, working out the appropriate winner based on the last answer details.\n @dev Doesn't require (or allow) a bond.\n @param question_id The ID of the question\n @param answer The answer, encoded into bytes32\n @param payee_if_wrong The account to by credited as winner if the last answer given is wrong, usually the account that paid the arbitrator\n @param last_history_hash The history hash before the final one\n @param last_answer_or_commitment_id The last answer given, or the commitment ID if it was a commitment.\n @param last_answerer The address that supplied the last answer", + "id": 8473, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "assignWinnerAndSubmitAnswerByArbitrator", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8406, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8395, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8473, + "src": "23306:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8394, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "23306:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8397, + "name": "answer", + "nodeType": "VariableDeclaration", + "scope": 8473, + "src": "23327:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8396, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "23327:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8399, + "name": "payee_if_wrong", + "nodeType": "VariableDeclaration", + "scope": 8473, + "src": "23343:22:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8398, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "23343:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8401, + "name": "last_history_hash", + "nodeType": "VariableDeclaration", + "scope": 8473, + "src": "23367:25:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8400, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "23367:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8403, + "name": "last_answer_or_commitment_id", + "nodeType": "VariableDeclaration", + "scope": 8473, + "src": "23394:36:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8402, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "23394:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8405, + "name": "last_answerer", + "nodeType": "VariableDeclaration", + "scope": 8473, + "src": "23432:21:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8404, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "23432:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "23305:149:18" + }, + "payable": false, + "returnParameters": { + "id": 8407, + "nodeType": "ParameterList", + "parameters": [], + "src": "23469:0:18" + }, + "scope": 9314, + "src": "23257:1079:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 8506, + "nodeType": "Block", + "src": "24589:201:18", + "statements": [ + { + "assignments": [ + 8481 + ], + "declarations": [ + { + "constant": false, + "id": 8481, + "name": "finalize_ts", + "nodeType": "VariableDeclaration", + "scope": 8507, + "src": "24599:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 8480, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "24599:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8486, + "initialValue": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8482, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "24620:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8484, + "indexExpression": { + "argumentTypes": null, + "id": 8483, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8475, + "src": "24630:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "24620:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8485, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "finalize_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7253, + "src": "24620:34:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "24599:55:18" + }, + { + "expression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 8503, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 8496, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8491, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "24673:46:18", + "subExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8487, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "24674:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8489, + "indexExpression": { + "argumentTypes": null, + "id": 8488, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8475, + "src": "24684:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "24674:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8490, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "is_pending_arbitration", + "nodeType": "MemberAccess", + "referencedDeclaration": 7255, + "src": "24674:45:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 8494, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8492, + "name": "finalize_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8481, + "src": "24724:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "id": 8493, + "name": "UNANSWERED", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7134, + "src": "24738:10:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "24724:24:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 8495, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "24723:26:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "24673:76:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 8501, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8497, + "name": "finalize_ts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8481, + "src": "24754:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8499, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9718, + "src": "24776:3:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 8498, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "24769:6:18", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint32_$", + "typeString": "type(uint32)" + }, + "typeName": "uint32" + }, + "id": 8500, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24769:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "24754:26:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 8502, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "24753:28:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "24673:108:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 8504, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "24671:112:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "functionReturnParameters": 8479, + "id": 8505, + "nodeType": "Return", + "src": "24664:119:18" + } + ] + }, + "documentation": "@notice Report whether the answer to the specified question is finalized\n @param question_id The ID of the question\n @return Return true if finalized", + "id": 8507, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "isFinalized", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8476, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8475, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8507, + "src": "24536:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8474, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "24536:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "24535:21:18" + }, + "payable": false, + "returnParameters": { + "id": 8479, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8478, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 8507, + "src": "24583:4:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 8477, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "24583:4:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "24582:6:18" + }, + "scope": 9314, + "src": "24515:275:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 8522, + "nodeType": "Block", + "src": "25123:58:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8517, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "25140:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8519, + "indexExpression": { + "argumentTypes": null, + "id": 8518, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8509, + "src": "25150:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "25140:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8520, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "best_answer", + "nodeType": "MemberAccess", + "referencedDeclaration": 7259, + "src": "25140:34:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 8516, + "id": 8521, + "nodeType": "Return", + "src": "25133:41:18" + } + ] + }, + "documentation": "@notice (Deprecated) Return the final answer to the specified question, or revert if there isn't one\n @param question_id The ID of the question\n @return The answer formatted as a bytes32", + "id": 8523, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 8512, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8509, + "src": "25074:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8513, + "modifierName": { + "argumentTypes": null, + "id": 8511, + "name": "stateFinalized", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7490, + "src": "25059:14:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "25059:27:18" + } + ], + "name": "getFinalAnswer", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8510, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8509, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8523, + "src": "25029:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8508, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "25029:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "25028:21:18" + }, + "payable": false, + "returnParameters": { + "id": 8516, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8515, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 8523, + "src": "25114:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8514, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "25114:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "25113:9:18" + }, + "scope": 9314, + "src": "25005:176:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 8538, + "nodeType": "Block", + "src": "25496:58:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8533, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "25513:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8535, + "indexExpression": { + "argumentTypes": null, + "id": 8534, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8525, + "src": "25523:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "25513:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8536, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "best_answer", + "nodeType": "MemberAccess", + "referencedDeclaration": 7259, + "src": "25513:34:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 8532, + "id": 8537, + "nodeType": "Return", + "src": "25506:41:18" + } + ] + }, + "documentation": "@notice Return the final answer to the specified question, or revert if there isn't one\n @param question_id The ID of the question\n @return The answer formatted as a bytes32", + "id": 8539, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 8528, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8525, + "src": "25447:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8529, + "modifierName": { + "argumentTypes": null, + "id": 8527, + "name": "stateFinalized", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7490, + "src": "25432:14:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "25432:27:18" + } + ], + "name": "resultFor", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8526, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8525, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8539, + "src": "25402:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8524, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "25402:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "25401:21:18" + }, + "payable": false, + "returnParameters": { + "id": 8532, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8531, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 8539, + "src": "25487:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8530, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "25487:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "25486:9:18" + }, + "scope": 9314, + "src": "25383:171:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 8602, + "nodeType": "Block", + "src": "26532:427:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 8563, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8558, + "name": "content_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8543, + "src": "26550:12:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8559, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "26566:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8561, + "indexExpression": { + "argumentTypes": null, + "id": 8560, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8541, + "src": "26576:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "26566:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8562, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "content_hash", + "nodeType": "MemberAccess", + "referencedDeclaration": 7245, + "src": "26566:35:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "26550:51:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "636f6e74656e742068617368206d757374206d61746368", + "id": 8564, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26603:25:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_1ab4f91b91ff887ba4101461ee7fdff8a9550df020c832d7174034a04b833c71", + "typeString": "literal_string \"content hash must match\"" + }, + "value": "content hash must match" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_1ab4f91b91ff887ba4101461ee7fdff8a9550df020c832d7174034a04b833c71", + "typeString": "literal_string \"content hash must match\"" + } + ], + "id": 8557, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "26542:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 8565, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "26542:87:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8566, + "nodeType": "ExpressionStatement", + "src": "26542:87:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 8573, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8568, + "name": "arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8545, + "src": "26647:10:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8569, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "26661:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8571, + "indexExpression": { + "argumentTypes": null, + "id": 8570, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8541, + "src": "26671:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "26661:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8572, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "arbitrator", + "nodeType": "MemberAccess", + "referencedDeclaration": 7247, + "src": "26661:33:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "26647:47:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "61726269747261746f72206d757374206d61746368", + "id": 8574, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26696:23:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_e14333e0b7159d63d81a1f747c3418d619023485dd483dee8ea5dfb57b0ff723", + "typeString": "literal_string \"arbitrator must match\"" + }, + "value": "arbitrator must match" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_e14333e0b7159d63d81a1f747c3418d619023485dd483dee8ea5dfb57b0ff723", + "typeString": "literal_string \"arbitrator must match\"" + } + ], + "id": 8567, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "26639:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 8575, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "26639:81:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8576, + "nodeType": "ExpressionStatement", + "src": "26639:81:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "id": 8583, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8578, + "name": "min_timeout", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8547, + "src": "26738:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8579, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "26753:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8581, + "indexExpression": { + "argumentTypes": null, + "id": 8580, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8541, + "src": "26763:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "26753:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8582, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timeout", + "nodeType": "MemberAccess", + "referencedDeclaration": 7251, + "src": "26753:30:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "26738:45:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "74696d656f7574206d757374206265206c6f6e6720656e6f756768", + "id": 8584, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26785:29:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_cc60de11d8ba89bb648c5bc8147e6f8669fe77735adef82b63fc28eef3d7dfeb", + "typeString": "literal_string \"timeout must be long enough\"" + }, + "value": "timeout must be long enough" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_cc60de11d8ba89bb648c5bc8147e6f8669fe77735adef82b63fc28eef3d7dfeb", + "typeString": "literal_string \"timeout must be long enough\"" + } + ], + "id": 8577, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "26730:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 8585, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "26730:85:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8586, + "nodeType": "ExpressionStatement", + "src": "26730:85:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 8593, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8588, + "name": "min_bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8549, + "src": "26833:8:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8589, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "26845:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8591, + "indexExpression": { + "argumentTypes": null, + "id": 8590, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8541, + "src": "26855:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "26845:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8592, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bond", + "nodeType": "MemberAccess", + "referencedDeclaration": 7263, + "src": "26845:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "26833:39:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "626f6e64206d757374206265206869676820656e6f756768", + "id": 8594, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26874:26:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_4fbe9b5254b5b7c01e42aaadc74b327644dc528a9916fa76193407d46b5c0951", + "typeString": "literal_string \"bond must be high enough\"" + }, + "value": "bond must be high enough" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_4fbe9b5254b5b7c01e42aaadc74b327644dc528a9916fa76193407d46b5c0951", + "typeString": "literal_string \"bond must be high enough\"" + } + ], + "id": 8587, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "26825:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 8595, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "26825:76:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8596, + "nodeType": "ExpressionStatement", + "src": "26825:76:18" + }, + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8597, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "26918:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8599, + "indexExpression": { + "argumentTypes": null, + "id": 8598, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8541, + "src": "26928:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "26918:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8600, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "best_answer", + "nodeType": "MemberAccess", + "referencedDeclaration": 7259, + "src": "26918:34:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 8556, + "id": 8601, + "nodeType": "Return", + "src": "26911:41:18" + } + ] + }, + "documentation": "@notice Return the final answer to the specified question, provided it matches the specified criteria.\n @dev Reverts if the question is not finalized, or if it does not match the specified criteria.\n @param question_id The ID of the question\n @param content_hash The hash of the question content (template ID + opening time + question parameter string)\n @param arbitrator The arbitrator chosen for the question (regardless of whether they are asked to arbitrate)\n @param min_timeout The timeout set in the initial question settings must be this high or higher\n @param min_bond The bond sent with the final answer must be this high or higher\n @return The answer formatted as a bytes32", + "id": 8603, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 8552, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8541, + "src": "26483:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8553, + "modifierName": { + "argumentTypes": null, + "id": 8551, + "name": "stateFinalized", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7490, + "src": "26468:14:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "26468:27:18" + } + ], + "name": "getFinalAnswerIfMatches", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8550, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8541, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8603, + "src": "26344:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8540, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "26344:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8543, + "name": "content_hash", + "nodeType": "VariableDeclaration", + "scope": 8603, + "src": "26374:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8542, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "26374:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8545, + "name": "arbitrator", + "nodeType": "VariableDeclaration", + "scope": 8603, + "src": "26396:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8544, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "26396:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8547, + "name": "min_timeout", + "nodeType": "VariableDeclaration", + "scope": 8603, + "src": "26416:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 8546, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "26416:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8549, + "name": "min_bond", + "nodeType": "VariableDeclaration", + "scope": 8603, + "src": "26436:16:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8548, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "26436:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "26334:124:18" + }, + "payable": false, + "returnParameters": { + "id": 8556, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8555, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 8603, + "src": "26523:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8554, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "26523:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "26522:9:18" + }, + "scope": 9314, + "src": "26302:657:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 8820, + "nodeType": "Block", + "src": "28471:2958:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 8627, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 8624, + "name": "history_hashes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8608, + "src": "28490:14:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 8625, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "28490:21:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 8626, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "28514:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "28490:25:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "6174206c65617374206f6e6520686973746f7279206861736820656e747279206d7573742062652070726f7669646564", + "id": 8628, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "28517:50:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_e887b9c35a99bf27d861fac479e37f4d87d4bceab6db3e0e5edcbd73f35992ed", + "typeString": "literal_string \"at least one history hash entry must be provided\"" + }, + "value": "at least one history hash entry must be provided" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_e887b9c35a99bf27d861fac479e37f4d87d4bceab6db3e0e5edcbd73f35992ed", + "typeString": "literal_string \"at least one history hash entry must be provided\"" + } + ], + "id": 8623, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9719, + 9720 + ], + "referencedDeclaration": 9720, + "src": "28482:7:18", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 8629, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "28482:86:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8630, + "nodeType": "ExpressionStatement", + "src": "28482:86:18" + }, + { + "assignments": [ + 8632 + ], + "declarations": [ + { + "constant": false, + "id": 8632, + "name": "payee", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "28659:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8631, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "28659:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8637, + "initialValue": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8633, + "name": "question_claims", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7297, + "src": "28675:15:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Claim_$7278_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Claim storage ref)" + } + }, + "id": 8635, + "indexExpression": { + "argumentTypes": null, + "id": 8634, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "28691:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "28675:28:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Claim_$7278_storage", + "typeString": "struct Realitio_v2_1.Claim storage ref" + } + }, + "id": 8636, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "payee", + "nodeType": "MemberAccess", + "referencedDeclaration": 7273, + "src": "28675:34:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "28659:50:18" + }, + { + "assignments": [ + 8639 + ], + "declarations": [ + { + "constant": false, + "id": 8639, + "name": "last_bond", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "28720:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8638, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "28720:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8644, + "initialValue": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8640, + "name": "question_claims", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7297, + "src": "28740:15:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Claim_$7278_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Claim storage ref)" + } + }, + "id": 8642, + "indexExpression": { + "argumentTypes": null, + "id": 8641, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "28756:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "28740:28:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Claim_$7278_storage", + "typeString": "struct Realitio_v2_1.Claim storage ref" + } + }, + "id": 8643, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "last_bond", + "nodeType": "MemberAccess", + "referencedDeclaration": 7275, + "src": "28740:38:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "28720:58:18" + }, + { + "assignments": [ + 8646 + ], + "declarations": [ + { + "constant": false, + "id": 8646, + "name": "queued_funds", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "28789:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8645, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "28789:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8651, + "initialValue": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8647, + "name": "question_claims", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7297, + "src": "28812:15:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Claim_$7278_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Claim storage ref)" + } + }, + "id": 8649, + "indexExpression": { + "argumentTypes": null, + "id": 8648, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "28828:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "28812:28:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Claim_$7278_storage", + "typeString": "struct Realitio_v2_1.Claim storage ref" + } + }, + "id": 8650, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "queued_funds", + "nodeType": "MemberAccess", + "referencedDeclaration": 7277, + "src": "28812:41:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "28789:64:18" + }, + { + "assignments": [ + 8653 + ], + "declarations": [ + { + "constant": false, + "id": 8653, + "name": "last_history_hash", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "29074:25:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8652, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "29074:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8658, + "initialValue": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8654, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "29102:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8656, + "indexExpression": { + "argumentTypes": null, + "id": 8655, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "29112:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "29102:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8657, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "history_hash", + "nodeType": "MemberAccess", + "referencedDeclaration": 7261, + "src": "29102:35:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "29074:63:18" + }, + { + "assignments": [ + 8660 + ], + "declarations": [ + { + "constant": false, + "id": 8660, + "name": "best_answer", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "29148:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8659, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "29148:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8665, + "initialValue": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8661, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "29170:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8663, + "indexExpression": { + "argumentTypes": null, + "id": 8662, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "29180:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "29170:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8664, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "best_answer", + "nodeType": "MemberAccess", + "referencedDeclaration": 7259, + "src": "29170:34:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "29148:56:18" + }, + { + "assignments": [], + "declarations": [ + { + "constant": false, + "id": 8667, + "name": "i", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "29215:9:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8666, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "29215:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8668, + "initialValue": null, + "nodeType": "VariableDeclarationStatement", + "src": "29215:9:18" + }, + { + "body": { + "id": 8755, + "nodeType": "Block", + "src": "29278:1075:18", + "statements": [ + { + "assignments": [ + 8681 + ], + "declarations": [ + { + "constant": false, + "id": 8681, + "name": "is_commitment", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "29412:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 8680, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "29412:4:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8697, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8683, + "name": "last_history_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8653, + "src": "29461:17:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8684, + "name": "history_hashes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8608, + "src": "29480:14:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 8686, + "indexExpression": { + "argumentTypes": null, + "id": 8685, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "29495:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "29480:17:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8687, + "name": "answers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8617, + "src": "29499:7:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 8689, + "indexExpression": { + "argumentTypes": null, + "id": 8688, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "29507:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "29499:10:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8690, + "name": "bonds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8614, + "src": "29511:5:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 8692, + "indexExpression": { + "argumentTypes": null, + "id": 8691, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "29517:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "29511:8:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8693, + "name": "addrs", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8611, + "src": "29521:5:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + "id": 8695, + "indexExpression": { + "argumentTypes": null, + "id": 8694, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "29527:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "29521:8:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 8682, + "name": "_verifyHistoryInputOrRevert", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8900, + "src": "29433:27:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes32_$_t_bytes32_$_t_bytes32_$_t_uint256_$_t_address_$returns$_t_bool_$", + "typeString": "function (bytes32,bytes32,bytes32,uint256,address) pure returns (bool)" + } + }, + "id": 8696, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "29433:97:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "29412:118:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8703, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 8698, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8646, + "src": "29557:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8701, + "name": "last_bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8639, + "src": "29589:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 8699, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8646, + "src": "29572:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8700, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 7080, + "src": "29572:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 8702, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "29572:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "29557:42:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8704, + "nodeType": "ExpressionStatement", + "src": "29557:42:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8724, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "id": 8705, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8646, + "src": "29615:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 8706, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8632, + "src": "29629:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "id": 8707, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "29614:21:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_address_$", + "typeString": "tuple(uint256,address)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8709, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "29675:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8710, + "name": "best_answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8660, + "src": "29688:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8711, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8646, + "src": "29701:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 8712, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8632, + "src": "29715:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8713, + "name": "addrs", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8611, + "src": "29739:5:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + "id": 8715, + "indexExpression": { + "argumentTypes": null, + "id": 8714, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "29745:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "29739:8:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8716, + "name": "bonds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8614, + "src": "29749:5:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 8718, + "indexExpression": { + "argumentTypes": null, + "id": 8717, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "29755:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "29749:8:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8719, + "name": "answers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8617, + "src": "29759:7:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 8721, + "indexExpression": { + "argumentTypes": null, + "id": 8720, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "29767:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "29759:10:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8722, + "name": "is_commitment", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8681, + "src": "29771:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 8708, + "name": "_processHistoryItem", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9027, + "src": "29638:19:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_uint256_$_t_address_$_t_address_$_t_uint256_$_t_bytes32_$_t_bool_$returns$_t_uint256_$_t_address_$", + "typeString": "function (bytes32,bytes32,uint256,address,address,uint256,bytes32,bool) returns (uint256,address)" + } + }, + "id": 8723, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "29638:147:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_address_$", + "typeString": "tuple(uint256,address)" + } + }, + "src": "29614:171:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8725, + "nodeType": "ExpressionStatement", + "src": "29614:171:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8730, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 8726, + "name": "last_bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8639, + "src": "29897:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8727, + "name": "bonds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8614, + "src": "29909:5:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 8729, + "indexExpression": { + "argumentTypes": null, + "id": 8728, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "29915:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "29909:8:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "29897:20:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8731, + "nodeType": "ExpressionStatement", + "src": "29897:20:18" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 8737, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8732, + "name": "last_bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8639, + "src": "30151:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8733, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "30164:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8735, + "indexExpression": { + "argumentTypes": null, + "id": 8734, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "30174:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "30164:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8736, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bond", + "nodeType": "MemberAccess", + "referencedDeclaration": 7263, + "src": "30164:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "30151:40:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 8748, + "nodeType": "IfStatement", + "src": "30147:143:18", + "trueBody": { + "id": 8747, + "nodeType": "Block", + "src": "30193:97:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 8745, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 8738, + "name": "last_bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8639, + "src": "30211:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 8743, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8741, + "name": "last_bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8639, + "src": "30237:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "/", + "rightExpression": { + "argumentTypes": null, + "id": 8742, + "name": "BOND_CLAIM_FEE_PROPORTION", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7143, + "src": "30249:25:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "30237:37:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 8739, + "name": "last_bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8639, + "src": "30223:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8740, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sub", + "nodeType": "MemberAccess", + "referencedDeclaration": 7056, + "src": "30223:13:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 8744, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "30223:52:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "30211:64:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8746, + "nodeType": "ExpressionStatement", + "src": "30211:64:18" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "id": 8753, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 8749, + "name": "last_history_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8653, + "src": "30304:17:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8750, + "name": "history_hashes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8608, + "src": "30324:14:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 8752, + "indexExpression": { + "argumentTypes": null, + "id": 8751, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "30339:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "30324:17:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "30304:37:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 8754, + "nodeType": "ExpressionStatement", + "src": "30304:37:18" + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 8676, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8673, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "29246:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 8674, + "name": "history_hashes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8608, + "src": "29250:14:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 8675, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "29250:21:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "29246:25:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 8756, + "initializationExpression": { + "expression": { + "argumentTypes": null, + "id": 8671, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 8669, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "29239:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "30", + "id": 8670, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "29243:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "29239:5:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8672, + "nodeType": "ExpressionStatement", + "src": "29239:5:18" + }, + "loopExpression": { + "expression": { + "argumentTypes": null, + "id": 8678, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "29273:3:18", + "subExpression": { + "argumentTypes": null, + "id": 8677, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8667, + "src": "29273:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8679, + "nodeType": "ExpressionStatement", + "src": "29273:3:18" + }, + "nodeType": "ForStatement", + "src": "29234:1119:18" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 8759, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8757, + "name": "last_history_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8653, + "src": "30368:17:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "id": 8758, + "name": "NULL_HASH", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7131, + "src": "30389:9:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "30368:30:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 8811, + "nodeType": "Block", + "src": "31143:213:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8798, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "31248:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8799, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8632, + "src": "31261:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8802, + "name": "last_bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8639, + "src": "31285:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 8800, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8646, + "src": "31268:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8801, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 7080, + "src": "31268:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 8803, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "31268:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 8797, + "name": "_payPayee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8848, + "src": "31238:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (bytes32,address,uint256)" + } + }, + "id": 8804, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "31238:58:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8805, + "nodeType": "ExpressionStatement", + "src": "31238:58:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8809, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "delete", + "prefix": true, + "src": "31310:35:18", + "subExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8806, + "name": "question_claims", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7297, + "src": "31317:15:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Claim_$7278_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Claim storage ref)" + } + }, + "id": 8808, + "indexExpression": { + "argumentTypes": null, + "id": 8807, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "31333:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "31317:28:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Claim_$7278_storage", + "typeString": "struct Realitio_v2_1.Claim storage ref" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8810, + "nodeType": "ExpressionStatement", + "src": "31310:35:18" + } + ] + }, + "id": 8812, + "nodeType": "IfStatement", + "src": "30364:992:18", + "trueBody": { + "id": 8796, + "nodeType": "Block", + "src": "30400:737:18", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 8762, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8760, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8632, + "src": "30803:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "id": 8761, + "name": "NULL_ADDRESS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7126, + "src": "30812:12:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "30803:21:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 8774, + "nodeType": "IfStatement", + "src": "30799:137:18", + "trueBody": { + "id": 8773, + "nodeType": "Block", + "src": "30826:110:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8764, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "30854:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8765, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8632, + "src": "30867:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 8766, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8646, + "src": "30874:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 8763, + "name": "_payPayee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8848, + "src": "30844:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (bytes32,address,uint256)" + } + }, + "id": 8767, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "30844:43:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8768, + "nodeType": "ExpressionStatement", + "src": "30844:43:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8771, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 8769, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8646, + "src": "30905:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "30", + "id": 8770, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "30920:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "30905:16:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8772, + "nodeType": "ExpressionStatement", + "src": "30905:16:18" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "id": 8780, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8775, + "name": "question_claims", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7297, + "src": "30950:15:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Claim_$7278_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Claim storage ref)" + } + }, + "id": 8777, + "indexExpression": { + "argumentTypes": null, + "id": 8776, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "30966:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "30950:28:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Claim_$7278_storage", + "typeString": "struct Realitio_v2_1.Claim storage ref" + } + }, + "id": 8778, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "payee", + "nodeType": "MemberAccess", + "referencedDeclaration": 7273, + "src": "30950:34:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 8779, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8632, + "src": "30987:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "30950:42:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 8781, + "nodeType": "ExpressionStatement", + "src": "30950:42:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8787, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8782, + "name": "question_claims", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7297, + "src": "31006:15:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Claim_$7278_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Claim storage ref)" + } + }, + "id": 8784, + "indexExpression": { + "argumentTypes": null, + "id": 8783, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "31022:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "31006:28:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Claim_$7278_storage", + "typeString": "struct Realitio_v2_1.Claim storage ref" + } + }, + "id": 8785, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "last_bond", + "nodeType": "MemberAccess", + "referencedDeclaration": 7275, + "src": "31006:38:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 8786, + "name": "last_bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8639, + "src": "31047:9:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "31006:50:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8788, + "nodeType": "ExpressionStatement", + "src": "31006:50:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8794, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8789, + "name": "question_claims", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7297, + "src": "31070:15:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Claim_$7278_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Claim storage ref)" + } + }, + "id": 8791, + "indexExpression": { + "argumentTypes": null, + "id": 8790, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "31086:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "31070:28:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Claim_$7278_storage", + "typeString": "struct Realitio_v2_1.Claim storage ref" + } + }, + "id": 8792, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "queued_funds", + "nodeType": "MemberAccess", + "referencedDeclaration": 7277, + "src": "31070:41:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 8793, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8646, + "src": "31114:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "31070:56:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8795, + "nodeType": "ExpressionStatement", + "src": "31070:56:18" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "id": 8818, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8813, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "31366:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8815, + "indexExpression": { + "argumentTypes": null, + "id": 8814, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "31376:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "31366:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8816, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "history_hash", + "nodeType": "MemberAccess", + "referencedDeclaration": 7261, + "src": "31366:35:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 8817, + "name": "last_history_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8653, + "src": "31404:17:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "31366:55:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 8819, + "nodeType": "ExpressionStatement", + "src": "31366:55:18" + } + ] + }, + "documentation": "@notice Assigns the winnings (bounty and bonds) to everyone who gave the accepted answer\n Caller must provide the answer history, in reverse order\n @dev Works up the chain and assign bonds to the person who gave the right answer\n If someone gave the winning answer earlier, they must get paid from the higher bond\n That means we can't pay out the bond added at n until we have looked at n-1\n The first answer is authenticated by checking against the stored history_hash.\n One of the inputs to history_hash is the history_hash before it, so we use that to authenticate the next entry, etc\n Once we get to a null hash we'll know we're done and there are no more answers.\n Usually you would call the whole thing in a single transaction, but if not then the data is persisted to pick up later.\n @param question_id The ID of the question\n @param history_hashes Second-last-to-first, the hash of each history entry. (Final one should be empty).\n @param addrs Last-to-first, the address of each answerer or commitment sender\n @param bonds Last-to-first, the bond supplied with each answer or commitment\n @param answers Last-to-first, each answer supplied, or commitment ID if the answer was supplied with commit->reveal", + "id": 8821, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 8620, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8605, + "src": "28447:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 8621, + "modifierName": { + "argumentTypes": null, + "id": 8619, + "name": "stateFinalized", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7490, + "src": "28432:14:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "28432:27:18" + } + ], + "name": "claimWinnings", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8618, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8605, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "28309:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8604, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "28309:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8608, + "name": "history_hashes", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "28339:24:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[]" + }, + "typeName": { + "baseType": { + "id": 8606, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "28339:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 8607, + "length": null, + "nodeType": "ArrayTypeName", + "src": "28339:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8611, + "name": "addrs", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "28365:15:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[]" + }, + "typeName": { + "baseType": { + "id": 8609, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "28365:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 8610, + "length": null, + "nodeType": "ArrayTypeName", + "src": "28365:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", + "typeString": "address[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8614, + "name": "bonds", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "28382:15:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[]" + }, + "typeName": { + "baseType": { + "id": 8612, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "28382:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8613, + "length": null, + "nodeType": "ArrayTypeName", + "src": "28382:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8617, + "name": "answers", + "nodeType": "VariableDeclaration", + "scope": 8821, + "src": "28399:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[]" + }, + "typeName": { + "baseType": { + "id": 8615, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "28399:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 8616, + "length": null, + "nodeType": "ArrayTypeName", + "src": "28399:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "28299:123:18" + }, + "payable": false, + "returnParameters": { + "id": 8622, + "nodeType": "ParameterList", + "parameters": [], + "src": "28471:0:18" + }, + "scope": 9314, + "src": "28277:3152:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 8847, + "nodeType": "Block", + "src": "31519:113:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 8839, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8830, + "name": "balanceOf", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 396, + "src": "31529:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 8832, + "indexExpression": { + "argumentTypes": null, + "id": 8831, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8825, + "src": "31539:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "31529:16:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8837, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8827, + "src": "31569:5:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8833, + "name": "balanceOf", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 396, + "src": "31548:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 8835, + "indexExpression": { + "argumentTypes": null, + "id": 8834, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8825, + "src": "31558:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "31548:16:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8836, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 7080, + "src": "31548:20:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 8838, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "31548:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "31529:46:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8840, + "nodeType": "ExpressionStatement", + "src": "31529:46:18" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8842, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8823, + "src": "31599:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8843, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8825, + "src": "31612:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 8844, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8827, + "src": "31619:5:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 8841, + "name": "LogClaim", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7243, + "src": "31590:8:18", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (bytes32,address,uint256)" + } + }, + "id": 8845, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "31590:35:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8846, + "nodeType": "EmitStatement", + "src": "31585:40:18" + } + ] + }, + "documentation": null, + "id": 8848, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "_payPayee", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8828, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8823, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 8848, + "src": "31454:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8822, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "31454:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8825, + "name": "payee", + "nodeType": "VariableDeclaration", + "scope": 8848, + "src": "31475:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8824, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "31475:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8827, + "name": "value", + "nodeType": "VariableDeclaration", + "scope": 8848, + "src": "31490:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8826, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "31490:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "31453:51:18" + }, + "payable": false, + "returnParameters": { + "id": 8829, + "nodeType": "ParameterList", + "parameters": [], + "src": "31519:0:18" + }, + "scope": 9314, + "src": "31435:197:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 8899, + "nodeType": "Block", + "src": "31823:364:18", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 8874, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8863, + "name": "last_history_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8850, + "src": "31837:17:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8867, + "name": "history_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8852, + "src": "31885:12:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8868, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8854, + "src": "31899:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8869, + "name": "bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8856, + "src": "31907:4:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 8870, + "name": "addr", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8858, + "src": "31913:4:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "hexValue": "74727565", + "id": 8871, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "31919:4:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "expression": { + "argumentTypes": null, + "id": 8865, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9703, + "src": "31868:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 8866, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "31868:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 8872, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "31868:56:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 8864, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9710, + "src": "31858:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 8873, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "31858:67:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "31837:88:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 8878, + "nodeType": "IfStatement", + "src": "31833:131:18", + "trueBody": { + "id": 8877, + "nodeType": "Block", + "src": "31928:36:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 8875, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "31949:4:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "functionReturnParameters": 8862, + "id": 8876, + "nodeType": "Return", + "src": "31942:11:18" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 8890, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8879, + "name": "last_history_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8850, + "src": "31977:17:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 8883, + "name": "history_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8852, + "src": "32025:12:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8884, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8854, + "src": "32039:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 8885, + "name": "bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8856, + "src": "32047:4:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 8886, + "name": "addr", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8858, + "src": "32053:4:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 8887, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "32059:5:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "expression": { + "argumentTypes": null, + "id": 8881, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9703, + "src": "32008:3:18", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 8882, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "32008:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 8888, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "32008:57:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 8880, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9710, + "src": "31998:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 8889, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "31998:68:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "31977:89:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 8894, + "nodeType": "IfStatement", + "src": "31973:133:18", + "trueBody": { + "id": 8893, + "nodeType": "Block", + "src": "32069:37:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 8891, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "32090:5:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "functionReturnParameters": 8862, + "id": 8892, + "nodeType": "Return", + "src": "32083:12:18" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "486973746f727920696e7075742070726f766964656420646964206e6f74206d61746368207468652065787065637465642068617368", + "id": 8896, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "32123:56:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_105eb464ca1766d0405b5fa901151a4c75699ccc5e522facb7c8a5407d6bd553", + "typeString": "literal_string \"History input provided did not match the expected hash\"" + }, + "value": "History input provided did not match the expected hash" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_105eb464ca1766d0405b5fa901151a4c75699ccc5e522facb7c8a5407d6bd553", + "typeString": "literal_string \"History input provided did not match the expected hash\"" + } + ], + "id": 8895, + "name": "revert", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 9721, + 9722 + ], + "referencedDeclaration": 9722, + "src": "32116:6:18", + "typeDescriptions": { + "typeIdentifier": "t_function_revert_pure$_t_string_memory_ptr_$returns$__$", + "typeString": "function (string memory) pure" + } + }, + "id": 8897, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "32116:64:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8898, + "nodeType": "ExpressionStatement", + "src": "32116:64:18" + } + ] + }, + "documentation": null, + "id": 8900, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "_verifyHistoryInputOrRevert", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8859, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8850, + "name": "last_history_hash", + "nodeType": "VariableDeclaration", + "scope": 8900, + "src": "31684:25:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8849, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "31684:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8852, + "name": "history_hash", + "nodeType": "VariableDeclaration", + "scope": 8900, + "src": "31719:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8851, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "31719:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8854, + "name": "answer", + "nodeType": "VariableDeclaration", + "scope": 8900, + "src": "31741:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8853, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "31741:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8856, + "name": "bond", + "nodeType": "VariableDeclaration", + "scope": 8900, + "src": "31757:12:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8855, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "31757:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8858, + "name": "addr", + "nodeType": "VariableDeclaration", + "scope": 8900, + "src": "31771:12:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8857, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "31771:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "31674:115:18" + }, + "payable": false, + "returnParameters": { + "id": 8862, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8861, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 8900, + "src": "31817:4:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 8860, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "31817:4:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "31816:6:18" + }, + "scope": 9314, + "src": "31638:549:18", + "stateMutability": "pure", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 9026, + "nodeType": "Block", + "src": "32437:2167:18", + "statements": [ + { + "condition": { + "argumentTypes": null, + "id": 8923, + "name": "is_commitment", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8916, + "src": "32636:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 8958, + "nodeType": "IfStatement", + "src": "32632:482:18", + "trueBody": { + "id": 8957, + "nodeType": "Block", + "src": "32651:463:18", + "statements": [ + { + "assignments": [ + 8925 + ], + "declarations": [ + { + "constant": false, + "id": 8925, + "name": "commitment_id", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "32665:21:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8924, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "32665:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8927, + "initialValue": { + "argumentTypes": null, + "id": 8926, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8914, + "src": "32689:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "32665:30:18" + }, + { + "condition": { + "argumentTypes": null, + "id": 8932, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "32810:39:18", + "subExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8928, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "32811:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 8930, + "indexExpression": { + "argumentTypes": null, + "id": 8929, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8925, + "src": "32823:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "32811:26:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "id": 8931, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "is_revealed", + "nodeType": "MemberAccess", + "referencedDeclaration": 7268, + "src": "32811:38:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 8955, + "nodeType": "Block", + "src": "32969:135:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 8948, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 8943, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8914, + "src": "32987:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8944, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "32996:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 8946, + "indexExpression": { + "argumentTypes": null, + "id": 8945, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8925, + "src": "33008:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "32996:26:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "id": 8947, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "revealed_answer", + "nodeType": "MemberAccess", + "referencedDeclaration": 7270, + "src": "32996:42:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "32987:51:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 8949, + "nodeType": "ExpressionStatement", + "src": "32987:51:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8953, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "delete", + "prefix": true, + "src": "33056:33:18", + "subExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8950, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "33063:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 8952, + "indexExpression": { + "argumentTypes": null, + "id": 8951, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8925, + "src": "33075:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "33063:26:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8954, + "nodeType": "ExpressionStatement", + "src": "33056:33:18" + } + ] + }, + "id": 8956, + "nodeType": "IfStatement", + "src": "32806:298:18", + "trueBody": { + "id": 8942, + "nodeType": "Block", + "src": "32851:112:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 8936, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "delete", + "prefix": true, + "src": "32869:33:18", + "subExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8933, + "name": "commitments", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7301, + "src": "32876:11:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Commitment_$7271_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Commitment storage ref)" + } + }, + "id": 8935, + "indexExpression": { + "argumentTypes": null, + "id": 8934, + "name": "commitment_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8925, + "src": "32888:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "32876:26:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Commitment_$7271_storage", + "typeString": "struct Realitio_v2_1.Commitment storage ref" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 8937, + "nodeType": "ExpressionStatement", + "src": "32869:33:18" + }, + { + "expression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "id": 8938, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8906, + "src": "32928:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 8939, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8908, + "src": "32942:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "id": 8940, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "32927:21:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_address_$", + "typeString": "tuple(uint256,address)" + } + }, + "functionReturnParameters": 8922, + "id": 8941, + "nodeType": "Return", + "src": "32920:28:18" + } + ] + } + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 8961, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8959, + "name": "answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8914, + "src": "33128:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 8960, + "name": "best_answer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8904, + "src": "33138:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "33128:21:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 9021, + "nodeType": "IfStatement", + "src": "33124:1434:18", + "trueBody": { + "id": 9020, + "nodeType": "Block", + "src": "33151:1407:18", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 8964, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8962, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8908, + "src": "33170:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 8963, + "name": "NULL_ADDRESS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7126, + "src": "33179:12:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "33170:21:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 8989, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8987, + "name": "addr", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8910, + "src": "33509:4:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "id": 8988, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8908, + "src": "33517:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "33509:13:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 9018, + "nodeType": "IfStatement", + "src": "33505:1042:18", + "trueBody": { + "id": 9017, + "nodeType": "Block", + "src": "33524:1023:18", + "statements": [ + { + "assignments": [ + 8991 + ], + "declarations": [ + { + "constant": false, + "id": 8991, + "name": "answer_takeover_fee", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "34143:27:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8990, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "34143:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8999, + "initialValue": { + "argumentTypes": null, + "condition": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 8994, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 8992, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8906, + "src": "34174:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": { + "argumentTypes": null, + "id": 8993, + "name": "bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8912, + "src": "34190:4:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "34174:20:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 8995, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "34173:22:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "argumentTypes": null, + "id": 8997, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8906, + "src": "34205:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8998, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "34173:44:18", + "trueExpression": { + "argumentTypes": null, + "id": 8996, + "name": "bond", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8912, + "src": "34198:4:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "34143:74:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 9001, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8902, + "src": "34309:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 9002, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8908, + "src": "34322:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 9005, + "name": "answer_takeover_fee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8991, + "src": "34346:19:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 9003, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8906, + "src": "34329:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9004, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sub", + "nodeType": "MemberAccess", + "referencedDeclaration": 7056, + "src": "34329:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 9006, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "34329:37:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 9000, + "name": "_payPayee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8848, + "src": "34299:9:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (bytes32,address,uint256)" + } + }, + "id": 9007, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "34299:68:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 9008, + "nodeType": "ExpressionStatement", + "src": "34299:68:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 9011, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 9009, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8908, + "src": "34467:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 9010, + "name": "addr", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8910, + "src": "34475:4:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "34467:12:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 9012, + "nodeType": "ExpressionStatement", + "src": "34467:12:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 9015, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 9013, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8906, + "src": "34497:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 9014, + "name": "answer_takeover_fee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8991, + "src": "34512:19:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "34497:34:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9016, + "nodeType": "ExpressionStatement", + "src": "34497:34:18" + } + ] + } + }, + "id": 9019, + "nodeType": "IfStatement", + "src": "33166:1381:18", + "trueBody": { + "id": 8986, + "nodeType": "Block", + "src": "33193:306:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 8967, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 8965, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8908, + "src": "33340:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 8966, + "name": "addr", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8910, + "src": "33348:4:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "33340:12:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 8968, + "nodeType": "ExpressionStatement", + "src": "33340:12:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8977, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 8969, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8906, + "src": "33370:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8972, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "33402:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8974, + "indexExpression": { + "argumentTypes": null, + "id": 8973, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8902, + "src": "33412:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "33402:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8975, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bounty", + "nodeType": "MemberAccess", + "referencedDeclaration": 7257, + "src": "33402:29:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 8970, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8906, + "src": "33385:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8971, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 7080, + "src": "33385:16:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 8976, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "33385:47:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "33370:62:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8978, + "nodeType": "ExpressionStatement", + "src": "33370:62:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 8984, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 8979, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "33450:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 8981, + "indexExpression": { + "argumentTypes": null, + "id": 8980, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8902, + "src": "33460:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "33450:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 8982, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "bounty", + "nodeType": "MemberAccess", + "referencedDeclaration": 7257, + "src": "33450:29:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "30", + "id": 8983, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "33482:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "33450:33:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 8985, + "nodeType": "ExpressionStatement", + "src": "33450:33:18" + } + ] + } + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "id": 9022, + "name": "queued_funds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8906, + "src": "34576:12:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 9023, + "name": "payee", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8908, + "src": "34590:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "id": 9024, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "34575:21:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_address_$", + "typeString": "tuple(uint256,address)" + } + }, + "functionReturnParameters": 8922, + "id": 9025, + "nodeType": "Return", + "src": "34568:28:18" + } + ] + }, + "documentation": null, + "id": 9027, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "_processHistoryItem", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 8917, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8902, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "32231:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8901, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "32231:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8904, + "name": "best_answer", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "32252:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8903, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "32252:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8906, + "name": "queued_funds", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "32282:20:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8905, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "32282:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8908, + "name": "payee", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "32304:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8907, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "32304:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8910, + "name": "addr", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "32328:12:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8909, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "32328:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8912, + "name": "bond", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "32342:12:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8911, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "32342:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8914, + "name": "answer", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "32356:14:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 8913, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "32356:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8916, + "name": "is_commitment", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "32372:18:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 8915, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "32372:4:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "32221:175:18" + }, + "payable": false, + "returnParameters": { + "id": 8922, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8919, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "32419:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 8918, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "32419:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 8921, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9027, + "src": "32428:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 8920, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "32428:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "32418:18:18" + }, + "scope": 9314, + "src": "32193:2411:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 9182, + "nodeType": "Block", + "src": "35829:723:18", + "statements": [ + { + "assignments": [], + "declarations": [ + { + "constant": false, + "id": 9051, + "name": "qi", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "35848:10:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 9050, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "35848:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 9052, + "initialValue": null, + "nodeType": "VariableDeclarationStatement", + "src": "35848:10:18" + }, + { + "assignments": [], + "declarations": [ + { + "constant": false, + "id": 9054, + "name": "i", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "35868:9:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 9053, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "35868:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 9055, + "initialValue": null, + "nodeType": "VariableDeclarationStatement", + "src": "35868:9:18" + }, + { + "body": { + "id": 9177, + "nodeType": "Block", + "src": "35932:594:18", + "statements": [ + { + "assignments": [ + 9068 + ], + "declarations": [ + { + "constant": false, + "id": 9068, + "name": "qid", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "35946:11:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9067, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "35946:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 9072, + "initialValue": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9069, + "name": "question_ids", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9030, + "src": "35960:12:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 9071, + "indexExpression": { + "argumentTypes": null, + "id": 9070, + "name": "qi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9051, + "src": "35973:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "35960:16:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "35946:30:18" + }, + { + "assignments": [ + 9074 + ], + "declarations": [ + { + "constant": false, + "id": 9074, + "name": "ln", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "35990:10:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 9073, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "35990:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 9078, + "initialValue": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9075, + "name": "lengths", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9033, + "src": "36003:7:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 9077, + "indexExpression": { + "argumentTypes": null, + "id": 9076, + "name": "qi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9051, + "src": "36011:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "36003:11:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "35990:24:18" + }, + { + "assignments": [ + 9082 + ], + "declarations": [ + { + "constant": false, + "id": 9082, + "name": "hh", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "36028:19:18", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[]" + }, + "typeName": { + "baseType": { + "id": 9080, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "36028:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 9081, + "length": null, + "nodeType": "ArrayTypeName", + "src": "36028:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 9088, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 9086, + "name": "ln", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9074, + "src": "36064:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 9085, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "NewExpression", + "src": "36050:13:18", + "typeDescriptions": { + "typeIdentifier": "t_function_objectcreation_pure$_t_uint256_$returns$_t_array$_t_bytes32_$dyn_memory_$", + "typeString": "function (uint256) pure returns (bytes32[] memory)" + }, + "typeName": { + "baseType": { + "id": 9083, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "36054:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 9084, + "length": null, + "nodeType": "ArrayTypeName", + "src": "36054:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + } + }, + "id": 9087, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "36050:17:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory", + "typeString": "bytes32[] memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "36028:39:18" + }, + { + "assignments": [ + 9092 + ], + "declarations": [ + { + "constant": false, + "id": 9092, + "name": "ad", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "36081:19:18", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[]" + }, + "typeName": { + "baseType": { + "id": 9090, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "36081:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 9091, + "length": null, + "nodeType": "ArrayTypeName", + "src": "36081:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", + "typeString": "address[]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 9098, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 9096, + "name": "ln", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9074, + "src": "36117:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 9095, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "NewExpression", + "src": "36103:13:18", + "typeDescriptions": { + "typeIdentifier": "t_function_objectcreation_pure$_t_uint256_$returns$_t_array$_t_address_$dyn_memory_$", + "typeString": "function (uint256) pure returns (address[] memory)" + }, + "typeName": { + "baseType": { + "id": 9093, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "36107:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 9094, + "length": null, + "nodeType": "ArrayTypeName", + "src": "36107:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", + "typeString": "address[]" + } + } + }, + "id": 9097, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "36103:17:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory", + "typeString": "address[] memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "36081:39:18" + }, + { + "assignments": [ + 9102 + ], + "declarations": [ + { + "constant": false, + "id": 9102, + "name": "bo", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "36134:19:18", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[]" + }, + "typeName": { + "baseType": { + "id": 9100, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "36134:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9101, + "length": null, + "nodeType": "ArrayTypeName", + "src": "36134:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 9108, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 9106, + "name": "ln", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9074, + "src": "36170:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 9105, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "NewExpression", + "src": "36156:13:18", + "typeDescriptions": { + "typeIdentifier": "t_function_objectcreation_pure$_t_uint256_$returns$_t_array$_t_uint256_$dyn_memory_$", + "typeString": "function (uint256) pure returns (uint256[] memory)" + }, + "typeName": { + "baseType": { + "id": 9103, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "36160:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9104, + "length": null, + "nodeType": "ArrayTypeName", + "src": "36160:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + } + }, + "id": 9107, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "36156:17:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory", + "typeString": "uint256[] memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "36134:39:18" + }, + { + "assignments": [ + 9112 + ], + "declarations": [ + { + "constant": false, + "id": 9112, + "name": "an", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "36187:19:18", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[]" + }, + "typeName": { + "baseType": { + "id": 9110, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "36187:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 9111, + "length": null, + "nodeType": "ArrayTypeName", + "src": "36187:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 9118, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 9116, + "name": "ln", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9074, + "src": "36223:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 9115, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "NewExpression", + "src": "36209:13:18", + "typeDescriptions": { + "typeIdentifier": "t_function_objectcreation_pure$_t_uint256_$returns$_t_array$_t_bytes32_$dyn_memory_$", + "typeString": "function (uint256) pure returns (bytes32[] memory)" + }, + "typeName": { + "baseType": { + "id": 9113, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "36213:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 9114, + "length": null, + "nodeType": "ArrayTypeName", + "src": "36213:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + } + }, + "id": 9117, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "36209:17:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory", + "typeString": "bytes32[] memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "36187:39:18" + }, + { + "assignments": [], + "declarations": [ + { + "constant": false, + "id": 9120, + "name": "j", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "36240:9:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 9119, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "36240:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 9121, + "initialValue": null, + "nodeType": "VariableDeclarationStatement", + "src": "36240:9:18" + }, + { + "body": { + "id": 9167, + "nodeType": "Block", + "src": "36288:180:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 9138, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9132, + "name": "hh", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9082, + "src": "36306:2:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 9134, + "indexExpression": { + "argumentTypes": null, + "id": 9133, + "name": "j", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9120, + "src": "36309:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "36306:5:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9135, + "name": "hist_hashes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9036, + "src": "36314:11:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 9137, + "indexExpression": { + "argumentTypes": null, + "id": 9136, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9054, + "src": "36326:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "36314:14:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "36306:22:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 9139, + "nodeType": "ExpressionStatement", + "src": "36306:22:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 9146, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9140, + "name": "ad", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9092, + "src": "36346:2:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + "id": 9142, + "indexExpression": { + "argumentTypes": null, + "id": 9141, + "name": "j", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9120, + "src": "36349:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "36346:5:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9143, + "name": "addrs", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9039, + "src": "36354:5:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + "id": 9145, + "indexExpression": { + "argumentTypes": null, + "id": 9144, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9054, + "src": "36360:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "36354:8:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "36346:16:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 9147, + "nodeType": "ExpressionStatement", + "src": "36346:16:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 9154, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9148, + "name": "bo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9102, + "src": "36380:2:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 9150, + "indexExpression": { + "argumentTypes": null, + "id": 9149, + "name": "j", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9120, + "src": "36383:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "36380:5:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9151, + "name": "bonds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9042, + "src": "36388:5:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 9153, + "indexExpression": { + "argumentTypes": null, + "id": 9152, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9054, + "src": "36394:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "36388:8:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "36380:16:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9155, + "nodeType": "ExpressionStatement", + "src": "36380:16:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 9162, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9156, + "name": "an", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9112, + "src": "36414:2:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 9158, + "indexExpression": { + "argumentTypes": null, + "id": 9157, + "name": "j", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9120, + "src": "36417:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "36414:5:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9159, + "name": "answers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9045, + "src": "36422:7:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 9161, + "indexExpression": { + "argumentTypes": null, + "id": 9160, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9054, + "src": "36430:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "36422:10:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "36414:18:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 9163, + "nodeType": "ExpressionStatement", + "src": "36414:18:18" + }, + { + "expression": { + "argumentTypes": null, + "id": 9165, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "36450:3:18", + "subExpression": { + "argumentTypes": null, + "id": 9164, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9054, + "src": "36450:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9166, + "nodeType": "ExpressionStatement", + "src": "36450:3:18" + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 9128, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 9126, + "name": "j", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9120, + "src": "36275:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "id": 9127, + "name": "ln", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9074, + "src": "36279:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "36275:6:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 9168, + "initializationExpression": { + "expression": { + "argumentTypes": null, + "id": 9124, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 9122, + "name": "j", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9120, + "src": "36268:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "30", + "id": 9123, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "36272:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "36268:5:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9125, + "nodeType": "ExpressionStatement", + "src": "36268:5:18" + }, + "loopExpression": { + "expression": { + "argumentTypes": null, + "id": 9130, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "36283:3:18", + "subExpression": { + "argumentTypes": null, + "id": 9129, + "name": "j", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9120, + "src": "36283:1:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9131, + "nodeType": "ExpressionStatement", + "src": "36283:3:18" + }, + "nodeType": "ForStatement", + "src": "36263:205:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 9170, + "name": "qid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9068, + "src": "36495:3:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 9171, + "name": "hh", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9082, + "src": "36500:2:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + { + "argumentTypes": null, + "id": 9172, + "name": "ad", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9092, + "src": "36504:2:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + { + "argumentTypes": null, + "id": 9173, + "name": "bo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9102, + "src": "36508:2:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + { + "argumentTypes": null, + "id": 9174, + "name": "an", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9112, + "src": "36512:2:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + }, + { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + }, + { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + }, + { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + ], + "id": 9169, + "name": "claimWinnings", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8821, + "src": "36481:13:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_array$_t_bytes32_$dyn_memory_ptr_$_t_array$_t_address_$dyn_memory_ptr_$_t_array$_t_uint256_$dyn_memory_ptr_$_t_array$_t_bytes32_$dyn_memory_ptr_$returns$__$", + "typeString": "function (bytes32,bytes32[] memory,address[] memory,uint256[] memory,bytes32[] memory)" + } + }, + "id": 9175, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "36481:34:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 9176, + "nodeType": "ExpressionStatement", + "src": "36481:34:18" + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 9063, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 9060, + "name": "qi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9051, + "src": "35900:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 9061, + "name": "question_ids", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9030, + "src": "35905:12:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 9062, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "35905:19:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "35900:24:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 9178, + "initializationExpression": { + "expression": { + "argumentTypes": null, + "id": 9058, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 9056, + "name": "qi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9051, + "src": "35892:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "30", + "id": 9057, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "35897:1:18", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "35892:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9059, + "nodeType": "ExpressionStatement", + "src": "35892:6:18" + }, + "loopExpression": { + "expression": { + "argumentTypes": null, + "id": 9065, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "35926:4:18", + "subExpression": { + "argumentTypes": null, + "id": 9064, + "name": "qi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9051, + "src": "35926:2:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9066, + "nodeType": "ExpressionStatement", + "src": "35926:4:18" + }, + "nodeType": "ForStatement", + "src": "35887:639:18" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 9179, + "name": "withdraw", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 434, + "src": "36535:8:18", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 9180, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "36535:10:18", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 9181, + "nodeType": "ExpressionStatement", + "src": "36535:10:18" + } + ] + }, + "documentation": "@notice Convenience function to assign bounties/bonds for multiple questions in one go, then withdraw all your funds.\n Caller must provide the answer history for each question, in reverse order\n @dev Can be called by anyone to assign bonds/bounties, but funds are only withdrawn for the user making the call.\n @param question_ids The IDs of the questions you want to claim for\n @param lengths The number of history entries you will supply for each question ID\n @param hist_hashes In a single list for all supplied questions, the hash of each history entry.\n @param addrs In a single list for all supplied questions, the address of each answerer or commitment sender\n @param bonds In a single list for all supplied questions, the bond supplied with each answer or commitment\n @param answers In a single list for all supplied questions, each answer supplied, or commitment ID ", + "id": 9183, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [], + "id": 9048, + "modifierName": { + "argumentTypes": null, + "id": 9047, + "name": "stateAny", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7326, + "src": "35741:8:18", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "35741:10:18" + } + ], + "name": "claimMultipleAndWithdrawBalance", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 9046, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9030, + "name": "question_ids", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "35599:22:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[]" + }, + "typeName": { + "baseType": { + "id": 9028, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "35599:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 9029, + "length": null, + "nodeType": "ArrayTypeName", + "src": "35599:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 9033, + "name": "lengths", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "35623:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[]" + }, + "typeName": { + "baseType": { + "id": 9031, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "35623:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9032, + "length": null, + "nodeType": "ArrayTypeName", + "src": "35623:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 9036, + "name": "hist_hashes", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "35651:21:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[]" + }, + "typeName": { + "baseType": { + "id": 9034, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "35651:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 9035, + "length": null, + "nodeType": "ArrayTypeName", + "src": "35651:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 9039, + "name": "addrs", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "35674:15:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[]" + }, + "typeName": { + "baseType": { + "id": 9037, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "35674:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 9038, + "length": null, + "nodeType": "ArrayTypeName", + "src": "35674:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", + "typeString": "address[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 9042, + "name": "bonds", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "35691:15:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[]" + }, + "typeName": { + "baseType": { + "id": 9040, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "35691:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9041, + "length": null, + "nodeType": "ArrayTypeName", + "src": "35691:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 9045, + "name": "answers", + "nodeType": "VariableDeclaration", + "scope": 9183, + "src": "35708:17:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[]" + }, + "typeName": { + "baseType": { + "id": 9043, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "35708:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 9044, + "length": null, + "nodeType": "ArrayTypeName", + "src": "35708:9:18", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "35589:142:18" + }, + "payable": false, + "returnParameters": { + "id": 9049, + "nodeType": "ParameterList", + "parameters": [], + "src": "35829:0:18" + }, + "scope": 9314, + "src": "35549:1003:18", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 9195, + "nodeType": "Block", + "src": "36775:59:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9190, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "36792:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 9192, + "indexExpression": { + "argumentTypes": null, + "id": 9191, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9185, + "src": "36802:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "36792:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 9193, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "content_hash", + "nodeType": "MemberAccess", + "referencedDeclaration": 7245, + "src": "36792:35:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 9189, + "id": 9194, + "nodeType": "Return", + "src": "36785:42:18" + } + ] + }, + "documentation": "@notice Returns the questions's content hash, identifying the question content\n @param question_id The ID of the question ", + "id": 9196, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getContentHash", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 9186, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9185, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 9196, + "src": "36720:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9184, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "36720:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "36719:21:18" + }, + "payable": false, + "returnParameters": { + "id": 9189, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9188, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9196, + "src": "36766:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9187, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "36766:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "36765:9:18" + }, + "scope": 9314, + "src": "36696:138:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 9208, + "nodeType": "Block", + "src": "37033:57:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9203, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "37050:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 9205, + "indexExpression": { + "argumentTypes": null, + "id": 9204, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9198, + "src": "37060:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "37050:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 9206, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "arbitrator", + "nodeType": "MemberAccess", + "referencedDeclaration": 7247, + "src": "37050:33:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "functionReturnParameters": 9202, + "id": 9207, + "nodeType": "Return", + "src": "37043:40:18" + } + ] + }, + "documentation": "@notice Returns the arbitrator address for the question\n @param question_id The ID of the question ", + "id": 9209, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getArbitrator", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 9199, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9198, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 9209, + "src": "36978:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9197, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "36978:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "36977:21:18" + }, + "payable": false, + "returnParameters": { + "id": 9202, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9201, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9209, + "src": "37024:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 9200, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "37024:7:18", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "37023:9:18" + }, + "scope": 9314, + "src": "36955:135:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 9221, + "nodeType": "Block", + "src": "37301:57:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9216, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "37318:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 9218, + "indexExpression": { + "argumentTypes": null, + "id": 9217, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9211, + "src": "37328:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "37318:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 9219, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "opening_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7249, + "src": "37318:33:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "functionReturnParameters": 9215, + "id": 9220, + "nodeType": "Return", + "src": "37311:40:18" + } + ] + }, + "documentation": "@notice Returns the timestamp when the question can first be answered\n @param question_id The ID of the question ", + "id": 9222, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getOpeningTS", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 9212, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9211, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 9222, + "src": "37247:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9210, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "37247:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "37246:21:18" + }, + "payable": false, + "returnParameters": { + "id": 9215, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9214, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9222, + "src": "37293:6:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 9213, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "37293:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "37292:8:18" + }, + "scope": 9314, + "src": "37225:133:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 9234, + "nodeType": "Block", + "src": "37559:54:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9229, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "37576:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 9231, + "indexExpression": { + "argumentTypes": null, + "id": 9230, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9224, + "src": "37586:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "37576:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 9232, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timeout", + "nodeType": "MemberAccess", + "referencedDeclaration": 7251, + "src": "37576:30:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "functionReturnParameters": 9228, + "id": 9233, + "nodeType": "Return", + "src": "37569:37:18" + } + ] + }, + "documentation": "@notice Returns the timeout in seconds used after each answer\n @param question_id The ID of the question ", + "id": 9235, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getTimeout", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 9225, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9224, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 9235, + "src": "37505:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9223, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "37505:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "37504:21:18" + }, + "payable": false, + "returnParameters": { + "id": 9228, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9227, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9235, + "src": "37551:6:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 9226, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "37551:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "37550:8:18" + }, + "scope": 9314, + "src": "37485:128:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 9247, + "nodeType": "Block", + "src": "37829:58:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9242, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "37846:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 9244, + "indexExpression": { + "argumentTypes": null, + "id": 9243, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9237, + "src": "37856:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "37846:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 9245, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "finalize_ts", + "nodeType": "MemberAccess", + "referencedDeclaration": 7253, + "src": "37846:34:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "functionReturnParameters": 9241, + "id": 9246, + "nodeType": "Return", + "src": "37839:41:18" + } + ] + }, + "documentation": "@notice Returns the timestamp at which the question will be/was finalized\n @param question_id The ID of the question ", + "id": 9248, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getFinalizeTS", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 9238, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9237, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 9248, + "src": "37775:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9236, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "37775:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "37774:21:18" + }, + "payable": false, + "returnParameters": { + "id": 9241, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9240, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9248, + "src": "37821:6:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 9239, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "37821:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "37820:8:18" + }, + "scope": 9314, + "src": "37752:135:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 9260, + "nodeType": "Block", + "src": "38094:69:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9255, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "38111:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 9257, + "indexExpression": { + "argumentTypes": null, + "id": 9256, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9250, + "src": "38121:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "38111:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 9258, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "is_pending_arbitration", + "nodeType": "MemberAccess", + "referencedDeclaration": 7255, + "src": "38111:45:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "functionReturnParameters": 9254, + "id": 9259, + "nodeType": "Return", + "src": "38104:52:18" + } + ] + }, + "documentation": "@notice Returns whether the question is pending arbitration\n @param question_id The ID of the question ", + "id": 9261, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "isPendingArbitration", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 9251, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9250, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 9261, + "src": "38042:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9249, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "38042:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "38041:21:18" + }, + "payable": false, + "returnParameters": { + "id": 9254, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9253, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9261, + "src": "38088:4:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 9252, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "38088:4:18", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "38087:6:18" + }, + "scope": 9314, + "src": "38012:151:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 9273, + "nodeType": "Block", + "src": "38416:53:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9268, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "38433:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 9270, + "indexExpression": { + "argumentTypes": null, + "id": 9269, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9263, + "src": "38443:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "38433:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 9271, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bounty", + "nodeType": "MemberAccess", + "referencedDeclaration": 7257, + "src": "38433:29:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 9267, + "id": 9272, + "nodeType": "Return", + "src": "38426:36:18" + } + ] + }, + "documentation": "@notice Returns the current total unclaimed bounty\n @dev Set back to zero once the bounty has been claimed\n @param question_id The ID of the question ", + "id": 9274, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getBounty", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 9264, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9263, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 9274, + "src": "38361:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9262, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "38361:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "38360:21:18" + }, + "payable": false, + "returnParameters": { + "id": 9267, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9266, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9274, + "src": "38407:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 9265, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "38407:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "38406:9:18" + }, + "scope": 9314, + "src": "38342:127:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 9286, + "nodeType": "Block", + "src": "38652:58:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9281, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "38669:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 9283, + "indexExpression": { + "argumentTypes": null, + "id": 9282, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9276, + "src": "38679:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "38669:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 9284, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "best_answer", + "nodeType": "MemberAccess", + "referencedDeclaration": 7259, + "src": "38669:34:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 9280, + "id": 9285, + "nodeType": "Return", + "src": "38662:41:18" + } + ] + }, + "documentation": "@notice Returns the current best answer\n @param question_id The ID of the question ", + "id": 9287, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getBestAnswer", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 9277, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9276, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 9287, + "src": "38597:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9275, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "38597:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "38596:21:18" + }, + "payable": false, + "returnParameters": { + "id": 9280, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9279, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9287, + "src": "38643:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9278, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "38643:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "38642:9:18" + }, + "scope": 9314, + "src": "38574:136:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 9299, + "nodeType": "Block", + "src": "38973:59:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9294, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "38990:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 9296, + "indexExpression": { + "argumentTypes": null, + "id": 9295, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9289, + "src": "39000:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "38990:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 9297, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "history_hash", + "nodeType": "MemberAccess", + "referencedDeclaration": 7261, + "src": "38990:35:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 9293, + "id": 9298, + "nodeType": "Return", + "src": "38983:42:18" + } + ] + }, + "documentation": "@notice Returns the history hash of the question \n @param question_id The ID of the question \n @dev Updated on each answer, then rewound as each is claimed", + "id": 9300, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getHistoryHash", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 9290, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9289, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 9300, + "src": "38918:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9288, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "38918:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "38917:21:18" + }, + "payable": false, + "returnParameters": { + "id": 9293, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9292, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9300, + "src": "38964:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9291, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "38964:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "38963:9:18" + }, + "scope": 9314, + "src": "38894:138:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 9312, + "nodeType": "Block", + "src": "39231:51:18", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 9307, + "name": "questions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7293, + "src": "39248:9:18", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_Question_$7264_storage_$", + "typeString": "mapping(bytes32 => struct Realitio_v2_1.Question storage ref)" + } + }, + "id": 9309, + "indexExpression": { + "argumentTypes": null, + "id": 9308, + "name": "question_id", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9302, + "src": "39258:11:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "39248:22:18", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Question_$7264_storage", + "typeString": "struct Realitio_v2_1.Question storage ref" + } + }, + "id": 9310, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "bond", + "nodeType": "MemberAccess", + "referencedDeclaration": 7263, + "src": "39248:27:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 9306, + "id": 9311, + "nodeType": "Return", + "src": "39241:34:18" + } + ] + }, + "documentation": "@notice Returns the highest bond posted so far for a question\n @param question_id The ID of the question ", + "id": 9313, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getBond", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 9303, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9302, + "name": "question_id", + "nodeType": "VariableDeclaration", + "scope": 9313, + "src": "39176:19:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 9301, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "39176:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "39175:21:18" + }, + "payable": false, + "returnParameters": { + "id": 9306, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9305, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 9313, + "src": "39222:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 9304, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "39222:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "39221:9:18" + }, + "scope": 9314, + "src": "39159:123:18", + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 9315, + "src": "306:38979:18" + } + ], + "src": "0:39286:18" + }, + "compiler": { + "name": "solc", + "version": "0.4.25+commit.59dbf8f1.Emscripten.clang", + "optimizer": true, + "runs": 200 + }, + "networks": {}, + "schemaVersion": "2.3.3", + "updatedAt": "2021-01-13T02:29:13.230Z" +} diff --git a/lib/assets/contracts/Realitio_v2_1_ArbitratorWithAppeals.json b/lib/assets/contracts/Realitio_v2_1_ArbitratorWithAppeals.json new file mode 100644 index 0000000..ac595ed --- /dev/null +++ b/lib/assets/contracts/Realitio_v2_1_ArbitratorWithAppeals.json @@ -0,0 +1,16090 @@ +{ + "contractName": "Realitio_v2_1_ArbitratorWithAppeals", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_realitio", + "type": "address" + }, + { + "internalType": "string", + "name": "_metadata", + "type": "string" + }, + { + "internalType": "contract IArbitrator", + "name": "_arbitrator", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_arbitratorExtraData", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_localDisputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_round", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ruling", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Contribution", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IArbitrator", + "name": "_arbitrator", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_metaEvidenceID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_evidenceGroupID", + "type": "uint256" + } + ], + "name": "Dispute", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "_questionID", + "type": "bytes32" + } + ], + "name": "DisputeIDToQuestionID", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IArbitrator", + "name": "_arbitrator", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_evidenceGroupID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_party", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "_evidence", + "type": "string" + } + ], + "name": "Evidence", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_metaEvidenceID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "_evidence", + "type": "string" + } + ], + "name": "MetaEvidence", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IArbitrator", + "name": "_arbitrator", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + } + ], + "name": "Ruling", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_localDisputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_round", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + } + ], + "name": "RulingFunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_localDisputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_round", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_reward", + "type": "uint256" + } + ], + "name": "Withdrawal", + "type": "event" + }, + { + "inputs": [], + "name": "MULTIPLIER_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VERSION", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "arbitrationRequests", + "outputs": [ + { + "internalType": "enum RealitioArbitratorWithAppealsBase.Status", + "name": "status", + "type": "uint8" + }, + { + "internalType": "address", + "name": "disputer", + "type": "address" + }, + { + "internalType": "uint256", + "name": "disputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "answer", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "arbitrator", + "outputs": [ + { + "internalType": "contract IArbitrator", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "arbitratorExtraData", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_governor", + "type": "address" + } + ], + "name": "changeGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_metaEvidence", + "type": "string" + } + ], + "name": "changeMetaEvidence", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_winnerStakeMultiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_loserStakeMultiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_loserAppealPeriodMultiplier", + "type": "uint256" + } + ], + "name": "changeMultipliers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "externalIDtoLocalID", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_questionID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + } + ], + "name": "fundAppeal", + "outputs": [ + { + "internalType": "bool", + "name": "fullyFunded", + "type": "bool" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "getDisputeFee", + "outputs": [ + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMultipliers", + "outputs": [ + { + "internalType": "uint256", + "name": "_winnerStakeMultiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_loserStakeMultiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_loserAppealPeriodMultiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_denominator", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_questionID", + "type": "uint256" + }, + { + "internalType": "address payable", + "name": "_contributor", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "_contributedTo", + "type": "uint256[]" + } + ], + "name": "getTotalWithdrawableAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "sum", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "loserAppealPeriodMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "loserStakeMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "metaEvidenceUpdates", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "metadata", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "numberOfRulingOptions", + "outputs": [ + { + "internalType": "uint256", + "name": "count", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "realitio", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_questionID", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_maxPrevious", + "type": "uint256" + } + ], + "name": "requestArbitration", + "outputs": [ + { + "internalType": "uint256", + "name": "disputeID", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + } + ], + "name": "rule", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_questionID", + "type": "uint256" + }, + { + "internalType": "string", + "name": "_evidenceURI", + "type": "string" + } + ], + "name": "submitEvidence", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "winnerStakeMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_questionID", + "type": "uint256" + }, + { + "internalType": "address payable", + "name": "_contributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_roundNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + } + ], + "name": "withdrawFeesAndRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_questionID", + "type": "uint256" + }, + { + "internalType": "address payable", + "name": "_contributor", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "_contributedTo", + "type": "uint256[]" + } + ], + "name": "withdrawFeesAndRewardsForAllRounds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_questionID", + "type": "uint256" + }, + { + "internalType": "address payable", + "name": "_contributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_roundNumber", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "_contributedTo", + "type": "uint256[]" + } + ], + "name": "withdrawFeesAndRewardsForMultipleRulings", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_questionID", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "_lastHistoryHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "_lastAnswerOrCommitmentID", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_lastAnswerer", + "type": "address" + } + ], + "name": "reportAnswer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_realitio\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_metadata\",\"type\":\"string\"},{\"internalType\":\"contract IArbitrator\",\"name\":\"_arbitrator\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_arbitratorExtraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_localDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_round\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"ruling\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Contribution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IArbitrator\",\"name\":\"_arbitrator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_metaEvidenceID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_evidenceGroupID\",\"type\":\"uint256\"}],\"name\":\"Dispute\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_questionID\",\"type\":\"bytes32\"}],\"name\":\"DisputeIDToQuestionID\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IArbitrator\",\"name\":\"_arbitrator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_evidenceGroupID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_party\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_evidence\",\"type\":\"string\"}],\"name\":\"Evidence\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_metaEvidenceID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_evidence\",\"type\":\"string\"}],\"name\":\"MetaEvidence\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IArbitrator\",\"name\":\"_arbitrator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_ruling\",\"type\":\"uint256\"}],\"name\":\"Ruling\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_localDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_round\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_ruling\",\"type\":\"uint256\"}],\"name\":\"RulingFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_localDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_round\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_ruling\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_reward\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MULTIPLIER_DENOMINATOR\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"arbitrationRequests\",\"outputs\":[{\"internalType\":\"enum RealitioArbitratorWithAppealsBase.Status\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"disputer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"disputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"answer\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"arbitrator\",\"outputs\":[{\"internalType\":\"contract IArbitrator\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"arbitratorExtraData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"}],\"name\":\"changeGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_metaEvidence\",\"type\":\"string\"}],\"name\":\"changeMetaEvidence\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_winnerStakeMultiplier\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_loserStakeMultiplier\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_loserAppealPeriodMultiplier\",\"type\":\"uint256\"}],\"name\":\"changeMultipliers\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"externalIDtoLocalID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_questionID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_ruling\",\"type\":\"uint256\"}],\"name\":\"fundAppeal\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"fullyFunded\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"getDisputeFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMultipliers\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_winnerStakeMultiplier\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_loserStakeMultiplier\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_loserAppealPeriodMultiplier\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_denominator\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_questionID\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"_contributor\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"_contributedTo\",\"type\":\"uint256[]\"}],\"name\":\"getTotalWithdrawableAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"sum\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"loserAppealPeriodMultiplier\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"loserStakeMultiplier\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"metaEvidenceUpdates\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"metadata\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"numberOfRulingOptions\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"realitio\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_questionID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_lastHistoryHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_lastAnswerOrCommitmentID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_lastAnswerer\",\"type\":\"address\"}],\"name\":\"reportAnswer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_questionID\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_maxPrevious\",\"type\":\"uint256\"}],\"name\":\"requestArbitration\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"disputeID\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_ruling\",\"type\":\"uint256\"}],\"name\":\"rule\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_questionID\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_evidenceURI\",\"type\":\"string\"}],\"name\":\"submitEvidence\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"winnerStakeMultiplier\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_questionID\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"_contributor\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_roundNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_ruling\",\"type\":\"uint256\"}],\"name\":\"withdrawFeesAndRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_questionID\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"_contributor\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"_contributedTo\",\"type\":\"uint256[]\"}],\"name\":\"withdrawFeesAndRewardsForAllRounds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_questionID\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"_contributor\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_roundNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_contributedTo\",\"type\":\"uint256[]\"}],\"name\":\"withdrawFeesAndRewardsForMultipleRulings\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"A Realitio arbitrator implementation that uses Realitio v2.1 and Kleros. It notifies Realitio contract for arbitration requests and creates corresponding dispute on Kleros. Transmits Kleros ruling to Realitio contract. Maintains crowdfunded appeals and notifies Kleros contract. Provides a function to submit evidence for Kleros dispute. There is a conversion between Kleros ruling and Realitio answer and there is a need for shifting by 1. This is because ruling 0 in Kleros signals tie or no-ruling but in Realitio 0 is a valid answer. For reviewers this should be a focus as it's quite easy to get confused. Any mistakes on this conversion will render this contract useless. NOTE: This contract trusts the Kleros arbitrator and Realitio.\",\"kind\":\"dev\",\"methods\":{\"changeGovernor(address)\":{\"params\":{\"_governor\":\"The address of the new governor.\"}},\"changeMetaEvidence(string)\":{\"details\":\"Updates the meta evidence used for disputes. This function needs to be executed at least once before requesting arbitration, because we don't emit MetaEvidence during construction.\",\"params\":{\"_metaEvidence\":\"URI to the new meta evidence file.\"}},\"changeMultipliers(uint256,uint256,uint256)\":{\"details\":\"Changes the proportion of appeal fees that must be paid by winner and loser and changes the appeal period portion for losers.\",\"params\":{\"_loserAppealPeriodMultiplier\":\"The new loser appeal period multiplier respect to DENOMINATOR.\",\"_loserStakeMultiplier\":\"The new loser stake multiplier value respect to DENOMINATOR.\",\"_winnerStakeMultiplier\":\"The new winner stake multiplier value respect to DENOMINATOR.\"}},\"constructor\":{\"details\":\"Constructor.\",\"params\":{\"_arbitrator\":\"The address of the ERC792 arbitrator.\",\"_arbitratorExtraData\":\"The extra data used to raise a dispute in the ERC792 arbitrator.\",\"_metadata\":\"The metadata required for RealitioArbitrator.\",\"_realitio\":\"The address of the Realitio contract.\"}},\"fundAppeal(uint256,uint256)\":{\"details\":\"TRUSTED. Manages crowdfunded appeals contributions and calls appeal function of the Kleros arbitrator to appeal a dispute. Note that we don\\u2019t need to check that msg.value is enough to pay arbitration fees as it\\u2019s the responsibility of the arbitrator contract.\",\"params\":{\"_questionID\":\"Identifier of the Realitio question, casted to uint. This also serves as the local identifier in this contract.\",\"_ruling\":\"The ruling option to which the caller wants to contribute to.\"},\"returns\":{\"fullyFunded\":\"True if the ruling option got fully funded as a result of this contribution.\"}},\"getDisputeFee(bytes32)\":{\"details\":\"Returns arbitration fee by calling arbitrationCost function in the arbitrator contract.\",\"returns\":{\"fee\":\"Arbitration that needs to be paid.\"}},\"getMultipliers()\":{\"details\":\"Calculate history has for givenReturns multipliers for appeals.\",\"returns\":{\"_denominator\":\"Multiplier denominator in basis points. Required for achieving floating-point-like behavior.\",\"_loserAppealPeriodMultiplier\":\"Losers appeal period multiplier. The loser is given less time to fund its appeal to defend against last minute appeal funding attacks.\",\"_loserStakeMultiplier\":\"Losers stake multiplier.\",\"_winnerStakeMultiplier\":\"Winners stake multiplier.\"}},\"getTotalWithdrawableAmount(uint256,address,uint256[])\":{\"details\":\"Returns the sum of withdrawable amount.\",\"params\":{\"_contributedTo\":\"Ruling options to look for potential withdrawals.\",\"_contributor\":\"The contributor for which to query.\",\"_questionID\":\"Identifier of the Realitio question, casted to uint. This also serves as the local identifier in this contract.\"},\"returns\":{\"sum\":\"The total amount available to withdraw.\"}},\"numberOfRulingOptions(uint256)\":{\"details\":\"Returns number of possible ruling options. Valid rulings are [0, count].\",\"returns\":{\"count\":\"The number of ruling options.\"}},\"reportAnswer(bytes32,bytes32,bytes32,address)\":{\"details\":\"Reports the answer to a specified question from the Kleros arbitrator to the Realitio v2.1 contract. This can be called by anyone, after the dispute gets a ruling from Kleros. We can't directly call `assignWinnerAndSubmitAnswerByArbitrator` inside `rule` because of extra parameters (e.g. _lastHistoryHash).\",\"params\":{\"_lastAnswerOrCommitmentID\":\"The last answer given, or its commitment ID if it was a commitment, to the question in the Realitio contract, in bytes32.\",\"_lastAnswerer\":\"The last answerer to the question in the Realitio contract.\",\"_lastHistoryHash\":\"The history hash given with the last answer to the question in the Realitio contract.\",\"_questionID\":\"The ID of Realitio question.\"}},\"requestArbitration(bytes32,uint256)\":{\"details\":\"Request arbitration from Kleros for given _questionID.\",\"params\":{\"_maxPrevious\":\"If specified, reverts if a bond higher than this was submitted after you sent your transaction.\",\"_questionID\":\"The question identifier in Realitio contract.\"},\"returns\":{\"disputeID\":\"ID of the resulting dispute on arbitrator.\"}},\"rule(uint256,uint256)\":{\"details\":\"Receives ruling from Kleros and enforces it.\",\"params\":{\"_disputeID\":\"ID of Kleros dispute.\",\"_ruling\":\"Ruling that is given by Kleros. This needs to be converted to Realitio answer before reporting the answer by shifting by 1.\"}},\"submitEvidence(uint256,string)\":{\"details\":\"Allows to submit evidence for a given dispute.\",\"params\":{\"_evidenceURI\":\"Link to evidence.\",\"_questionID\":\"Realitio question identifier.\"}},\"withdrawFeesAndRewards(uint256,address,uint256,uint256)\":{\"details\":\"Allows to withdraw any reimbursable fees or rewards after the dispute gets solved.\",\"params\":{\"_contributor\":\"The address whose rewards to withdraw.\",\"_questionID\":\"Identifier of the Realitio question, casted to uint. This also serves as the local identifier in this contract.\",\"_roundNumber\":\"The number of the round caller wants to withdraw from.\",\"_ruling\":\"Ruling that received contribution from contributor.\"},\"returns\":{\"amount\":\"The amount available to withdraw for given question, contributor, round number and ruling option.\"}},\"withdrawFeesAndRewardsForAllRounds(uint256,address,uint256[])\":{\"details\":\"Allows to withdraw any rewards or reimbursable fees after the dispute gets resolved. For multiple rulings options and for all rounds at once. This function has O(m*n) time complexity where m is number of rounds and n is the number of ruling options contributed by given user. It is safe to assume m is always less than 10 as appeal cost growth order is O(m^2).\",\"params\":{\"_contributedTo\":\"Rulings that received contributions from contributor.\",\"_contributor\":\"The address whose rewards to withdraw.\",\"_questionID\":\"Identifier of the Realitio question, casted to uint. This also serves as the local identifier in this contract.\"}},\"withdrawFeesAndRewardsForMultipleRulings(uint256,address,uint256,uint256[])\":{\"details\":\"Allows to withdraw any reimbursable fees or rewards after the dispute gets solved. For multiple ruling options at once. This function has O(n) time complexity where n is number of ruling options contributed by given user. It is safe to assume n is always less than 3 as it does not make sense to contribute to different ruling options in the same round, so it will rarely be greater than 1.\",\"params\":{\"_contributedTo\":\"Rulings that received contributions from contributor.\",\"_contributor\":\"The address whose rewards to withdraw.\",\"_questionID\":\"Identifier of the Realitio question, casted to uint. This also serves as the local identifier in this contract.\",\"_roundNumber\":\"The number of the round caller wants to withdraw from.\"}}},\"title\":\"Realitio_v2_1_ArbitratorWithAppeals\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"changeGovernor(address)\":{\"notice\":\"Changes the address of the governor.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"/home/f/repos/realitio-arbitrator-with-appeals/contracts/v2.1/Realitio_v2_1_ArbitratorWithAppeals.sol\":\"Realitio_v2_1_ArbitratorWithAppeals\"},\"evmVersion\":\"byzantium\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":20000},\"remappings\":[]},\"sources\":{\"/home/f/repos/realitio-arbitrator-with-appeals/contracts/IRealitioArbitrator.sol\":{\"keccak256\":\"0xa4c66788bf829c90495b4be7599db0895e92f6125eaf2ec174bdacd43b62efcc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://77f76fafc7edc6f27adb2caccc4479adf6c1b9f8552b27c6a0366f8a10aefc45\",\"dweb:/ipfs/Qmakhn3QDjAqowbvv5npamKZgsbXyjMqrMMz3o5XbjwT2c\"]},\"/home/f/repos/realitio-arbitrator-with-appeals/contracts/IRealitioBase.sol\":{\"keccak256\":\"0xb7542a31c27cacf12cc09d9f673c966351a6a86add13bf072cfa12df1088aee1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3649f211560577fb0d512ab0f310ff259833a3b7364b19bcf72edfa4349805a8\",\"dweb:/ipfs/QmfN5SuzviRSYzKYoF52mxCauAGXx6aLsgDjhEosrGgenN\"]},\"/home/f/repos/realitio-arbitrator-with-appeals/contracts/RealitioArbitratorWithAppealsBase.sol\":{\"keccak256\":\"0xecefcdad0288d210a815b68cf93cde0c9889e8331ca6c1ab7942cfb791b01b8e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c223f17b69dba6080d77bb051131184f109a45f90e2ef1bad1684143eb1eb6a1\",\"dweb:/ipfs/QmTSpJEBKHdoKz3VZTFxBCFqGEuZ9LfZqf2jcYv5Qdyqj1\"]},\"/home/f/repos/realitio-arbitrator-with-appeals/contracts/v2.1/IRealitio_v2_1.sol\":{\"keccak256\":\"0x09d8b829c969256d61d6c9fcb63e1b58688d94d2742a9c23f4cd3698cf3d5313\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a6ace4fabe7cc78a3dee954f30b3147b949ac8a41670d432a86f3bea47eb5d4d\",\"dweb:/ipfs/QmR18P9ALA7U3DQjLSiuBieEhHkqwCwzC2pz5W2BhP9zMS\"]},\"/home/f/repos/realitio-arbitrator-with-appeals/contracts/v2.1/Realitio_v2_1_ArbitratorWithAppeals.sol\":{\"keccak256\":\"0x4cbd733dacc1123b49905cada728aabfc5dc032ead027f0cbcfddd201fea7fb7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://41beec7b7431ddbc610d1baa45fc2301aa47fcaf28dcbcaa2c5d7a8b7bdcd754\",\"dweb:/ipfs/QmcteynyxCWR1dAv5dVfDcBrCKC9S8mpFDiAVCCKQQmdt4\"]},\"@kleros/dispute-resolver-interface-contract/contracts/solc-0.7.x/IDisputeResolver.sol\":{\"keccak256\":\"0x90f7f1dfbda574ee567c7ec1c8a1542a9bc01d661f5bd7569548e301278d3be7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f65ca97d793bd8937580cd311d3dc166629ae6865c68d717169565f905c8a704\",\"dweb:/ipfs/QmUetVP9AuNbMi29UX4tgL7B9ZwKeLcUiYqWffwHizNACe\"]},\"@kleros/erc-792/contracts/IArbitrable.sol\":{\"keccak256\":\"0x1803a3433a78c509b20bd9477a2c60a71b2ce1ee7e17eb0ef0601618a8a72526\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a72a4b4b7048818eb14e698b7b493cb0e44456f91237b1a9a9251669b1de6484\",\"dweb:/ipfs/QmQLXrMT9S5uMe5WHFcf1G1s1GGZGCtNgXcQQGxwukQkXB\"]},\"@kleros/erc-792/contracts/IArbitrator.sol\":{\"keccak256\":\"0x240a4142f9ec379da0333dfc82409b7b058cff9ea118368eb5e8f15447996c1e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6a3a6d3631ce0ca5ef1266f1dc7cd6adb842c875fb6a45385a5adfad65f48c67\",\"dweb:/ipfs/QmZi9SpTkcVnUvwmwRdDin3KFALskAQCYWYAsh9AFzmi86\"]},\"@kleros/erc-792/contracts/erc-1497/IEvidence.sol\":{\"keccak256\":\"0x1ccedf5213730632540c748486637d7b1977ee73375818bf498a8276ca49dd13\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d58a60e8a3cdfe8515aa67a009cc139aab20d10fe0adc6058cc963b26c2e34a4\",\"dweb:/ipfs/QmUJY5dhS4KpXbLYhTBqMi33fNCUjFG19aLzxcDyeeBFkv\"]},\"@kleros/ethereum-libraries/contracts/CappedMath.sol\":{\"keccak256\":\"0x17dc8ae95582317df81532d06545576f0c509e462299ce71ddddd65ea506a5aa\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3a4f55c759e62bb02a4b9ff69c7e24844fdf9186730633d09af32ec70ebe64eb\",\"dweb:/ipfs/QmXcxEcHyk3ffHCAi7fwPu3Q1JEP5PpCricznM6TRkGoNw\"]}},\"version\":1}", + "bytecode": "0x60c060405260018054600160a060020a03191633179055610bb8600455611b586005556113886006553480156200003557600080fd5b5060405162002b5e38038062002b5e83398101604081905262000058916200020c565b6c01000000000000000000000000600160a060020a038516026080528251849084908490849062000091906002906020860190620000d2565b506c01000000000000000000000000600160a060020a0383160260a0528051620000c3906000906020840190620000d2565b505050505050505050620002e2565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200010a576000855562000155565b82601f106200012557805160ff191683800117855562000155565b8280016001018555821562000155579182015b828111156200015557825182559160200191906001019062000138565b506200016392915062000167565b5090565b5b8082111562000163576000815560010162000168565b60006001604060020a03808411156200019357fe5b6040516020601f8601601f1916820181018381118382101715620001b357fe5b8060405250819350858252868686011115620001ce57600080fd5b600092505b85831015620001f0578483015182840182015291820191620001d3565b85831115620002025760008187840101525b5050509392505050565b6000806000806080858703121562000222578384fd5b84516200022f81620002c9565b60208601519094506001604060020a03808211156200024c578485fd5b818701915087601f83011262000260578485fd5b62000271888351602085016200017e565b9450604087015191506200028582620002c9565b6060870151919350808211156200029a578283fd5b508501601f81018713620002ac578182fd5b620002bd878251602084016200017e565b91505092959194509250565b600160a060020a0381168114620002df57600080fd5b50565b6080516c01000000000000000000000000900460a0516c0100000000000000000000000090046127fc620003626000398061065d5280610b5b5280610e605280610f5b52806110cf52806111c5528061130c52806113d152806114825280611b4b5280611d1d5250806115e95280611685528061181a52506127fc6000f3fe6080604052600436106101d4576000357c0100000000000000000000000000000000000000000000000000000000900480637b94338311610109578063bc8802a2116100a7578063e32511da11610081578063e32511da146104b0578063e4c0aaf4146104d0578063fe6ca782146104f0578063ffa1ad7414610505576101d4565b8063bc8802a21461045b578063c21ae06114610470578063c25516e914610490576101d4565b806390765279116100e357806390765279146103e8578063a22352e214610408578063a6a7f0eb14610428578063a829c3d114610448576101d4565b80637b9433831461039357806385632b12146103a85780638d8b2d7e146103c8576101d4565b8063392f37e911610176578063631eabd511610150578063631eabd5146103145780636cc6cde1146103445780636cdc090f1461035957806379873f8a1461036e576101d4565b8063392f37e9146102bf5780634658eb01146102d45780634b2f0ea0146102f4576101d4565b80630e274e4c116101b25780630e274e4c146102485780631d5120851461026a578063311a6c561461027f578063362c34791461029f576101d4565b80630c139eb4146101d95780630c340a24146102045780630c7ac7b614610226575b600080fd5b3480156101e557600080fd5b506101ee61051a565b6040516101fb91906122ed565b60405180910390f35b34801561021057600080fd5b50610219610520565b6040516101fb91906122c1565b34801561023257600080fd5b5061023b61053c565b6040516101fb9190612363565b34801561025457600080fd5b5061026861026336600461202b565b6105e8565b005b34801561027657600080fd5b506101ee610622565b34801561028b57600080fd5b5061026861029a366004611fb2565b610628565b3480156102ab57600080fd5b506101ee6102ba3660046120e3565b61084f565b3480156102cb57600080fd5b5061023b61098e565b3480156102e057600080fd5b506102686102ef36600461218c565b610a04565b610307610302366004611fb2565b610a63565b6040516101fb91906122e2565b34801561032057600080fd5b5061033461032f366004611f5a565b610f18565b6040516101fb9493929190612389565b34801561035057600080fd5b50610219610f59565b34801561036557600080fd5b506101ee610f7d565b34801561037a57600080fd5b50610383610f83565b6040516101fb949392919061277a565b34801561039f57600080fd5b506101ee610f95565b3480156103b457600080fd5b506102686103c3366004612082565b610f9b565b3480156103d457600080fd5b506101ee6103e3366004611f5a565b610fd0565b3480156103f457600080fd5b50610268610403366004611fd3565b610ff5565b34801561041457600080fd5b506101ee610423366004611f5a565b61108f565b34801561043457600080fd5b5061026861044336600461211f565b611154565b6101ee610456366004611fb2565b611239565b34801561046757600080fd5b50610219611683565b34801561047c57600080fd5b506101ee61048b366004611f5a565b6116a7565b34801561049c57600080fd5b506101ee6104ab36600461202b565b6116b9565b3480156104bc57600080fd5b506102686104cb366004611f72565b61176c565b3480156104dc57600080fd5b506102686104eb366004611f3e565b6118d3565b3480156104fc57600080fd5b506101ee61196b565b34801561051157600080fd5b5061023b611971565b60065481565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815292918301828280156105e05780601f106105b5576101008083540402835291602001916105e0565b820191906000526020600020905b8154815290600101906020018083116105c357829003601f168201915b505050505081565b6000838152600760205260408120600381015490915b8181101561061a5761061286868387610f9b565b6001016105fe565b505050505050565b60055481565b60008281526008602090815260408083205480845260079092529091203373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612473565b60405180910390fd5b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe831115610717576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b4906124e1565b6001815460ff16600381111561072957fe5b14610760576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b49061271c565b600381018054600091907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061079657fe5b90600052602060002090600502019050600081600401805490506001146107bd57846107d9565b816004016000815481106107cd57fe5b90600052602060002001545b600284810182905584547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016178455604051909150869033907f394027a5fa6e098a1191094d1719d6929b9abc535fcc0c8f448d6a4e756222769061083f9085906122ed565b60405180910390a3505050505050565b60008481526007602052604081206003810180548391908690811061087057fe5b6000918252602090912060059091020190506001825460ff16600381111561089457fe5b116108cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b4906125bd565b6108db81878685600201546119aa565b925082156109845773ffffffffffffffffffffffffffffffffffffffff8616600081815260028301602090815260408083208884529091528082208290555185156108fc0291869190818181858888f19350505050508573ffffffffffffffffffffffffffffffffffffffff1685887f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae878760405161097b92919061276c565b60405180910390a45b5050949350505050565b600280546040805160206001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01909316849004601f810184900484028201840190925281815292918301828280156105e05780601f106105b5576101008083540402835291602001916105e0565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a55576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b49061254f565b600492909255600555600655565b60007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe821115610abf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612586565b600083815260076020526040902060018082015490825460ff166003811115610ae457fe5b14610b1b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b4906125f4565b6040517f1c3db16d00000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690631c3db16d90610b909085906004016122ed565b60206040518083038186803b158015610ba857600080fd5b505afa158015610bbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be09190612013565b9050610bed828683611b46565b600080610bfb848885611cc2565b6003870180549294509092507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201916000919083908110610c3957fe5b600091825260208083208c84526001600590930201918201905260409091205490915060ff1615610c96576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612662565b6000898152602082905260408120543490610cb2908690611dd5565b11610cd65760008a815260208390526040902054610cd1908590611dd5565b610cd8565b345b90503373ffffffffffffffffffffffffffffffffffffffff16838c7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08d85604051610d2492919061276c565b60405180910390a433600090815260028301602090815260408083208d8452825280832080548501905590849052902080548201908190558411610df55760008a81526020838152604080832054600386018054909101905560048501805460018181018355918552838520018e90558d845280860190925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909217909155518b9185918e917f39493c1b78d9a13bcc9e1d532fc7faed3889248d93affa811416ce3c6bcb1a6891a45b600482015460021415610ecd57600380890180546001018155600052820154610e1e9086611dd5565b60038301556040517f49912f8800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906349912f88908790610e9a908b90600090600401612753565b6000604051808303818588803b158015610eb357600080fd5b505af1158015610ec7573d6000803e3d6000fd5b50505050505b336108fc610edb3484611dd5565b6040518115909202916000818181858888f150505060008c81526001909401602052505060409091205460ff169750505050505050505b92915050565b60076020526000908152604090208054600182015460029092015460ff82169261010090920473ffffffffffffffffffffffffffffffffffffffff16919084565b7f000000000000000000000000000000000000000000000000000000000000000081565b60035481565b60045460055460065461271090919293565b60045481565b805160005b8181101561061a57610fc7868686868581518110610fba57fe5b602002602001015161084f565b50600101610fa0565b507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe90565b60015473ffffffffffffffffffffffffffffffffffffffff163314611046576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b49061254f565b6003547f61606860eb6c87306811e2695215385101daab53bd6ab4e9f9049aead9363c7d838360405161107a9291906123c9565b60405180910390a25050600380546001019055565b6040517ff7434ea900000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063f7434ea990611104908490600401612376565b60206040518083038186803b15801561111c57600080fd5b505afa158015611130573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f129190612013565b60008381526007602052604090206002815460ff16600381111561117457fe5b106111ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b4906126bf565b3373ffffffffffffffffffffffffffffffffffffffff16847f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167fdccf2f8b2cc26eafcd61905cba744cff4b81d14740725f6376390dc6298a6a3c868660405161122b9291906123c9565b60405180910390a450505050565b60008060035411611276576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b49061262b565b600083815260076020526040812090815460ff16600381111561129557fe5b146112cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b4906124aa565b6040517ff7434ea900000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063f7434ea990611341908490600401612376565b60206040518083038186803b15801561135957600080fd5b505afa15801561136d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113919190612013565b6040517fc13517e100000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063c13517e190839061142b907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe90600090600401612753565b6020604051808303818588803b15801561144457600080fd5b505af1158015611458573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061147d9190612013565b9250827f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f74baab670a4015ab2f1b467c5252a96141a2573f2908e58a92081e80d3cfde3d60016003540388600190046040516114f192919061276c565b60405180910390a3827fcbb827f06aed2dd1e157f8e6b29f32604bc4e88360964014c4d4ad259f8d3fa88660405161152991906122ed565b60405180910390a2600083815260086020526040808220879055835460017fffffffffffffffffffffff0000000000000000000000000000000000000000ff909116336101008102919091177fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168217865581860187905560038601805490920182559252517ff6a94ecb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169163f6a94ecb9161162091899189906004016122f6565b600060405180830381600087803b15801561163a57600080fd5b505af115801561164e573d6000803e3d6000fd5b503392506108fc915061166390503484611dd5565b6040518115909202916000818181858888f1935050505050505092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60086020526000908152604090205481565b60008381526007602052604081206002815460ff1660038111156116d957fe5b10156116e9576000915050611765565b6003810154600282015460005b8281101561176057600084600301828154811061170f57fe5b9060005260206000209060050201905060005b87518110156117565761174a828a8a848151811061173c57fe5b6020026020010151876119aa565b90960195600101611722565b50506001016116f6565b505050505b9392505050565b60008481526007602052604090206002815460ff16600381111561178c57fe5b146117c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612518565b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660031780825560028201546040517fd44e293c0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169363d44e293c9361189a938b937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201926101009004909116908a908a908a90600401612322565b600060405180830381600087803b1580156118b457600080fd5b505af11580156118c8573d6000803e3d6000fd5b505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611924576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b49061254f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b61271081565b6040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b600082815260018501602052604081205460ff166119fb575073ffffffffffffffffffffffffffffffffffffffff831660009081526002850160209081526040808320858452909152902054611b3e565b81831415611a6e57600083815260208690526040902054611a1d576000611a67565b60008381526020868152604080832054600389015473ffffffffffffffffffffffffffffffffffffffff8916855260028a0184528285208886529093529220540281611a6557fe5b045b9050611b3e565b6004850154600111801590611a945750600082815260018601602052604090205460ff16155b15611b3e5784600001600086600401600181548110611aaf57fe5b906000526020600020015481526020019081526020016000205485600001600087600401600081548110611adf57fe5b6000918252602080832090910154835282810193909352604091820181205460038a015473ffffffffffffffffffffffffffffffffffffffff8a16835260028b018552838320898452909452919020549201910281611b3a57fe5b0490505b949350505050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663afe15cfb866040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401611bbe91906122ed565b604080518083038186803b158015611bd557600080fd5b505afa158015611be9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c0d9190612169565b9150915083831415611c6357814210158015611c2857508042105b611c5e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612416565b611cbb565b814210158015611c8557506127106006548383030281611c7f57fe5b04820142105b611cbb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612416565b5050505050565b600080600083851415611cd85750600454611cdd565b506005545b6040517ff23f16e600000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063f23f16e690611d54908a908590600401612753565b60206040518083038186803b158015611d6c57600080fd5b505afa158015611d80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611da49190612013565b905080611dc7612710611db78386611df0565b81611dbe57fe5b84919004611e38565b935093505050935093915050565b600082821115611de757506000610f12565b50808203610f12565b600082611dff57506000610f12565b82820282848281611e0c57fe5b0414611765577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611b3e565b600082820183811015611765577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611b3e565b600082601f830112611e7b578081fd5b8135602067ffffffffffffffff80831115611e9257fe5b81830260405183828201018181108482111715611eab57fe5b60405284815283810192508684018288018501891015611ec9578687fd5b8692505b85831015611eeb578035845292840192600192909201918401611ecd565b50979650505050505050565b60008083601f840112611f08578182fd5b50813567ffffffffffffffff811115611f1f578182fd5b602083019150836020828501011115611f3757600080fd5b9250929050565b600060208284031215611f4f578081fd5b8135611765816127a1565b600060208284031215611f6b578081fd5b5035919050565b60008060008060808587031215611f87578283fd5b8435935060208501359250604085013591506060850135611fa7816127a1565b939692955090935050565b60008060408385031215611fc4578182fd5b50508035926020909101359150565b60008060208385031215611fe5578182fd5b823567ffffffffffffffff811115611ffb578283fd5b61200785828601611ef7565b90969095509350505050565b600060208284031215612024578081fd5b5051919050565b60008060006060848603121561203f578283fd5b833592506020840135612051816127a1565b9150604084013567ffffffffffffffff81111561206c578182fd5b61207886828701611e6b565b9150509250925092565b60008060008060808587031215612097578384fd5b8435935060208501356120a9816127a1565b925060408501359150606085013567ffffffffffffffff8111156120cb578182fd5b6120d787828801611e6b565b91505092959194509250565b600080600080608085870312156120f8578384fd5b84359350602085013561210a816127a1565b93969395505050506040820135916060013590565b600080600060408486031215612133578283fd5b83359250602084013567ffffffffffffffff811115612150578283fd5b61215c86828701611ef7565b9497909650939450505050565b6000806040838503121561217b578182fd5b505080516020909101519092909150565b6000806000606084860312156121a0578081fd5b505081359360208301359350604090920135919050565b60008151808452815b818110156121dc576020818501810151868301820152016121c0565b818111156121ed5782602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000815460018082166000811461223e576001811461227a576122b8565b607f600284041686527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00831660208701526040860193506122b8565b6002830480875261228a86612795565b60005b828110156122ae5781546020828b010152848201915060208101905061228d565b8801602001955050505b50505092915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b901515815260200190565b90815260200190565b92835273ffffffffffffffffffffffffffffffffffffffff919091166020830152604082015260600190565b958652602086019490945273ffffffffffffffffffffffffffffffffffffffff9283166040860152606085019190915260808401521660a082015260c00190565b60006020825261176560208301846121b7565b6000602082526117656020830184612220565b608081016004861061239757fe5b94815273ffffffffffffffffffffffffffffffffffffffff939093166020840152604083019190915260609091015290565b60006020825282602083015282846040840137818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6020808252602e908201527f46756e64696e67206d757374206265206d6164652077697468696e207468652060408201527f61707065616c20706572696f642e000000000000000000000000000000000000606082015260800190565b60208082526017908201527f4f6e6c792061726269747261746f7220616c6c6f776564000000000000000000604082015260600190565b6020808252601d908201527f4172626974726174696f6e20616c726561647920726571756573746564000000604082015260600190565b6020808252600e908201527f496e76616c69642072756c696e67000000000000000000000000000000000000604082015260600190565b6020808252601b908201527f546865207374617475732073686f756c642062652052756c65642e0000000000604082015260600190565b6020808252601f908201527f4f6e6c7920676f7665726e6f722063616e206578656375746520746869732e00604082015260600190565b60208082526017908201527f416e73776572206973206f7574206f6620626f756e6473000000000000000000604082015260600190565b60208082526017908201527f5468657265206973206e6f2072756c696e67207965742e000000000000000000604082015260600190565b60208082526015908201527f4e6f206469737075746520746f2061707065616c2e0000000000000000000000604082015260600190565b6020808252601d908201527f5468657265206973206e6f206d65746165766964656e6365207965742e000000604082015260600190565b60208082526021908201527f41707065616c206665652068617320616c7265616479206265656e207061696460408201527f2e00000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252602d908201527f43616e6e6f74207375626d69742065766964656e636520746f2061207265736f60408201527f6c76656420646973707574652e00000000000000000000000000000000000000606082015260800190565b6020808252601a908201527f496e76616c6964206172626974726174696f6e20737461747573000000000000604082015260600190565b600083825260406020830152611b3e6040830184612220565b918252602082015260400190565b93845260208401929092526040830152606082015260800190565b60009081526020902090565b73ffffffffffffffffffffffffffffffffffffffff811681146127c357600080fd5b5056fea264697066735822122078e6e723788183bd0325c92ef0f7700e866fd8c2991787e152c7d04cca89b8af64736f6c63430007060033", + "deployedBytecode": "0x6080604052600436106101d4576000357c0100000000000000000000000000000000000000000000000000000000900480637b94338311610109578063bc8802a2116100a7578063e32511da11610081578063e32511da146104b0578063e4c0aaf4146104d0578063fe6ca782146104f0578063ffa1ad7414610505576101d4565b8063bc8802a21461045b578063c21ae06114610470578063c25516e914610490576101d4565b806390765279116100e357806390765279146103e8578063a22352e214610408578063a6a7f0eb14610428578063a829c3d114610448576101d4565b80637b9433831461039357806385632b12146103a85780638d8b2d7e146103c8576101d4565b8063392f37e911610176578063631eabd511610150578063631eabd5146103145780636cc6cde1146103445780636cdc090f1461035957806379873f8a1461036e576101d4565b8063392f37e9146102bf5780634658eb01146102d45780634b2f0ea0146102f4576101d4565b80630e274e4c116101b25780630e274e4c146102485780631d5120851461026a578063311a6c561461027f578063362c34791461029f576101d4565b80630c139eb4146101d95780630c340a24146102045780630c7ac7b614610226575b600080fd5b3480156101e557600080fd5b506101ee61051a565b6040516101fb91906122ed565b60405180910390f35b34801561021057600080fd5b50610219610520565b6040516101fb91906122c1565b34801561023257600080fd5b5061023b61053c565b6040516101fb9190612363565b34801561025457600080fd5b5061026861026336600461202b565b6105e8565b005b34801561027657600080fd5b506101ee610622565b34801561028b57600080fd5b5061026861029a366004611fb2565b610628565b3480156102ab57600080fd5b506101ee6102ba3660046120e3565b61084f565b3480156102cb57600080fd5b5061023b61098e565b3480156102e057600080fd5b506102686102ef36600461218c565b610a04565b610307610302366004611fb2565b610a63565b6040516101fb91906122e2565b34801561032057600080fd5b5061033461032f366004611f5a565b610f18565b6040516101fb9493929190612389565b34801561035057600080fd5b50610219610f59565b34801561036557600080fd5b506101ee610f7d565b34801561037a57600080fd5b50610383610f83565b6040516101fb949392919061277a565b34801561039f57600080fd5b506101ee610f95565b3480156103b457600080fd5b506102686103c3366004612082565b610f9b565b3480156103d457600080fd5b506101ee6103e3366004611f5a565b610fd0565b3480156103f457600080fd5b50610268610403366004611fd3565b610ff5565b34801561041457600080fd5b506101ee610423366004611f5a565b61108f565b34801561043457600080fd5b5061026861044336600461211f565b611154565b6101ee610456366004611fb2565b611239565b34801561046757600080fd5b50610219611683565b34801561047c57600080fd5b506101ee61048b366004611f5a565b6116a7565b34801561049c57600080fd5b506101ee6104ab36600461202b565b6116b9565b3480156104bc57600080fd5b506102686104cb366004611f72565b61176c565b3480156104dc57600080fd5b506102686104eb366004611f3e565b6118d3565b3480156104fc57600080fd5b506101ee61196b565b34801561051157600080fd5b5061023b611971565b60065481565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815292918301828280156105e05780601f106105b5576101008083540402835291602001916105e0565b820191906000526020600020905b8154815290600101906020018083116105c357829003601f168201915b505050505081565b6000838152600760205260408120600381015490915b8181101561061a5761061286868387610f9b565b6001016105fe565b505050505050565b60055481565b60008281526008602090815260408083205480845260079092529091203373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612473565b60405180910390fd5b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe831115610717576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b4906124e1565b6001815460ff16600381111561072957fe5b14610760576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b49061271c565b600381018054600091907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061079657fe5b90600052602060002090600502019050600081600401805490506001146107bd57846107d9565b816004016000815481106107cd57fe5b90600052602060002001545b600284810182905584547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016178455604051909150869033907f394027a5fa6e098a1191094d1719d6929b9abc535fcc0c8f448d6a4e756222769061083f9085906122ed565b60405180910390a3505050505050565b60008481526007602052604081206003810180548391908690811061087057fe5b6000918252602090912060059091020190506001825460ff16600381111561089457fe5b116108cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b4906125bd565b6108db81878685600201546119aa565b925082156109845773ffffffffffffffffffffffffffffffffffffffff8616600081815260028301602090815260408083208884529091528082208290555185156108fc0291869190818181858888f19350505050508573ffffffffffffffffffffffffffffffffffffffff1685887f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae878760405161097b92919061276c565b60405180910390a45b5050949350505050565b600280546040805160206001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01909316849004601f810184900484028201840190925281815292918301828280156105e05780601f106105b5576101008083540402835291602001916105e0565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a55576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b49061254f565b600492909255600555600655565b60007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe821115610abf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612586565b600083815260076020526040902060018082015490825460ff166003811115610ae457fe5b14610b1b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b4906125f4565b6040517f1c3db16d00000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690631c3db16d90610b909085906004016122ed565b60206040518083038186803b158015610ba857600080fd5b505afa158015610bbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be09190612013565b9050610bed828683611b46565b600080610bfb848885611cc2565b6003870180549294509092507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201916000919083908110610c3957fe5b600091825260208083208c84526001600590930201918201905260409091205490915060ff1615610c96576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612662565b6000898152602082905260408120543490610cb2908690611dd5565b11610cd65760008a815260208390526040902054610cd1908590611dd5565b610cd8565b345b90503373ffffffffffffffffffffffffffffffffffffffff16838c7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08d85604051610d2492919061276c565b60405180910390a433600090815260028301602090815260408083208d8452825280832080548501905590849052902080548201908190558411610df55760008a81526020838152604080832054600386018054909101905560048501805460018181018355918552838520018e90558d845280860190925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909217909155518b9185918e917f39493c1b78d9a13bcc9e1d532fc7faed3889248d93affa811416ce3c6bcb1a6891a45b600482015460021415610ecd57600380890180546001018155600052820154610e1e9086611dd5565b60038301556040517f49912f8800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906349912f88908790610e9a908b90600090600401612753565b6000604051808303818588803b158015610eb357600080fd5b505af1158015610ec7573d6000803e3d6000fd5b50505050505b336108fc610edb3484611dd5565b6040518115909202916000818181858888f150505060008c81526001909401602052505060409091205460ff169750505050505050505b92915050565b60076020526000908152604090208054600182015460029092015460ff82169261010090920473ffffffffffffffffffffffffffffffffffffffff16919084565b7f000000000000000000000000000000000000000000000000000000000000000081565b60035481565b60045460055460065461271090919293565b60045481565b805160005b8181101561061a57610fc7868686868581518110610fba57fe5b602002602001015161084f565b50600101610fa0565b507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe90565b60015473ffffffffffffffffffffffffffffffffffffffff163314611046576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b49061254f565b6003547f61606860eb6c87306811e2695215385101daab53bd6ab4e9f9049aead9363c7d838360405161107a9291906123c9565b60405180910390a25050600380546001019055565b6040517ff7434ea900000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063f7434ea990611104908490600401612376565b60206040518083038186803b15801561111c57600080fd5b505afa158015611130573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f129190612013565b60008381526007602052604090206002815460ff16600381111561117457fe5b106111ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b4906126bf565b3373ffffffffffffffffffffffffffffffffffffffff16847f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167fdccf2f8b2cc26eafcd61905cba744cff4b81d14740725f6376390dc6298a6a3c868660405161122b9291906123c9565b60405180910390a450505050565b60008060035411611276576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b49061262b565b600083815260076020526040812090815460ff16600381111561129557fe5b146112cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b4906124aa565b6040517ff7434ea900000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063f7434ea990611341908490600401612376565b60206040518083038186803b15801561135957600080fd5b505afa15801561136d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113919190612013565b6040517fc13517e100000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063c13517e190839061142b907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe90600090600401612753565b6020604051808303818588803b15801561144457600080fd5b505af1158015611458573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061147d9190612013565b9250827f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f74baab670a4015ab2f1b467c5252a96141a2573f2908e58a92081e80d3cfde3d60016003540388600190046040516114f192919061276c565b60405180910390a3827fcbb827f06aed2dd1e157f8e6b29f32604bc4e88360964014c4d4ad259f8d3fa88660405161152991906122ed565b60405180910390a2600083815260086020526040808220879055835460017fffffffffffffffffffffff0000000000000000000000000000000000000000ff909116336101008102919091177fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168217865581860187905560038601805490920182559252517ff6a94ecb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169163f6a94ecb9161162091899189906004016122f6565b600060405180830381600087803b15801561163a57600080fd5b505af115801561164e573d6000803e3d6000fd5b503392506108fc915061166390503484611dd5565b6040518115909202916000818181858888f1935050505050505092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60086020526000908152604090205481565b60008381526007602052604081206002815460ff1660038111156116d957fe5b10156116e9576000915050611765565b6003810154600282015460005b8281101561176057600084600301828154811061170f57fe5b9060005260206000209060050201905060005b87518110156117565761174a828a8a848151811061173c57fe5b6020026020010151876119aa565b90960195600101611722565b50506001016116f6565b505050505b9392505050565b60008481526007602052604090206002815460ff16600381111561178c57fe5b146117c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612518565b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660031780825560028201546040517fd44e293c0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169363d44e293c9361189a938b937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201926101009004909116908a908a908a90600401612322565b600060405180830381600087803b1580156118b457600080fd5b505af11580156118c8573d6000803e3d6000fd5b505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611924576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b49061254f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b61271081565b6040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b600082815260018501602052604081205460ff166119fb575073ffffffffffffffffffffffffffffffffffffffff831660009081526002850160209081526040808320858452909152902054611b3e565b81831415611a6e57600083815260208690526040902054611a1d576000611a67565b60008381526020868152604080832054600389015473ffffffffffffffffffffffffffffffffffffffff8916855260028a0184528285208886529093529220540281611a6557fe5b045b9050611b3e565b6004850154600111801590611a945750600082815260018601602052604090205460ff16155b15611b3e5784600001600086600401600181548110611aaf57fe5b906000526020600020015481526020019081526020016000205485600001600087600401600081548110611adf57fe5b6000918252602080832090910154835282810193909352604091820181205460038a015473ffffffffffffffffffffffffffffffffffffffff8a16835260028b018552838320898452909452919020549201910281611b3a57fe5b0490505b949350505050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663afe15cfb866040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401611bbe91906122ed565b604080518083038186803b158015611bd557600080fd5b505afa158015611be9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c0d9190612169565b9150915083831415611c6357814210158015611c2857508042105b611c5e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612416565b611cbb565b814210158015611c8557506127106006548383030281611c7f57fe5b04820142105b611cbb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b490612416565b5050505050565b600080600083851415611cd85750600454611cdd565b506005545b6040517ff23f16e600000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063f23f16e690611d54908a908590600401612753565b60206040518083038186803b158015611d6c57600080fd5b505afa158015611d80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611da49190612013565b905080611dc7612710611db78386611df0565b81611dbe57fe5b84919004611e38565b935093505050935093915050565b600082821115611de757506000610f12565b50808203610f12565b600082611dff57506000610f12565b82820282848281611e0c57fe5b0414611765577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611b3e565b600082820183811015611765577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611b3e565b600082601f830112611e7b578081fd5b8135602067ffffffffffffffff80831115611e9257fe5b81830260405183828201018181108482111715611eab57fe5b60405284815283810192508684018288018501891015611ec9578687fd5b8692505b85831015611eeb578035845292840192600192909201918401611ecd565b50979650505050505050565b60008083601f840112611f08578182fd5b50813567ffffffffffffffff811115611f1f578182fd5b602083019150836020828501011115611f3757600080fd5b9250929050565b600060208284031215611f4f578081fd5b8135611765816127a1565b600060208284031215611f6b578081fd5b5035919050565b60008060008060808587031215611f87578283fd5b8435935060208501359250604085013591506060850135611fa7816127a1565b939692955090935050565b60008060408385031215611fc4578182fd5b50508035926020909101359150565b60008060208385031215611fe5578182fd5b823567ffffffffffffffff811115611ffb578283fd5b61200785828601611ef7565b90969095509350505050565b600060208284031215612024578081fd5b5051919050565b60008060006060848603121561203f578283fd5b833592506020840135612051816127a1565b9150604084013567ffffffffffffffff81111561206c578182fd5b61207886828701611e6b565b9150509250925092565b60008060008060808587031215612097578384fd5b8435935060208501356120a9816127a1565b925060408501359150606085013567ffffffffffffffff8111156120cb578182fd5b6120d787828801611e6b565b91505092959194509250565b600080600080608085870312156120f8578384fd5b84359350602085013561210a816127a1565b93969395505050506040820135916060013590565b600080600060408486031215612133578283fd5b83359250602084013567ffffffffffffffff811115612150578283fd5b61215c86828701611ef7565b9497909650939450505050565b6000806040838503121561217b578182fd5b505080516020909101519092909150565b6000806000606084860312156121a0578081fd5b505081359360208301359350604090920135919050565b60008151808452815b818110156121dc576020818501810151868301820152016121c0565b818111156121ed5782602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000815460018082166000811461223e576001811461227a576122b8565b607f600284041686527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00831660208701526040860193506122b8565b6002830480875261228a86612795565b60005b828110156122ae5781546020828b010152848201915060208101905061228d565b8801602001955050505b50505092915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b901515815260200190565b90815260200190565b92835273ffffffffffffffffffffffffffffffffffffffff919091166020830152604082015260600190565b958652602086019490945273ffffffffffffffffffffffffffffffffffffffff9283166040860152606085019190915260808401521660a082015260c00190565b60006020825261176560208301846121b7565b6000602082526117656020830184612220565b608081016004861061239757fe5b94815273ffffffffffffffffffffffffffffffffffffffff939093166020840152604083019190915260609091015290565b60006020825282602083015282846040840137818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6020808252602e908201527f46756e64696e67206d757374206265206d6164652077697468696e207468652060408201527f61707065616c20706572696f642e000000000000000000000000000000000000606082015260800190565b60208082526017908201527f4f6e6c792061726269747261746f7220616c6c6f776564000000000000000000604082015260600190565b6020808252601d908201527f4172626974726174696f6e20616c726561647920726571756573746564000000604082015260600190565b6020808252600e908201527f496e76616c69642072756c696e67000000000000000000000000000000000000604082015260600190565b6020808252601b908201527f546865207374617475732073686f756c642062652052756c65642e0000000000604082015260600190565b6020808252601f908201527f4f6e6c7920676f7665726e6f722063616e206578656375746520746869732e00604082015260600190565b60208082526017908201527f416e73776572206973206f7574206f6620626f756e6473000000000000000000604082015260600190565b60208082526017908201527f5468657265206973206e6f2072756c696e67207965742e000000000000000000604082015260600190565b60208082526015908201527f4e6f206469737075746520746f2061707065616c2e0000000000000000000000604082015260600190565b6020808252601d908201527f5468657265206973206e6f206d65746165766964656e6365207965742e000000604082015260600190565b60208082526021908201527f41707065616c206665652068617320616c7265616479206265656e207061696460408201527f2e00000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252602d908201527f43616e6e6f74207375626d69742065766964656e636520746f2061207265736f60408201527f6c76656420646973707574652e00000000000000000000000000000000000000606082015260800190565b6020808252601a908201527f496e76616c6964206172626974726174696f6e20737461747573000000000000604082015260600190565b600083825260406020830152611b3e6040830184612220565b918252602082015260400190565b93845260208401929092526040830152606082015260800190565b60009081526020902090565b73ffffffffffffffffffffffffffffffffffffffff811681146127c357600080fd5b5056fea264697066735822122078e6e723788183bd0325c92ef0f7700e866fd8c2991787e152c7d04cca89b8af64736f6c63430007060033", + "immutableReferences": { + "56": [ + { + "length": 32, + "start": 5609 + }, + { + "length": 32, + "start": 5765 + }, + { + "length": 32, + "start": 6170 + } + ], + "58": [ + { + "length": 32, + "start": 1629 + }, + { + "length": 32, + "start": 2907 + }, + { + "length": 32, + "start": 3680 + }, + { + "length": 32, + "start": 3931 + }, + { + "length": 32, + "start": 4303 + }, + { + "length": 32, + "start": 4549 + }, + { + "length": 32, + "start": 4876 + }, + { + "length": 32, + "start": 5073 + }, + { + "length": 32, + "start": 5250 + }, + { + "length": 32, + "start": 6987 + }, + { + "length": 32, + "start": 7453 + } + ] + }, + "generatedSources": [ + { + "ast": { + "nodeType": "YulBlock", + "src": "0:2071:12", + "statements": [ + { + "nodeType": "YulBlock", + "src": "6:3:12", + "statements": [] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "101:681:12", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "111:28:12", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "121:18:12", + "type": "", + "value": "0xffffffffffffffff" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "115:2:12", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "166:13:12", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "invalid", + "nodeType": "YulIdentifier", + "src": "168:7:12" + }, + "nodeType": "YulFunctionCall", + "src": "168:9:12" + }, + "nodeType": "YulExpressionStatement", + "src": "168:9:12" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "154:6:12" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "162:2:12" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "151:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "151:14:12" + }, + "nodeType": "YulIf", + "src": "148:2:12" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "188:23:12", + "value": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "208:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "202:5:12" + }, + "nodeType": "YulFunctionCall", + "src": "202:9:12" + }, + "variables": [ + { + "name": "memPtr", + "nodeType": "YulTypedName", + "src": "192:6:12", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "220:14:12", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "230:4:12", + "type": "", + "value": "0x20" + }, + "variables": [ + { + "name": "_2", + "nodeType": "YulTypedName", + "src": "224:2:12", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "243:71:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "269:6:12" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "285:6:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "293:4:12", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "281:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "281:17:12" + }, + { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "304:2:12", + "type": "", + "value": "31" + } + ], + "functionName": { + "name": "not", + "nodeType": "YulIdentifier", + "src": "300:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "300:7:12" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "277:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "277:31:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "265:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "265:44:12" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "311:2:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "261:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "261:53:12" + }, + "variables": [ + { + "name": "newFreePtr", + "nodeType": "YulTypedName", + "src": "247:10:12", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "373:13:12", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "invalid", + "nodeType": "YulIdentifier", + "src": "375:7:12" + }, + "nodeType": "YulFunctionCall", + "src": "375:9:12" + }, + "nodeType": "YulExpressionStatement", + "src": "375:9:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "332:10:12" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "344:2:12" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "329:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "329:18:12" + }, + { + "arguments": [ + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "352:10:12" + }, + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "364:6:12" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "349:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "349:22:12" + } + ], + "functionName": { + "name": "or", + "nodeType": "YulIdentifier", + "src": "326:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "326:46:12" + }, + "nodeType": "YulIf", + "src": "323:2:12" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "402:2:12", + "type": "", + "value": "64" + }, + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "406:10:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "395:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "395:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "395:22:12" + }, + { + "nodeType": "YulAssignment", + "src": "426:15:12", + "value": { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "435:6:12" + }, + "variableNames": [ + { + "name": "array", + "nodeType": "YulIdentifier", + "src": "426:5:12" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "457:6:12" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "465:6:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "450:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "450:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "450:22:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "510:16:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "519:1:12", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "522:1:12", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "512:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "512:12:12" + }, + "nodeType": "YulExpressionStatement", + "src": "512:12:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "src", + "nodeType": "YulIdentifier", + "src": "491:3:12" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "496:6:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "487:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "487:16:12" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "505:3:12" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "484:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "484:25:12" + }, + "nodeType": "YulIf", + "src": "481:2:12" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "535:10:12", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "544:1:12", + "type": "", + "value": "0" + }, + "variables": [ + { + "name": "i", + "nodeType": "YulTypedName", + "src": "539:1:12", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "604:75:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "633:6:12" + }, + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "641:1:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "629:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "629:14:12" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "645:2:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "625:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "625:23:12" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "src", + "nodeType": "YulIdentifier", + "src": "660:3:12" + }, + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "665:1:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "656:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "656:11:12" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "650:5:12" + }, + "nodeType": "YulFunctionCall", + "src": "650:18:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "618:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "618:51:12" + }, + "nodeType": "YulExpressionStatement", + "src": "618:51:12" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "565:1:12" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "568:6:12" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "562:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "562:13:12" + }, + "nodeType": "YulForLoop", + "post": { + "nodeType": "YulBlock", + "src": "576:19:12", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "578:15:12", + "value": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "587:1:12" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "590:2:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "583:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "583:10:12" + }, + "variableNames": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "578:1:12" + } + ] + } + ] + }, + "pre": { + "nodeType": "YulBlock", + "src": "558:3:12", + "statements": [] + }, + "src": "554:125:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "713:63:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "742:6:12" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "750:6:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "738:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "738:19:12" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "759:2:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "734:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "734:28:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "764:1:12", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "727:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "727:39:12" + }, + "nodeType": "YulExpressionStatement", + "src": "727:39:12" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "694:1:12" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "697:6:12" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "691:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "691:13:12" + }, + "nodeType": "YulIf", + "src": "688:2:12" + } + ] + }, + "name": "abi_decode_available_length_t_bytes_fromMemory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "src", + "nodeType": "YulTypedName", + "src": "70:3:12", + "type": "" + }, + { + "name": "length", + "nodeType": "YulTypedName", + "src": "75:6:12", + "type": "" + }, + { + "name": "end", + "nodeType": "YulTypedName", + "src": "83:3:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "array", + "nodeType": "YulTypedName", + "src": "91:5:12", + "type": "" + } + ], + "src": "14:768:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "958:973:12", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "1005:26:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1014:6:12" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1022:6:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1007:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "1007:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "1007:22:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "979:7:12" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "988:9:12" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "975:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "975:23:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1000:3:12", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "971:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "971:33:12" + }, + "nodeType": "YulIf", + "src": "968:2:12" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1040:29:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1059:9:12" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "1053:5:12" + }, + "nodeType": "YulFunctionCall", + "src": "1053:16:12" + }, + "variables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "1044:5:12", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "1105:5:12" + } + ], + "functionName": { + "name": "validator_revert_t_address", + "nodeType": "YulIdentifier", + "src": "1078:26:12" + }, + "nodeType": "YulFunctionCall", + "src": "1078:33:12" + }, + "nodeType": "YulExpressionStatement", + "src": "1078:33:12" + }, + { + "nodeType": "YulAssignment", + "src": "1120:15:12", + "value": { + "name": "value", + "nodeType": "YulIdentifier", + "src": "1130:5:12" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1120:6:12" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1144:39:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1168:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1179:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1164:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "1164:18:12" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "1158:5:12" + }, + "nodeType": "YulFunctionCall", + "src": "1158:25:12" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "1148:6:12", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1192:28:12", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1202:18:12", + "type": "", + "value": "0xffffffffffffffff" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "1196:2:12", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1247:26:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "1256:6:12" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "1264:6:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1249:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "1249:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "1249:22:12" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "1235:6:12" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "1243:2:12" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "1232:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "1232:14:12" + }, + "nodeType": "YulIf", + "src": "1229:2:12" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1282:32:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1296:9:12" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "1307:6:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1292:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "1292:22:12" + }, + "variables": [ + { + "name": "_2", + "nodeType": "YulTypedName", + "src": "1286:2:12", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1362:26:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "1371:6:12" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "1379:6:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1364:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "1364:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "1364:22:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "1341:2:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1345:4:12", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1337:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "1337:13:12" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "1352:7:12" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "1333:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "1333:27:12" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "1326:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "1326:35:12" + }, + "nodeType": "YulIf", + "src": "1323:2:12" + }, + { + "nodeType": "YulAssignment", + "src": "1397:89:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "1458:2:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1462:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1454:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "1454:11:12" + }, + { + "arguments": [ + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "1473:2:12" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "1467:5:12" + }, + "nodeType": "YulFunctionCall", + "src": "1467:9:12" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "1478:7:12" + } + ], + "functionName": { + "name": "abi_decode_available_length_t_bytes_fromMemory", + "nodeType": "YulIdentifier", + "src": "1407:46:12" + }, + "nodeType": "YulFunctionCall", + "src": "1407:79:12" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "1397:6:12" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1495:40:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1520:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1531:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1516:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "1516:18:12" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "1510:5:12" + }, + "nodeType": "YulFunctionCall", + "src": "1510:25:12" + }, + "variables": [ + { + "name": "value_1", + "nodeType": "YulTypedName", + "src": "1499:7:12", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "1571:7:12" + } + ], + "functionName": { + "name": "validator_revert_t_address", + "nodeType": "YulIdentifier", + "src": "1544:26:12" + }, + "nodeType": "YulFunctionCall", + "src": "1544:35:12" + }, + "nodeType": "YulExpressionStatement", + "src": "1544:35:12" + }, + { + "nodeType": "YulAssignment", + "src": "1588:17:12", + "value": { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "1598:7:12" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "1588:6:12" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1614:41:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1640:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1651:2:12", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1636:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "1636:18:12" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "1630:5:12" + }, + "nodeType": "YulFunctionCall", + "src": "1630:25:12" + }, + "variables": [ + { + "name": "offset_1", + "nodeType": "YulTypedName", + "src": "1618:8:12", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1684:26:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "1693:6:12" + }, + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "1701:6:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1686:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "1686:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "1686:22:12" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset_1", + "nodeType": "YulIdentifier", + "src": "1670:8:12" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "1680:2:12" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "1667:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "1667:16:12" + }, + "nodeType": "YulIf", + "src": "1664:2:12" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1719:34:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1733:9:12" + }, + { + "name": "offset_1", + "nodeType": "YulIdentifier", + "src": "1744:8:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1729:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "1729:24:12" + }, + "variables": [ + { + "name": "_3", + "nodeType": "YulTypedName", + "src": "1723:2:12", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1801:26:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "1810:6:12" + }, + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "1818:6:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1803:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "1803:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "1803:22:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "1780:2:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1784:4:12", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1776:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "1776:13:12" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "1791:7:12" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "1772:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "1772:27:12" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "1765:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "1765:35:12" + }, + "nodeType": "YulIf", + "src": "1762:2:12" + }, + { + "nodeType": "YulAssignment", + "src": "1836:89:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "1897:2:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1901:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1893:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "1893:11:12" + }, + { + "arguments": [ + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "1912:2:12" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "1906:5:12" + }, + "nodeType": "YulFunctionCall", + "src": "1906:9:12" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "1917:7:12" + } + ], + "functionName": { + "name": "abi_decode_available_length_t_bytes_fromMemory", + "nodeType": "YulIdentifier", + "src": "1846:46:12" + }, + "nodeType": "YulFunctionCall", + "src": "1846:79:12" + }, + "variableNames": [ + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "1836:6:12" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_addresst_string_memory_ptrt_contract$_IArbitrator_$1847t_bytes_memory_ptr_fromMemory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "900:9:12", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "911:7:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "923:6:12", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "931:6:12", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "939:6:12", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "947:6:12", + "type": "" + } + ], + "src": "787:1144:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1983:86:12", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "2047:16:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2056:1:12", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2059:1:12", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "2049:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "2049:12:12" + }, + "nodeType": "YulExpressionStatement", + "src": "2049:12:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "2006:5:12" + }, + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "2017:5:12" + }, + { + "arguments": [ + { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2032:1:12", + "type": "", + "value": "2" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2035:3:12", + "type": "", + "value": "160" + } + ], + "functionName": { + "name": "exp", + "nodeType": "YulIdentifier", + "src": "2028:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "2028:11:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2041:1:12", + "type": "", + "value": "1" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "2024:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "2024:19:12" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "2013:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "2013:31:12" + } + ], + "functionName": { + "name": "eq", + "nodeType": "YulIdentifier", + "src": "2003:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "2003:42:12" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "1996:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "1996:50:12" + }, + "nodeType": "YulIf", + "src": "1993:2:12" + } + ] + }, + "name": "validator_revert_t_address", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "1972:5:12", + "type": "" + } + ], + "src": "1936:133:12" + } + ] + }, + "contents": "{\n { }\n function abi_decode_available_length_t_bytes_fromMemory(src, length, end) -> array\n {\n let _1 := 0xffffffffffffffff\n if gt(length, _1) { invalid() }\n let memPtr := mload(64)\n let _2 := 0x20\n let newFreePtr := add(add(memPtr, and(add(length, 0x1f), not(31))), _2)\n if or(gt(newFreePtr, _1), lt(newFreePtr, memPtr)) { invalid() }\n mstore(64, newFreePtr)\n array := memPtr\n mstore(memPtr, length)\n if gt(add(src, length), end) { revert(0, 0) }\n let i := 0\n for { } lt(i, length) { i := add(i, _2) }\n {\n mstore(add(add(memPtr, i), _2), mload(add(src, i)))\n }\n if gt(i, length)\n {\n mstore(add(add(memPtr, length), _2), 0)\n }\n }\n function abi_decode_tuple_t_addresst_string_memory_ptrt_contract$_IArbitrator_$1847t_bytes_memory_ptr_fromMemory(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 128) { revert(value0, value0) }\n let value := mload(headStart)\n validator_revert_t_address(value)\n value0 := value\n let offset := mload(add(headStart, 32))\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(value1, value1) }\n let _2 := add(headStart, offset)\n if iszero(slt(add(_2, 0x1f), dataEnd)) { revert(value1, value1) }\n value1 := abi_decode_available_length_t_bytes_fromMemory(add(_2, 32), mload(_2), dataEnd)\n let value_1 := mload(add(headStart, 64))\n validator_revert_t_address(value_1)\n value2 := value_1\n let offset_1 := mload(add(headStart, 96))\n if gt(offset_1, _1) { revert(value3, value3) }\n let _3 := add(headStart, offset_1)\n if iszero(slt(add(_3, 0x1f), dataEnd)) { revert(value3, value3) }\n value3 := abi_decode_available_length_t_bytes_fromMemory(add(_3, 32), mload(_3), dataEnd)\n }\n function validator_revert_t_address(value)\n {\n if iszero(eq(value, and(value, sub(exp(2, 160), 1)))) { revert(0, 0) }\n }\n}", + "id": 12, + "language": "Yul", + "name": "#utility.yul" + } + ], + "deployedGeneratedSources": [ + { + "ast": { + "nodeType": "YulBlock", + "src": "0:17463:12", + "statements": [ + { + "nodeType": "YulBlock", + "src": "6:3:12", + "statements": [] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "84:838:12", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "133:24:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "array", + "nodeType": "YulIdentifier", + "src": "142:5:12" + }, + { + "name": "array", + "nodeType": "YulIdentifier", + "src": "149:5:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "135:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "135:20:12" + }, + "nodeType": "YulExpressionStatement", + "src": "135:20:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "112:6:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "120:4:12", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "108:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "108:17:12" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "127:3:12" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "104:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "104:27:12" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "97:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "97:35:12" + }, + "nodeType": "YulIf", + "src": "94:2:12" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "166:30:12", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "189:6:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "176:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "176:20:12" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "170:2:12", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "205:14:12", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "215:4:12", + "type": "", + "value": "0x20" + }, + "variables": [ + { + "name": "_2", + "nodeType": "YulTypedName", + "src": "209:2:12", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "228:28:12", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "238:18:12", + "type": "", + "value": "0xffffffffffffffff" + }, + "variables": [ + { + "name": "_3", + "nodeType": "YulTypedName", + "src": "232:2:12", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "279:13:12", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "invalid", + "nodeType": "YulIdentifier", + "src": "281:7:12" + }, + "nodeType": "YulFunctionCall", + "src": "281:9:12" + }, + "nodeType": "YulExpressionStatement", + "src": "281:9:12" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "271:2:12" + }, + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "275:2:12" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "268:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "268:10:12" + }, + "nodeType": "YulIf", + "src": "265:2:12" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "301:21:12", + "value": { + "arguments": [ + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "315:2:12" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "319:2:12" + } + ], + "functionName": { + "name": "mul", + "nodeType": "YulIdentifier", + "src": "311:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "311:11:12" + }, + "variables": [ + { + "name": "_4", + "nodeType": "YulTypedName", + "src": "305:2:12", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "331:23:12", + "value": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "351:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "345:5:12" + }, + "nodeType": "YulFunctionCall", + "src": "345:9:12" + }, + "variables": [ + { + "name": "memPtr", + "nodeType": "YulTypedName", + "src": "335:6:12", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "363:42:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "389:6:12" + }, + { + "name": "_4", + "nodeType": "YulIdentifier", + "src": "397:2:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "385:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "385:15:12" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "402:2:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "381:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "381:24:12" + }, + "variables": [ + { + "name": "newFreePtr", + "nodeType": "YulTypedName", + "src": "367:10:12", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "464:13:12", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "invalid", + "nodeType": "YulIdentifier", + "src": "466:7:12" + }, + "nodeType": "YulFunctionCall", + "src": "466:9:12" + }, + "nodeType": "YulExpressionStatement", + "src": "466:9:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "423:10:12" + }, + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "435:2:12" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "420:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "420:18:12" + }, + { + "arguments": [ + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "443:10:12" + }, + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "455:6:12" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "440:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "440:22:12" + } + ], + "functionName": { + "name": "or", + "nodeType": "YulIdentifier", + "src": "417:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "417:46:12" + }, + "nodeType": "YulIf", + "src": "414:2:12" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "493:2:12", + "type": "", + "value": "64" + }, + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "497:10:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "486:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "486:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "486:22:12" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "517:17:12", + "value": { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "528:6:12" + }, + "variables": [ + { + "name": "dst", + "nodeType": "YulTypedName", + "src": "521:3:12", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "550:6:12" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "558:2:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "543:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "543:18:12" + }, + "nodeType": "YulExpressionStatement", + "src": "543:18:12" + }, + { + "nodeType": "YulAssignment", + "src": "570:22:12", + "value": { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "581:6:12" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "589:2:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "577:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "577:15:12" + }, + "variableNames": [ + { + "name": "dst", + "nodeType": "YulIdentifier", + "src": "570:3:12" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "601:26:12", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "616:6:12" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "624:2:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "612:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "612:15:12" + }, + "variables": [ + { + "name": "src", + "nodeType": "YulTypedName", + "src": "605:3:12", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "673:24:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "array", + "nodeType": "YulIdentifier", + "src": "682:5:12" + }, + { + "name": "array", + "nodeType": "YulIdentifier", + "src": "689:5:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "675:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "675:20:12" + }, + "nodeType": "YulExpressionStatement", + "src": "675:20:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "650:6:12" + }, + { + "name": "_4", + "nodeType": "YulIdentifier", + "src": "658:2:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "646:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "646:15:12" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "663:2:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "642:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "642:24:12" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "668:3:12" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "639:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "639:33:12" + }, + "nodeType": "YulIf", + "src": "636:2:12" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "706:14:12", + "value": { + "name": "array", + "nodeType": "YulIdentifier", + "src": "715:5:12" + }, + "variables": [ + { + "name": "i", + "nodeType": "YulTypedName", + "src": "710:1:12", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "774:118:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "dst", + "nodeType": "YulIdentifier", + "src": "795:3:12" + }, + { + "arguments": [ + { + "name": "src", + "nodeType": "YulIdentifier", + "src": "813:3:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "800:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "800:17:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "788:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "788:30:12" + }, + "nodeType": "YulExpressionStatement", + "src": "788:30:12" + }, + { + "nodeType": "YulAssignment", + "src": "831:19:12", + "value": { + "arguments": [ + { + "name": "dst", + "nodeType": "YulIdentifier", + "src": "842:3:12" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "847:2:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "838:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "838:12:12" + }, + "variableNames": [ + { + "name": "dst", + "nodeType": "YulIdentifier", + "src": "831:3:12" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "863:19:12", + "value": { + "arguments": [ + { + "name": "src", + "nodeType": "YulIdentifier", + "src": "874:3:12" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "879:2:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "870:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "870:12:12" + }, + "variableNames": [ + { + "name": "src", + "nodeType": "YulIdentifier", + "src": "863:3:12" + } + ] + } + ] + }, + "condition": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "740:1:12" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "743:2:12" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "737:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "737:9:12" + }, + "nodeType": "YulForLoop", + "post": { + "nodeType": "YulBlock", + "src": "747:18:12", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "749:14:12", + "value": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "758:1:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "761:1:12", + "type": "", + "value": "1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "754:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "754:9:12" + }, + "variableNames": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "749:1:12" + } + ] + } + ] + }, + "pre": { + "nodeType": "YulBlock", + "src": "733:3:12", + "statements": [] + }, + "src": "729:163:12" + }, + { + "nodeType": "YulAssignment", + "src": "901:15:12", + "value": { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "910:6:12" + }, + "variableNames": [ + { + "name": "array", + "nodeType": "YulIdentifier", + "src": "901:5:12" + } + ] + } + ] + }, + "name": "abi_decode_t_array$_t_uint256_$dyn", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "58:6:12", + "type": "" + }, + { + "name": "end", + "nodeType": "YulTypedName", + "src": "66:3:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "array", + "nodeType": "YulTypedName", + "src": "74:5:12", + "type": "" + } + ], + "src": "14:908:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1002:303:12", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "1051:30:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "arrayPos", + "nodeType": "YulIdentifier", + "src": "1060:8:12" + }, + { + "name": "arrayPos", + "nodeType": "YulIdentifier", + "src": "1070:8:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1053:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "1053:26:12" + }, + "nodeType": "YulExpressionStatement", + "src": "1053:26:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "1030:6:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1038:4:12", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1026:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "1026:17:12" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "1045:3:12" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "1022:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "1022:27:12" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "1015:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "1015:35:12" + }, + "nodeType": "YulIf", + "src": "1012:2:12" + }, + { + "nodeType": "YulAssignment", + "src": "1090:30:12", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "1113:6:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "1100:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "1100:20:12" + }, + "variableNames": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "1090:6:12" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1163:30:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "arrayPos", + "nodeType": "YulIdentifier", + "src": "1172:8:12" + }, + { + "name": "arrayPos", + "nodeType": "YulIdentifier", + "src": "1182:8:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1165:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "1165:26:12" + }, + "nodeType": "YulExpressionStatement", + "src": "1165:26:12" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "1135:6:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1143:18:12", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "1132:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "1132:30:12" + }, + "nodeType": "YulIf", + "src": "1129:2:12" + }, + { + "nodeType": "YulAssignment", + "src": "1202:29:12", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "1218:6:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1226:4:12", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1214:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "1214:17:12" + }, + "variableNames": [ + { + "name": "arrayPos", + "nodeType": "YulIdentifier", + "src": "1202:8:12" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1283:16:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1292:1:12", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1295:1:12", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1285:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "1285:12:12" + }, + "nodeType": "YulExpressionStatement", + "src": "1285:12:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "1254:6:12" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "1262:6:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1250:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "1250:19:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1271:4:12", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1246:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "1246:30:12" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "1278:3:12" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "1243:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "1243:39:12" + }, + "nodeType": "YulIf", + "src": "1240:2:12" + } + ] + }, + "name": "abi_decode_t_string_calldata", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "965:6:12", + "type": "" + }, + { + "name": "end", + "nodeType": "YulTypedName", + "src": "973:3:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "arrayPos", + "nodeType": "YulTypedName", + "src": "981:8:12", + "type": "" + }, + { + "name": "length", + "nodeType": "YulTypedName", + "src": "991:6:12", + "type": "" + } + ], + "src": "927:378:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1380:189:12", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "1426:26:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1435:6:12" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1443:6:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1428:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "1428:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "1428:22:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "1401:7:12" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1410:9:12" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "1397:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "1397:23:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1422:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "1393:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "1393:32:12" + }, + "nodeType": "YulIf", + "src": "1390:2:12" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1461:36:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1487:9:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "1474:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "1474:23:12" + }, + "variables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "1465:5:12", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "1533:5:12" + } + ], + "functionName": { + "name": "validator_revert_t_address", + "nodeType": "YulIdentifier", + "src": "1506:26:12" + }, + "nodeType": "YulFunctionCall", + "src": "1506:33:12" + }, + "nodeType": "YulExpressionStatement", + "src": "1506:33:12" + }, + { + "nodeType": "YulAssignment", + "src": "1548:15:12", + "value": { + "name": "value", + "nodeType": "YulIdentifier", + "src": "1558:5:12" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1548:6:12" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_address", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "1346:9:12", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "1357:7:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "1369:6:12", + "type": "" + } + ], + "src": "1310:259:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1644:120:12", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "1690:26:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1699:6:12" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1707:6:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1692:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "1692:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "1692:22:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "1665:7:12" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1674:9:12" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "1661:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "1661:23:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1686:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "1657:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "1657:32:12" + }, + "nodeType": "YulIf", + "src": "1654:2:12" + }, + { + "nodeType": "YulAssignment", + "src": "1725:33:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1748:9:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "1735:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "1735:23:12" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1725:6:12" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes32", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "1610:9:12", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "1621:7:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "1633:6:12", + "type": "" + } + ], + "src": "1574:190:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1890:343:12", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "1937:26:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "1946:6:12" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "1954:6:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1939:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "1939:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "1939:22:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "1911:7:12" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1920:9:12" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "1907:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "1907:23:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1932:3:12", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "1903:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "1903:33:12" + }, + "nodeType": "YulIf", + "src": "1900:2:12" + }, + { + "nodeType": "YulAssignment", + "src": "1972:33:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1995:9:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "1982:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "1982:23:12" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1972:6:12" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "2014:42:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2041:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2052:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2037:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "2037:18:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "2024:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "2024:32:12" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "2014:6:12" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "2065:42:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2092:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2103:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2088:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "2088:18:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "2075:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "2075:32:12" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "2065:6:12" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "2116:45:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2146:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2157:2:12", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2142:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "2142:18:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "2129:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "2129:32:12" + }, + "variables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "2120:5:12", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "2197:5:12" + } + ], + "functionName": { + "name": "validator_revert_t_address", + "nodeType": "YulIdentifier", + "src": "2170:26:12" + }, + "nodeType": "YulFunctionCall", + "src": "2170:33:12" + }, + "nodeType": "YulExpressionStatement", + "src": "2170:33:12" + }, + { + "nodeType": "YulAssignment", + "src": "2212:15:12", + "value": { + "name": "value", + "nodeType": "YulIdentifier", + "src": "2222:5:12" + }, + "variableNames": [ + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "2212:6:12" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes32t_bytes32t_bytes32t_address", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "1832:9:12", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "1843:7:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "1855:6:12", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "1863:6:12", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "1871:6:12", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "1879:6:12", + "type": "" + } + ], + "src": "1769:464:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2325:171:12", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "2371:26:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "2380:6:12" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "2388:6:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "2373:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "2373:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "2373:22:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "2346:7:12" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2355:9:12" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "2342:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "2342:23:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2367:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "2338:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "2338:32:12" + }, + "nodeType": "YulIf", + "src": "2335:2:12" + }, + { + "nodeType": "YulAssignment", + "src": "2406:33:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2429:9:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "2416:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "2416:23:12" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "2406:6:12" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "2448:42:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2475:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2486:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2471:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "2471:18:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "2458:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "2458:32:12" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "2448:6:12" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes32t_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "2283:9:12", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "2294:7:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "2306:6:12", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "2314:6:12", + "type": "" + } + ], + "src": "2238:258:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2591:343:12", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "2637:26:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "2646:6:12" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "2654:6:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "2639:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "2639:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "2639:22:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "2612:7:12" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2621:9:12" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "2608:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "2608:23:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2633:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "2604:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "2604:32:12" + }, + "nodeType": "YulIf", + "src": "2601:2:12" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "2672:37:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2699:9:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "2686:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "2686:23:12" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "2676:6:12", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2752:26:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "2761:6:12" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "2769:6:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "2754:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "2754:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "2754:22:12" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "2724:6:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2732:18:12", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "2721:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "2721:30:12" + }, + "nodeType": "YulIf", + "src": "2718:2:12" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "2787:87:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2846:9:12" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "2857:6:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2842:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "2842:22:12" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "2866:7:12" + } + ], + "functionName": { + "name": "abi_decode_t_string_calldata", + "nodeType": "YulIdentifier", + "src": "2813:28:12" + }, + "nodeType": "YulFunctionCall", + "src": "2813:61:12" + }, + "variables": [ + { + "name": "value0_1", + "nodeType": "YulTypedName", + "src": "2791:8:12", + "type": "" + }, + { + "name": "value1_1", + "nodeType": "YulTypedName", + "src": "2801:8:12", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "2883:18:12", + "value": { + "name": "value0_1", + "nodeType": "YulIdentifier", + "src": "2893:8:12" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "2883:6:12" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "2910:18:12", + "value": { + "name": "value1_1", + "nodeType": "YulIdentifier", + "src": "2920:8:12" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "2910:6:12" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_string_calldata_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "2549:9:12", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "2560:7:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "2572:6:12", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "2580:6:12", + "type": "" + } + ], + "src": "2501:433:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "3009:120:12", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "3055:26:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3064:6:12" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3072:6:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "3057:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "3057:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "3057:22:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "3030:7:12" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3039:9:12" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "3026:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "3026:23:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3051:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "3022:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "3022:32:12" + }, + "nodeType": "YulIf", + "src": "3019:2:12" + }, + { + "nodeType": "YulAssignment", + "src": "3090:33:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3113:9:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "3100:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "3100:23:12" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3090:6:12" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "2975:9:12", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "2986:7:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "2998:6:12", + "type": "" + } + ], + "src": "2939:190:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "3215:113:12", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "3261:26:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3270:6:12" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3278:6:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "3263:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "3263:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "3263:22:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "3236:7:12" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3245:9:12" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "3232:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "3232:23:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3257:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "3228:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "3228:32:12" + }, + "nodeType": "YulIf", + "src": "3225:2:12" + }, + { + "nodeType": "YulAssignment", + "src": "3296:26:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3312:9:12" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "3306:5:12" + }, + "nodeType": "YulFunctionCall", + "src": "3306:16:12" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3296:6:12" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint256_fromMemory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "3181:9:12", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "3192:7:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "3204:6:12", + "type": "" + } + ], + "src": "3134:194:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "3470:450:12", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "3516:26:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3525:6:12" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3533:6:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "3518:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "3518:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "3518:22:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "3491:7:12" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3500:9:12" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "3487:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "3487:23:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3512:2:12", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "3483:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "3483:32:12" + }, + "nodeType": "YulIf", + "src": "3480:2:12" + }, + { + "nodeType": "YulAssignment", + "src": "3551:33:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3574:9:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "3561:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "3561:23:12" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3551:6:12" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "3593:45:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3623:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3634:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "3619:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "3619:18:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "3606:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "3606:32:12" + }, + "variables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "3597:5:12", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "3674:5:12" + } + ], + "functionName": { + "name": "validator_revert_t_address", + "nodeType": "YulIdentifier", + "src": "3647:26:12" + }, + "nodeType": "YulFunctionCall", + "src": "3647:33:12" + }, + "nodeType": "YulExpressionStatement", + "src": "3647:33:12" + }, + { + "nodeType": "YulAssignment", + "src": "3689:15:12", + "value": { + "name": "value", + "nodeType": "YulIdentifier", + "src": "3699:5:12" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "3689:6:12" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "3713:46:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3744:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3755:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "3740:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "3740:18:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "3727:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "3727:32:12" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "3717:6:12", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "3802:26:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "3811:6:12" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "3819:6:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "3804:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "3804:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "3804:22:12" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "3774:6:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3782:18:12", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "3771:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "3771:30:12" + }, + "nodeType": "YulIf", + "src": "3768:2:12" + }, + { + "nodeType": "YulAssignment", + "src": "3837:77:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3886:9:12" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "3897:6:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "3882:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "3882:22:12" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "3906:7:12" + } + ], + "functionName": { + "name": "abi_decode_t_array$_t_uint256_$dyn", + "nodeType": "YulIdentifier", + "src": "3847:34:12" + }, + "nodeType": "YulFunctionCall", + "src": "3847:67:12" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "3837:6:12" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint256t_address_payablet_array$_t_uint256_$dyn_memory_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "3420:9:12", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "3431:7:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "3443:6:12", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "3451:6:12", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "3459:6:12", + "type": "" + } + ], + "src": "3333:587:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "4079:502:12", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "4126:26:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "4135:6:12" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "4143:6:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "4128:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "4128:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "4128:22:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "4100:7:12" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4109:9:12" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "4096:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "4096:23:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4121:3:12", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "4092:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "4092:33:12" + }, + "nodeType": "YulIf", + "src": "4089:2:12" + }, + { + "nodeType": "YulAssignment", + "src": "4161:33:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4184:9:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "4171:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "4171:23:12" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "4161:6:12" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "4203:45:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4233:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4244:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4229:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "4229:18:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "4216:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "4216:32:12" + }, + "variables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "4207:5:12", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "4284:5:12" + } + ], + "functionName": { + "name": "validator_revert_t_address", + "nodeType": "YulIdentifier", + "src": "4257:26:12" + }, + "nodeType": "YulFunctionCall", + "src": "4257:33:12" + }, + "nodeType": "YulExpressionStatement", + "src": "4257:33:12" + }, + { + "nodeType": "YulAssignment", + "src": "4299:15:12", + "value": { + "name": "value", + "nodeType": "YulIdentifier", + "src": "4309:5:12" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "4299:6:12" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "4323:42:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4350:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4361:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4346:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "4346:18:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "4333:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "4333:32:12" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "4323:6:12" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "4374:46:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4405:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4416:2:12", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4401:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "4401:18:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "4388:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "4388:32:12" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "4378:6:12", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "4463:26:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "4472:6:12" + }, + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "4480:6:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "4465:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "4465:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "4465:22:12" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "4435:6:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4443:18:12", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "4432:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "4432:30:12" + }, + "nodeType": "YulIf", + "src": "4429:2:12" + }, + { + "nodeType": "YulAssignment", + "src": "4498:77:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4547:9:12" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "4558:6:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4543:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "4543:22:12" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "4567:7:12" + } + ], + "functionName": { + "name": "abi_decode_t_array$_t_uint256_$dyn", + "nodeType": "YulIdentifier", + "src": "4508:34:12" + }, + "nodeType": "YulFunctionCall", + "src": "4508:67:12" + }, + "variableNames": [ + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "4498:6:12" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint256t_address_payablet_uint256t_array$_t_uint256_$dyn_memory_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "4021:9:12", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "4032:7:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "4044:6:12", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "4052:6:12", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "4060:6:12", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "4068:6:12", + "type": "" + } + ], + "src": "3925:656:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "4715:343:12", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "4762:26:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "4771:6:12" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "4779:6:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "4764:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "4764:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "4764:22:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "4736:7:12" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4745:9:12" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "4732:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "4732:23:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4757:3:12", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "4728:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "4728:33:12" + }, + "nodeType": "YulIf", + "src": "4725:2:12" + }, + { + "nodeType": "YulAssignment", + "src": "4797:33:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4820:9:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "4807:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "4807:23:12" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "4797:6:12" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "4839:45:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4869:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4880:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4865:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "4865:18:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "4852:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "4852:32:12" + }, + "variables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "4843:5:12", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "4920:5:12" + } + ], + "functionName": { + "name": "validator_revert_t_address", + "nodeType": "YulIdentifier", + "src": "4893:26:12" + }, + "nodeType": "YulFunctionCall", + "src": "4893:33:12" + }, + "nodeType": "YulExpressionStatement", + "src": "4893:33:12" + }, + { + "nodeType": "YulAssignment", + "src": "4935:15:12", + "value": { + "name": "value", + "nodeType": "YulIdentifier", + "src": "4945:5:12" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "4935:6:12" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "4959:42:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4986:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4997:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4982:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "4982:18:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "4969:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "4969:32:12" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "4959:6:12" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "5010:42:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5037:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5048:2:12", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "5033:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "5033:18:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "5020:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "5020:32:12" + }, + "variableNames": [ + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "5010:6:12" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint256t_address_payablet_uint256t_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "4657:9:12", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "4668:7:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "4680:6:12", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "4688:6:12", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "4696:6:12", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "4704:6:12", + "type": "" + } + ], + "src": "4586:472:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5170:394:12", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "5216:26:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "5225:6:12" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "5233:6:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "5218:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "5218:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "5218:22:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "5191:7:12" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5200:9:12" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "5187:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "5187:23:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5212:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "5183:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "5183:32:12" + }, + "nodeType": "YulIf", + "src": "5180:2:12" + }, + { + "nodeType": "YulAssignment", + "src": "5251:33:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5274:9:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "5261:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "5261:23:12" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "5251:6:12" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "5293:46:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5324:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5335:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "5320:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "5320:18:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "5307:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "5307:32:12" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "5297:6:12", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5382:26:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "5391:6:12" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "5399:6:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "5384:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "5384:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "5384:22:12" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "5354:6:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5362:18:12", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "5351:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "5351:30:12" + }, + "nodeType": "YulIf", + "src": "5348:2:12" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "5417:87:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5476:9:12" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "5487:6:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "5472:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "5472:22:12" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "5496:7:12" + } + ], + "functionName": { + "name": "abi_decode_t_string_calldata", + "nodeType": "YulIdentifier", + "src": "5443:28:12" + }, + "nodeType": "YulFunctionCall", + "src": "5443:61:12" + }, + "variables": [ + { + "name": "value1_1", + "nodeType": "YulTypedName", + "src": "5421:8:12", + "type": "" + }, + { + "name": "value2_1", + "nodeType": "YulTypedName", + "src": "5431:8:12", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "5513:18:12", + "value": { + "name": "value1_1", + "nodeType": "YulIdentifier", + "src": "5523:8:12" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "5513:6:12" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "5540:18:12", + "value": { + "name": "value2_1", + "nodeType": "YulIdentifier", + "src": "5550:8:12" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "5540:6:12" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint256t_string_calldata_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "5120:9:12", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "5131:7:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "5143:6:12", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "5151:6:12", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "5159:6:12", + "type": "" + } + ], + "src": "5063:501:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5656:171:12", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "5702:26:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "5711:6:12" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "5719:6:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "5704:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "5704:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "5704:22:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "5677:7:12" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5686:9:12" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "5673:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "5673:23:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5698:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "5669:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "5669:32:12" + }, + "nodeType": "YulIf", + "src": "5666:2:12" + }, + { + "nodeType": "YulAssignment", + "src": "5737:33:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5760:9:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "5747:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "5747:23:12" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "5737:6:12" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "5779:42:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5806:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5817:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "5802:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "5802:18:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "5789:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "5789:32:12" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "5779:6:12" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint256t_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "5614:9:12", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "5625:7:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "5637:6:12", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "5645:6:12", + "type": "" + } + ], + "src": "5569:258:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5930:157:12", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "5976:26:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "5985:6:12" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "5993:6:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "5978:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "5978:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "5978:22:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "5951:7:12" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5960:9:12" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "5947:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "5947:23:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5972:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "5943:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "5943:32:12" + }, + "nodeType": "YulIf", + "src": "5940:2:12" + }, + { + "nodeType": "YulAssignment", + "src": "6011:26:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6027:9:12" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "6021:5:12" + }, + "nodeType": "YulFunctionCall", + "src": "6021:16:12" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "6011:6:12" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "6046:35:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6066:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6077:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6062:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "6062:18:12" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "6056:5:12" + }, + "nodeType": "YulFunctionCall", + "src": "6056:25:12" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "6046:6:12" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint256t_uint256_fromMemory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "5888:9:12", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "5899:7:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "5911:6:12", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "5919:6:12", + "type": "" + } + ], + "src": "5832:255:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "6196:222:12", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "6242:26:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "6251:6:12" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "6259:6:12" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "6244:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "6244:22:12" + }, + "nodeType": "YulExpressionStatement", + "src": "6244:22:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "6217:7:12" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6226:9:12" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "6213:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "6213:23:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6238:2:12", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "6209:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "6209:32:12" + }, + "nodeType": "YulIf", + "src": "6206:2:12" + }, + { + "nodeType": "YulAssignment", + "src": "6277:33:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6300:9:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "6287:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "6287:23:12" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "6277:6:12" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "6319:42:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6346:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6357:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6342:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "6342:18:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "6329:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "6329:32:12" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "6319:6:12" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "6370:42:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6397:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6408:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6393:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "6393:18:12" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "6380:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "6380:32:12" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "6370:6:12" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint256t_uint256t_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "6146:9:12", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "6157:7:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "6169:6:12", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "6177:6:12", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "6185:6:12", + "type": "" + } + ], + "src": "6092:326:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "6474:485:12", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "6484:26:12", + "value": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "6504:5:12" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "6498:5:12" + }, + "nodeType": "YulFunctionCall", + "src": "6498:12:12" + }, + "variables": [ + { + "name": "length", + "nodeType": "YulTypedName", + "src": "6488:6:12", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "6526:3:12" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "6531:6:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "6519:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "6519:19:12" + }, + "nodeType": "YulExpressionStatement", + "src": "6519:19:12" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "6547:12:12", + "value": { + "name": "end", + "nodeType": "YulIdentifier", + "src": "6556:3:12" + }, + "variables": [ + { + "name": "i", + "nodeType": "YulTypedName", + "src": "6551:1:12", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "6620:110:12", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "6634:14:12", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6644:4:12", + "type": "", + "value": "0x20" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "6638:2:12", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "6676:3:12" + }, + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "6681:1:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6672:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "6672:11:12" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "6685:2:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6668:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "6668:20:12" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "6704:5:12" + }, + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "6711:1:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6700:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "6700:13:12" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "6715:2:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6696:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "6696:22:12" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "6690:5:12" + }, + "nodeType": "YulFunctionCall", + "src": "6690:29:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "6661:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "6661:59:12" + }, + "nodeType": "YulExpressionStatement", + "src": "6661:59:12" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "6579:1:12" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "6582:6:12" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "6576:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "6576:13:12" + }, + "nodeType": "YulForLoop", + "post": { + "nodeType": "YulBlock", + "src": "6590:21:12", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "6592:17:12", + "value": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "6601:1:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6604:4:12", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6597:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "6597:12:12" + }, + "variableNames": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "6592:1:12" + } + ] + } + ] + }, + "pre": { + "nodeType": "YulBlock", + "src": "6572:3:12", + "statements": [] + }, + "src": "6568:162:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "6764:64:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "6793:3:12" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "6798:6:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6789:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "6789:16:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6807:4:12", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6785:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "6785:27:12" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "6814:3:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "6778:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "6778:40:12" + }, + "nodeType": "YulExpressionStatement", + "src": "6778:40:12" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "6745:1:12" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "6748:6:12" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "6742:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "6742:13:12" + }, + "nodeType": "YulIf", + "src": "6739:2:12" + }, + { + "nodeType": "YulAssignment", + "src": "6837:116:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "6852:3:12" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "6865:6:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6873:2:12", + "type": "", + "value": "31" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6861:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "6861:15:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6878:66:12", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "6857:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "6857:88:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6848:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "6848:98:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6948:4:12", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6844:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "6844:109:12" + }, + "variableNames": [ + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "6837:3:12" + } + ] + } + ] + }, + "name": "abi_encode_t_bytes", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "6451:5:12", + "type": "" + }, + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "6458:3:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nodeType": "YulTypedName", + "src": "6466:3:12", + "type": "" + } + ], + "src": "6423:536:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7023:755:12", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "7033:29:12", + "value": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "7056:5:12" + } + ], + "functionName": { + "name": "sload", + "nodeType": "YulIdentifier", + "src": "7050:5:12" + }, + "nodeType": "YulFunctionCall", + "src": "7050:12:12" + }, + "variables": [ + { + "name": "slotValue", + "nodeType": "YulTypedName", + "src": "7037:9:12", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "7071:11:12", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7081:1:12", + "type": "", + "value": "1" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "7075:2:12", + "type": "" + } + ] + }, + { + "cases": [ + { + "body": { + "nodeType": "YulBlock", + "src": "7132:216:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "7153:3:12" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "slotValue", + "nodeType": "YulIdentifier", + "src": "7166:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7177:1:12", + "type": "", + "value": "2" + } + ], + "functionName": { + "name": "div", + "nodeType": "YulIdentifier", + "src": "7162:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "7162:17:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7181:4:12", + "type": "", + "value": "0x7f" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "7158:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "7158:28:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "7146:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "7146:41:12" + }, + "nodeType": "YulExpressionStatement", + "src": "7146:41:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "7211:3:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7216:4:12", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7207:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "7207:14:12" + }, + { + "arguments": [ + { + "name": "slotValue", + "nodeType": "YulIdentifier", + "src": "7227:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7238:66:12", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "7223:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "7223:82:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "7200:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "7200:106:12" + }, + "nodeType": "YulExpressionStatement", + "src": "7200:106:12" + }, + { + "nodeType": "YulAssignment", + "src": "7319:19:12", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "7330:3:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7335:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7326:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "7326:12:12" + }, + "variableNames": [ + { + "name": "ret", + "nodeType": "YulIdentifier", + "src": "7319:3:12" + } + ] + } + ] + }, + "nodeType": "YulCase", + "src": "7125:223:12", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7130:1:12", + "type": "", + "value": "0" + } + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7364:408:12", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "7378:31:12", + "value": { + "arguments": [ + { + "name": "slotValue", + "nodeType": "YulIdentifier", + "src": "7396:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7407:1:12", + "type": "", + "value": "2" + } + ], + "functionName": { + "name": "div", + "nodeType": "YulIdentifier", + "src": "7392:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "7392:17:12" + }, + "variables": [ + { + "name": "length", + "nodeType": "YulTypedName", + "src": "7382:6:12", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "7429:3:12" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "7434:6:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "7422:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "7422:19:12" + }, + "nodeType": "YulExpressionStatement", + "src": "7422:19:12" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "7454:52:12", + "value": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "7500:5:12" + } + ], + "functionName": { + "name": "array_dataslot_t_bytes_storage", + "nodeType": "YulIdentifier", + "src": "7469:30:12" + }, + "nodeType": "YulFunctionCall", + "src": "7469:37:12" + }, + "variables": [ + { + "name": "dataPos", + "nodeType": "YulTypedName", + "src": "7458:7:12", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "7519:10:12", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7528:1:12", + "type": "", + "value": "0" + }, + "variables": [ + { + "name": "i", + "nodeType": "YulTypedName", + "src": "7523:1:12", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7598:122:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "7631:3:12" + }, + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "7636:1:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7627:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "7627:11:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7640:4:12", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7623:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "7623:22:12" + }, + { + "arguments": [ + { + "name": "dataPos", + "nodeType": "YulIdentifier", + "src": "7653:7:12" + } + ], + "functionName": { + "name": "sload", + "nodeType": "YulIdentifier", + "src": "7647:5:12" + }, + "nodeType": "YulFunctionCall", + "src": "7647:14:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "7616:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "7616:46:12" + }, + "nodeType": "YulExpressionStatement", + "src": "7616:46:12" + }, + { + "nodeType": "YulAssignment", + "src": "7679:27:12", + "value": { + "arguments": [ + { + "name": "dataPos", + "nodeType": "YulIdentifier", + "src": "7694:7:12" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "7703:2:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7690:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "7690:16:12" + }, + "variableNames": [ + { + "name": "dataPos", + "nodeType": "YulIdentifier", + "src": "7679:7:12" + } + ] + } + ] + }, + "condition": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "7553:1:12" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "7556:6:12" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "7550:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "7550:13:12" + }, + "nodeType": "YulForLoop", + "post": { + "nodeType": "YulBlock", + "src": "7564:21:12", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "7566:17:12", + "value": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "7575:1:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7578:4:12", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7571:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "7571:12:12" + }, + "variableNames": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "7566:1:12" + } + ] + } + ] + }, + "pre": { + "nodeType": "YulBlock", + "src": "7546:3:12", + "statements": [] + }, + "src": "7542:178:12" + }, + { + "nodeType": "YulAssignment", + "src": "7733:29:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "7748:3:12" + }, + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "7753:1:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7744:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "7744:11:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7757:4:12", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7740:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "7740:22:12" + }, + "variableNames": [ + { + "name": "ret", + "nodeType": "YulIdentifier", + "src": "7733:3:12" + } + ] + } + ] + }, + "nodeType": "YulCase", + "src": "7357:415:12", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7362:1:12", + "type": "", + "value": "1" + } + } + ], + "expression": { + "arguments": [ + { + "name": "slotValue", + "nodeType": "YulIdentifier", + "src": "7102:9:12" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "7113:2:12" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "7098:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "7098:18:12" + }, + "nodeType": "YulSwitch", + "src": "7091:681:12" + } + ] + }, + "name": "abi_encode_t_bytes_storage", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "7000:5:12", + "type": "" + }, + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "7007:3:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "ret", + "nodeType": "YulTypedName", + "src": "7015:3:12", + "type": "" + } + ], + "src": "6964:814:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7884:125:12", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "7894:26:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "7906:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7917:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7902:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "7902:18:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "7894:4:12" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "7936:9:12" + }, + { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "7951:6:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7959:42:12", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "7947:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "7947:55:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "7929:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "7929:74:12" + }, + "nodeType": "YulExpressionStatement", + "src": "7929:74:12" + } + ] + }, + "name": "abi_encode_tuple_t_address__to_t_address__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "7853:9:12", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "7864:6:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "7875:4:12", + "type": "" + } + ], + "src": "7783:226:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "8109:92:12", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "8119:26:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "8131:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8142:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8127:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "8127:18:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "8119:4:12" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "8161:9:12" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "8186:6:12" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "8179:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "8179:14:12" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "8172:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "8172:22:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "8154:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "8154:41:12" + }, + "nodeType": "YulExpressionStatement", + "src": "8154:41:12" + } + ] + }, + "name": "abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "8078:9:12", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "8089:6:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "8100:4:12", + "type": "" + } + ], + "src": "8014:187:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "8307:76:12", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "8317:26:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "8329:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8340:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8325:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "8325:18:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "8317:4:12" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "8359:9:12" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "8370:6:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "8352:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "8352:25:12" + }, + "nodeType": "YulExpressionStatement", + "src": "8352:25:12" + } + ] + }, + "name": "abi_encode_tuple_t_bytes32__to_t_bytes32__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "8276:9:12", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "8287:6:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "8298:4:12", + "type": "" + } + ], + "src": "8206:177:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "8553:211:12", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "8563:26:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "8575:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8586:2:12", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8571:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "8571:18:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "8563:4:12" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "8605:9:12" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "8616:6:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "8598:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "8598:25:12" + }, + "nodeType": "YulExpressionStatement", + "src": "8598:25:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "8643:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8654:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8639:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "8639:18:12" + }, + { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "8663:6:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8671:42:12", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "8659:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "8659:55:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "8632:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "8632:83:12" + }, + "nodeType": "YulExpressionStatement", + "src": "8632:83:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "8735:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8746:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8731:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "8731:18:12" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "8751:6:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "8724:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "8724:34:12" + }, + "nodeType": "YulExpressionStatement", + "src": "8724:34:12" + } + ] + }, + "name": "abi_encode_tuple_t_bytes32_t_address_payable_t_uint256__to_t_bytes32_t_address_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "8506:9:12", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "8517:6:12", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "8525:6:12", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "8533:6:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "8544:4:12", + "type": "" + } + ], + "src": "8388:376:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "9010:373:12", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "9020:27:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9032:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9043:3:12", + "type": "", + "value": "192" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9028:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "9028:19:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "9020:4:12" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9063:9:12" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "9074:6:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "9056:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "9056:25:12" + }, + "nodeType": "YulExpressionStatement", + "src": "9056:25:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9101:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9112:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9097:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "9097:18:12" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "9117:6:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "9090:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "9090:34:12" + }, + "nodeType": "YulExpressionStatement", + "src": "9090:34:12" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "9133:52:12", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9143:42:12", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "9137:2:12", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9205:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9216:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9201:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "9201:18:12" + }, + { + "arguments": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "9225:6:12" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "9233:2:12" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "9221:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "9221:15:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "9194:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "9194:43:12" + }, + "nodeType": "YulExpressionStatement", + "src": "9194:43:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9257:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9268:2:12", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9253:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "9253:18:12" + }, + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "9273:6:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "9246:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "9246:34:12" + }, + "nodeType": "YulExpressionStatement", + "src": "9246:34:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9300:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9311:3:12", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9296:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "9296:19:12" + }, + { + "name": "value4", + "nodeType": "YulIdentifier", + "src": "9317:6:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "9289:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "9289:35:12" + }, + "nodeType": "YulExpressionStatement", + "src": "9289:35:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9344:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9355:3:12", + "type": "", + "value": "160" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9340:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "9340:19:12" + }, + { + "arguments": [ + { + "name": "value5", + "nodeType": "YulIdentifier", + "src": "9365:6:12" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "9373:2:12" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "9361:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "9361:15:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "9333:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "9333:44:12" + }, + "nodeType": "YulExpressionStatement", + "src": "9333:44:12" + } + ] + }, + "name": "abi_encode_tuple_t_bytes32_t_bytes32_t_address_t_bytes32_t_bytes32_t_address__to_t_bytes32_t_bytes32_t_address_t_bytes32_t_bytes32_t_address__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "8939:9:12", + "type": "" + }, + { + "name": "value5", + "nodeType": "YulTypedName", + "src": "8950:6:12", + "type": "" + }, + { + "name": "value4", + "nodeType": "YulTypedName", + "src": "8958:6:12", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "8966:6:12", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "8974:6:12", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "8982:6:12", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "8990:6:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "9001:4:12", + "type": "" + } + ], + "src": "8769:614:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "9507:100:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9524:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9535:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "9517:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "9517:21:12" + }, + "nodeType": "YulExpressionStatement", + "src": "9517:21:12" + }, + { + "nodeType": "YulAssignment", + "src": "9547:54:12", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "9574:6:12" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9586:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9597:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9582:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "9582:18:12" + } + ], + "functionName": { + "name": "abi_encode_t_bytes", + "nodeType": "YulIdentifier", + "src": "9555:18:12" + }, + "nodeType": "YulFunctionCall", + "src": "9555:46:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "9547:4:12" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "9476:9:12", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "9487:6:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "9498:4:12", + "type": "" + } + ], + "src": "9388:219:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "9728:108:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9745:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9756:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "9738:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "9738:21:12" + }, + "nodeType": "YulExpressionStatement", + "src": "9738:21:12" + }, + { + "nodeType": "YulAssignment", + "src": "9768:62:12", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "9803:6:12" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9815:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9826:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9811:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "9811:18:12" + } + ], + "functionName": { + "name": "abi_encode_t_bytes_storage", + "nodeType": "YulIdentifier", + "src": "9776:26:12" + }, + "nodeType": "YulFunctionCall", + "src": "9776:54:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "9768:4:12" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_bytes_storage__to_t_bytes_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "9697:9:12", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "9708:6:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "9719:4:12", + "type": "" + } + ], + "src": "9612:224:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "9962:125:12", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "9972:26:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9984:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9995:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9980:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "9980:18:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "9972:4:12" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10014:9:12" + }, + { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "10029:6:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10037:42:12", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "10025:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "10025:55:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10007:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "10007:74:12" + }, + "nodeType": "YulExpressionStatement", + "src": "10007:74:12" + } + ] + }, + "name": "abi_encode_tuple_t_contract$_IArbitrator_$1847__to_t_address__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "9931:9:12", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "9942:6:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "9953:4:12", + "type": "" + } + ], + "src": "9841:246:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "10284:302:12", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "10294:27:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10306:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10317:3:12", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10302:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "10302:19:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "10294:4:12" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "10355:13:12", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "invalid", + "nodeType": "YulIdentifier", + "src": "10357:7:12" + }, + "nodeType": "YulFunctionCall", + "src": "10357:9:12" + }, + "nodeType": "YulExpressionStatement", + "src": "10357:9:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "10343:6:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10351:1:12", + "type": "", + "value": "4" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "10340:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "10340:13:12" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "10333:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "10333:21:12" + }, + "nodeType": "YulIf", + "src": "10330:2:12" + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10384:9:12" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "10395:6:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10377:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "10377:25:12" + }, + "nodeType": "YulExpressionStatement", + "src": "10377:25:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10422:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10433:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10418:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "10418:18:12" + }, + { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "10442:6:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10450:42:12", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "10438:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "10438:55:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10411:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "10411:83:12" + }, + "nodeType": "YulExpressionStatement", + "src": "10411:83:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10514:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10525:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10510:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "10510:18:12" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "10530:6:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10503:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "10503:34:12" + }, + "nodeType": "YulExpressionStatement", + "src": "10503:34:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10557:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10568:2:12", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10553:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "10553:18:12" + }, + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "10573:6:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10546:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "10546:34:12" + }, + "nodeType": "YulExpressionStatement", + "src": "10546:34:12" + } + ] + }, + "name": "abi_encode_tuple_t_enum$_Status_$95_t_address_t_uint256_t_uint256__to_t_uint8_t_address_t_uint256_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "10229:9:12", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "10240:6:12", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "10248:6:12", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "10256:6:12", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "10264:6:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "10275:4:12", + "type": "" + } + ], + "src": "10092:494:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "10722:321:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10739:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10750:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10732:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "10732:21:12" + }, + "nodeType": "YulExpressionStatement", + "src": "10732:21:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10773:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10784:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10769:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "10769:18:12" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "10789:6:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10762:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "10762:34:12" + }, + "nodeType": "YulExpressionStatement", + "src": "10762:34:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10822:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10833:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10818:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "10818:18:12" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "10838:6:12" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "10846:6:12" + } + ], + "functionName": { + "name": "calldatacopy", + "nodeType": "YulIdentifier", + "src": "10805:12:12" + }, + "nodeType": "YulFunctionCall", + "src": "10805:48:12" + }, + "nodeType": "YulExpressionStatement", + "src": "10805:48:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10877:9:12" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "10888:6:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10873:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "10873:22:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10897:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10869:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "10869:31:12" + }, + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "10902:4:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10862:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "10862:45:12" + }, + "nodeType": "YulExpressionStatement", + "src": "10862:45:12" + }, + { + "nodeType": "YulAssignment", + "src": "10916:121:12", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10932:9:12" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "10951:6:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10959:2:12", + "type": "", + "value": "31" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10947:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "10947:15:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10964:66:12", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "10943:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "10943:88:12" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10928:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "10928:104:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11034:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10924:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "10924:113:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "10916:4:12" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_string_calldata_ptr__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "10683:9:12", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "10694:6:12", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "10702:6:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "10713:4:12", + "type": "" + } + ], + "src": "10591:452:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "11169:100:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11186:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11197:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11179:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "11179:21:12" + }, + "nodeType": "YulExpressionStatement", + "src": "11179:21:12" + }, + { + "nodeType": "YulAssignment", + "src": "11209:54:12", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "11236:6:12" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11248:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11259:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11244:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "11244:18:12" + } + ], + "functionName": { + "name": "abi_encode_t_bytes", + "nodeType": "YulIdentifier", + "src": "11217:18:12" + }, + "nodeType": "YulFunctionCall", + "src": "11217:46:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "11209:4:12" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "11138:9:12", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "11149:6:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "11160:4:12", + "type": "" + } + ], + "src": "11048:221:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "11448:236:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11465:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11476:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11458:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "11458:21:12" + }, + "nodeType": "YulExpressionStatement", + "src": "11458:21:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11499:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11510:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11495:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "11495:18:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11515:2:12", + "type": "", + "value": "46" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11488:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "11488:30:12" + }, + "nodeType": "YulExpressionStatement", + "src": "11488:30:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11538:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11549:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11534:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "11534:18:12" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "11554:34:12", + "type": "", + "value": "Funding must be made within the " + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11527:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "11527:62:12" + }, + "nodeType": "YulExpressionStatement", + "src": "11527:62:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11609:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11620:2:12", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11605:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "11605:18:12" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "11625:16:12", + "type": "", + "value": "appeal period." + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11598:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "11598:44:12" + }, + "nodeType": "YulExpressionStatement", + "src": "11598:44:12" + }, + { + "nodeType": "YulAssignment", + "src": "11651:27:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11663:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11674:3:12", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11659:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "11659:19:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "11651:4:12" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_0345b6b07b3f7ea23ce7c0682ae193a7b3933d232b736d656630025e0007450f__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "11425:9:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "11439:4:12", + "type": "" + } + ], + "src": "11274:410:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "11863:173:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11880:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11891:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11873:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "11873:21:12" + }, + "nodeType": "YulExpressionStatement", + "src": "11873:21:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11914:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11925:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11910:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "11910:18:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11930:2:12", + "type": "", + "value": "23" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11903:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "11903:30:12" + }, + "nodeType": "YulExpressionStatement", + "src": "11903:30:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11953:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11964:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11949:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "11949:18:12" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "11969:25:12", + "type": "", + "value": "Only arbitrator allowed" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11942:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "11942:53:12" + }, + "nodeType": "YulExpressionStatement", + "src": "11942:53:12" + }, + { + "nodeType": "YulAssignment", + "src": "12004:26:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12016:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12027:2:12", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12012:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "12012:18:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "12004:4:12" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_1587ae476a4c91cb27e60192a738172f2d3bd86eda002a76489557322fbcd606__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "11840:9:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "11854:4:12", + "type": "" + } + ], + "src": "11689:347:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "12215:179:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12232:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12243:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12225:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "12225:21:12" + }, + "nodeType": "YulExpressionStatement", + "src": "12225:21:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12266:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12277:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12262:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "12262:18:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12282:2:12", + "type": "", + "value": "29" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12255:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "12255:30:12" + }, + "nodeType": "YulExpressionStatement", + "src": "12255:30:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12305:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12316:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12301:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "12301:18:12" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "12321:31:12", + "type": "", + "value": "Arbitration already requested" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12294:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "12294:59:12" + }, + "nodeType": "YulExpressionStatement", + "src": "12294:59:12" + }, + { + "nodeType": "YulAssignment", + "src": "12362:26:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12374:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12385:2:12", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12370:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "12370:18:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "12362:4:12" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_55423884b287f9932d36a37128861bfbe4d8feea42af3dd3ab8bbf80c9ba5cb7__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "12192:9:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "12206:4:12", + "type": "" + } + ], + "src": "12041:353:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "12573:164:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12590:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12601:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12583:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "12583:21:12" + }, + "nodeType": "YulExpressionStatement", + "src": "12583:21:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12624:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12635:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12620:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "12620:18:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12640:2:12", + "type": "", + "value": "14" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12613:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "12613:30:12" + }, + "nodeType": "YulExpressionStatement", + "src": "12613:30:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12663:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12674:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12659:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "12659:18:12" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "12679:16:12", + "type": "", + "value": "Invalid ruling" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12652:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "12652:44:12" + }, + "nodeType": "YulExpressionStatement", + "src": "12652:44:12" + }, + { + "nodeType": "YulAssignment", + "src": "12705:26:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12717:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12728:2:12", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12713:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "12713:18:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "12705:4:12" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_7a8ecda55f6cca96c1978f4fd25ea15366a0d0c7eef1b0ddd6bb2039bf48c978__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "12550:9:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "12564:4:12", + "type": "" + } + ], + "src": "12399:338:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "12916:177:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12933:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12944:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12926:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "12926:21:12" + }, + "nodeType": "YulExpressionStatement", + "src": "12926:21:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12967:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12978:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12963:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "12963:18:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12983:2:12", + "type": "", + "value": "27" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12956:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "12956:30:12" + }, + "nodeType": "YulExpressionStatement", + "src": "12956:30:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13006:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13017:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13002:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "13002:18:12" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "13022:29:12", + "type": "", + "value": "The status should be Ruled." + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12995:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "12995:57:12" + }, + "nodeType": "YulExpressionStatement", + "src": "12995:57:12" + }, + { + "nodeType": "YulAssignment", + "src": "13061:26:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13073:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13084:2:12", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13069:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "13069:18:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "13061:4:12" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_7b12e68595b54b95620c01e48f1dc5573a4c5ef17b89e01ed1eb1d416d772095__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "12893:9:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "12907:4:12", + "type": "" + } + ], + "src": "12742:351:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "13272:181:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13289:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13300:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13282:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "13282:21:12" + }, + "nodeType": "YulExpressionStatement", + "src": "13282:21:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13323:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13334:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13319:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "13319:18:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13339:2:12", + "type": "", + "value": "31" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13312:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "13312:30:12" + }, + "nodeType": "YulExpressionStatement", + "src": "13312:30:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13362:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13373:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13358:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "13358:18:12" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "13378:33:12", + "type": "", + "value": "Only governor can execute this." + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13351:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "13351:61:12" + }, + "nodeType": "YulExpressionStatement", + "src": "13351:61:12" + }, + { + "nodeType": "YulAssignment", + "src": "13421:26:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13433:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13444:2:12", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13429:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "13429:18:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "13421:4:12" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_7f704123736d1b3a92e260c8141259bdf1f9f67d73c4011b0e241b32535a29c0__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "13249:9:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "13263:4:12", + "type": "" + } + ], + "src": "13098:355:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "13632:173:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13649:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13660:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13642:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "13642:21:12" + }, + "nodeType": "YulExpressionStatement", + "src": "13642:21:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13683:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13694:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13679:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "13679:18:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13699:2:12", + "type": "", + "value": "23" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13672:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "13672:30:12" + }, + "nodeType": "YulExpressionStatement", + "src": "13672:30:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13722:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13733:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13718:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "13718:18:12" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "13738:25:12", + "type": "", + "value": "Answer is out of bounds" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13711:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "13711:53:12" + }, + "nodeType": "YulExpressionStatement", + "src": "13711:53:12" + }, + { + "nodeType": "YulAssignment", + "src": "13773:26:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13785:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13796:2:12", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13781:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "13781:18:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "13773:4:12" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_807f252b41bd7d25b9b54c1160c4b1e87b4c73129edc3c10cb4da24c4632a9c3__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "13609:9:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "13623:4:12", + "type": "" + } + ], + "src": "13458:347:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "13984:173:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14001:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14012:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13994:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "13994:21:12" + }, + "nodeType": "YulExpressionStatement", + "src": "13994:21:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14035:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14046:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14031:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "14031:18:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14051:2:12", + "type": "", + "value": "23" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "14024:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "14024:30:12" + }, + "nodeType": "YulExpressionStatement", + "src": "14024:30:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14074:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14085:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14070:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "14070:18:12" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "14090:25:12", + "type": "", + "value": "There is no ruling yet." + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "14063:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "14063:53:12" + }, + "nodeType": "YulExpressionStatement", + "src": "14063:53:12" + }, + { + "nodeType": "YulAssignment", + "src": "14125:26:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14137:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14148:2:12", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14133:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "14133:18:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "14125:4:12" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_9591a49cf5d9e3ba9b3aea5505a2b8a639d2f239a0cb6a9059466b60c54a080f__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "13961:9:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "13975:4:12", + "type": "" + } + ], + "src": "13810:347:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "14336:171:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14353:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14364:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "14346:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "14346:21:12" + }, + "nodeType": "YulExpressionStatement", + "src": "14346:21:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14387:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14398:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14383:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "14383:18:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14403:2:12", + "type": "", + "value": "21" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "14376:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "14376:30:12" + }, + "nodeType": "YulExpressionStatement", + "src": "14376:30:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14426:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14437:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14422:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "14422:18:12" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "14442:23:12", + "type": "", + "value": "No dispute to appeal." + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "14415:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "14415:51:12" + }, + "nodeType": "YulExpressionStatement", + "src": "14415:51:12" + }, + { + "nodeType": "YulAssignment", + "src": "14475:26:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14487:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14498:2:12", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14483:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "14483:18:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "14475:4:12" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_977851d5d407d7cd7d94a1de96a1bef813f7600043d5e83553db2bd20019e46d__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "14313:9:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "14327:4:12", + "type": "" + } + ], + "src": "14162:345:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "14686:179:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14703:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14714:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "14696:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "14696:21:12" + }, + "nodeType": "YulExpressionStatement", + "src": "14696:21:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14737:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14748:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14733:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "14733:18:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14753:2:12", + "type": "", + "value": "29" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "14726:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "14726:30:12" + }, + "nodeType": "YulExpressionStatement", + "src": "14726:30:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14776:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14787:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14772:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "14772:18:12" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "14792:31:12", + "type": "", + "value": "There is no metaevidence yet." + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "14765:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "14765:59:12" + }, + "nodeType": "YulExpressionStatement", + "src": "14765:59:12" + }, + { + "nodeType": "YulAssignment", + "src": "14833:26:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14845:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14856:2:12", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14841:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "14841:18:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "14833:4:12" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_aa7d933803aa49666b2a880b5e0ce2616fb839013df37734e6f96b996f511bfc__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "14663:9:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "14677:4:12", + "type": "" + } + ], + "src": "14512:353:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "15044:223:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15061:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15072:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15054:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "15054:21:12" + }, + "nodeType": "YulExpressionStatement", + "src": "15054:21:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15095:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15106:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15091:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "15091:18:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15111:2:12", + "type": "", + "value": "33" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15084:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "15084:30:12" + }, + "nodeType": "YulExpressionStatement", + "src": "15084:30:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15134:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15145:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15130:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "15130:18:12" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "15150:34:12", + "type": "", + "value": "Appeal fee has already been paid" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15123:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "15123:62:12" + }, + "nodeType": "YulExpressionStatement", + "src": "15123:62:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15205:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15216:2:12", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15201:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "15201:18:12" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "15221:3:12", + "type": "", + "value": "." + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15194:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "15194:31:12" + }, + "nodeType": "YulExpressionStatement", + "src": "15194:31:12" + }, + { + "nodeType": "YulAssignment", + "src": "15234:27:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15246:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15257:3:12", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15242:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "15242:19:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "15234:4:12" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_c2f2256a77e1cd7cdc564a3b966df4f3e5bfbdc15f00156637ffbff138e529be__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "15021:9:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "15035:4:12", + "type": "" + } + ], + "src": "14870:397:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "15446:235:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15463:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15474:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15456:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "15456:21:12" + }, + "nodeType": "YulExpressionStatement", + "src": "15456:21:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15497:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15508:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15493:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "15493:18:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15513:2:12", + "type": "", + "value": "45" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15486:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "15486:30:12" + }, + "nodeType": "YulExpressionStatement", + "src": "15486:30:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15536:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15547:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15532:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "15532:18:12" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "15552:34:12", + "type": "", + "value": "Cannot submit evidence to a reso" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15525:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "15525:62:12" + }, + "nodeType": "YulExpressionStatement", + "src": "15525:62:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15607:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15618:2:12", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15603:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "15603:18:12" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "15623:15:12", + "type": "", + "value": "lved dispute." + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15596:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "15596:43:12" + }, + "nodeType": "YulExpressionStatement", + "src": "15596:43:12" + }, + { + "nodeType": "YulAssignment", + "src": "15648:27:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15660:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15671:3:12", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15656:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "15656:19:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "15648:4:12" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_ca4412daad1a7629a806d6ed5fb65348818aea0846591a9cf2015068ce96fd51__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "15423:9:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "15437:4:12", + "type": "" + } + ], + "src": "15272:409:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "15860:176:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15877:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15888:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15870:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "15870:21:12" + }, + "nodeType": "YulExpressionStatement", + "src": "15870:21:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15911:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15922:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15907:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "15907:18:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15927:2:12", + "type": "", + "value": "26" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15900:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "15900:30:12" + }, + "nodeType": "YulExpressionStatement", + "src": "15900:30:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15950:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15961:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15946:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "15946:18:12" + }, + { + "kind": "string", + "nodeType": "YulLiteral", + "src": "15966:28:12", + "type": "", + "value": "Invalid arbitration status" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15939:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "15939:56:12" + }, + "nodeType": "YulExpressionStatement", + "src": "15939:56:12" + }, + { + "nodeType": "YulAssignment", + "src": "16004:26:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16016:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16027:2:12", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16012:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "16012:18:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "16004:4:12" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_eff7a83c06f307332f22e019405c9ddb8a5159f654bea9234a3c2d855632b2b1__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "15837:9:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "15851:4:12", + "type": "" + } + ], + "src": "15686:350:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "16142:76:12", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "16152:26:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16164:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16175:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16160:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "16160:18:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "16152:4:12" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16194:9:12" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "16205:6:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16187:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "16187:25:12" + }, + "nodeType": "YulExpressionStatement", + "src": "16187:25:12" + } + ] + }, + "name": "abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "16111:9:12", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "16122:6:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "16133:4:12", + "type": "" + } + ], + "src": "16041:177:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "16367:151:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16384:9:12" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "16395:6:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16377:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "16377:25:12" + }, + "nodeType": "YulExpressionStatement", + "src": "16377:25:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16422:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16433:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16418:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "16418:18:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16438:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16411:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "16411:30:12" + }, + "nodeType": "YulExpressionStatement", + "src": "16411:30:12" + }, + { + "nodeType": "YulAssignment", + "src": "16450:62:12", + "value": { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "16485:6:12" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16497:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16508:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16493:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "16493:18:12" + } + ], + "functionName": { + "name": "abi_encode_t_bytes_storage", + "nodeType": "YulIdentifier", + "src": "16458:26:12" + }, + "nodeType": "YulFunctionCall", + "src": "16458:54:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "16450:4:12" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_uint256_t_bytes_storage__to_t_uint256_t_bytes_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "16328:9:12", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "16339:6:12", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "16347:6:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "16358:4:12", + "type": "" + } + ], + "src": "16223:295:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "16652:119:12", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "16662:26:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16674:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16685:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16670:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "16670:18:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "16662:4:12" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16704:9:12" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "16715:6:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16697:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "16697:25:12" + }, + "nodeType": "YulExpressionStatement", + "src": "16697:25:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16742:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16753:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16738:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "16738:18:12" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "16758:6:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16731:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "16731:34:12" + }, + "nodeType": "YulExpressionStatement", + "src": "16731:34:12" + } + ] + }, + "name": "abi_encode_tuple_t_uint256_t_uint256__to_t_uint256_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "16613:9:12", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "16624:6:12", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "16632:6:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "16643:4:12", + "type": "" + } + ], + "src": "16523:248:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "16961:206:12", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "16971:27:12", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16983:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16994:3:12", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16979:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "16979:19:12" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "16971:4:12" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17014:9:12" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "17025:6:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17007:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "17007:25:12" + }, + "nodeType": "YulExpressionStatement", + "src": "17007:25:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17052:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17063:2:12", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17048:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "17048:18:12" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "17068:6:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17041:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "17041:34:12" + }, + "nodeType": "YulExpressionStatement", + "src": "17041:34:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17095:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17106:2:12", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17091:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "17091:18:12" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "17111:6:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17084:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "17084:34:12" + }, + "nodeType": "YulExpressionStatement", + "src": "17084:34:12" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17138:9:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17149:2:12", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17134:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "17134:18:12" + }, + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "17154:6:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17127:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "17127:34:12" + }, + "nodeType": "YulExpressionStatement", + "src": "17127:34:12" + } + ] + }, + "name": "abi_encode_tuple_t_uint256_t_uint256_t_uint256_t_uint256__to_t_uint256_t_uint256_t_uint256_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "16906:9:12", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "16917:6:12", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "16925:6:12", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "16933:6:12", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "16941:6:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "16952:4:12", + "type": "" + } + ], + "src": "16776:391:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "17229:71:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "data", + "nodeType": "YulIdentifier", + "src": "17246:4:12" + }, + { + "name": "ptr", + "nodeType": "YulIdentifier", + "src": "17252:3:12" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17239:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "17239:17:12" + }, + "nodeType": "YulExpressionStatement", + "src": "17239:17:12" + }, + { + "nodeType": "YulAssignment", + "src": "17265:29:12", + "value": { + "arguments": [ + { + "name": "data", + "nodeType": "YulIdentifier", + "src": "17283:4:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17289:4:12", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "keccak256", + "nodeType": "YulIdentifier", + "src": "17273:9:12" + }, + "nodeType": "YulFunctionCall", + "src": "17273:21:12" + }, + "variableNames": [ + { + "name": "data", + "nodeType": "YulIdentifier", + "src": "17265:4:12" + } + ] + } + ] + }, + "name": "array_dataslot_t_bytes_storage", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "ptr", + "nodeType": "YulTypedName", + "src": "17212:3:12", + "type": "" + } + ], + "returnVariables": [ + { + "name": "data", + "nodeType": "YulTypedName", + "src": "17220:4:12", + "type": "" + } + ], + "src": "17172:128:12" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "17352:109:12", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "17439:16:12", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17448:1:12", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17451:1:12", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "17441:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "17441:12:12" + }, + "nodeType": "YulExpressionStatement", + "src": "17441:12:12" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "17375:5:12" + }, + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "17386:5:12" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17393:42:12", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "17382:3:12" + }, + "nodeType": "YulFunctionCall", + "src": "17382:54:12" + } + ], + "functionName": { + "name": "eq", + "nodeType": "YulIdentifier", + "src": "17372:2:12" + }, + "nodeType": "YulFunctionCall", + "src": "17372:65:12" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "17365:6:12" + }, + "nodeType": "YulFunctionCall", + "src": "17365:73:12" + }, + "nodeType": "YulIf", + "src": "17362:2:12" + } + ] + }, + "name": "validator_revert_t_address", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "17341:5:12", + "type": "" + } + ], + "src": "17305:156:12" + } + ] + }, + "contents": "{\n { }\n function abi_decode_t_array$_t_uint256_$dyn(offset, end) -> array\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(array, array) }\n let _1 := calldataload(offset)\n let _2 := 0x20\n let _3 := 0xffffffffffffffff\n if gt(_1, _3) { invalid() }\n let _4 := mul(_1, _2)\n let memPtr := mload(64)\n let newFreePtr := add(add(memPtr, _4), _2)\n if or(gt(newFreePtr, _3), lt(newFreePtr, memPtr)) { invalid() }\n mstore(64, newFreePtr)\n let dst := memPtr\n mstore(memPtr, _1)\n dst := add(memPtr, _2)\n let src := add(offset, _2)\n if gt(add(add(offset, _4), _2), end) { revert(array, array) }\n let i := array\n for { } lt(i, _1) { i := add(i, 1) }\n {\n mstore(dst, calldataload(src))\n dst := add(dst, _2)\n src := add(src, _2)\n }\n array := memPtr\n }\n function abi_decode_t_string_calldata(offset, end) -> arrayPos, length\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(arrayPos, arrayPos) }\n length := calldataload(offset)\n if gt(length, 0xffffffffffffffff) { revert(arrayPos, arrayPos) }\n arrayPos := add(offset, 0x20)\n if gt(add(add(offset, length), 0x20), end) { revert(0, 0) }\n }\n function abi_decode_tuple_t_address(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(value0, value0) }\n let value := calldataload(headStart)\n validator_revert_t_address(value)\n value0 := value\n }\n function abi_decode_tuple_t_bytes32(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(value0, value0) }\n value0 := calldataload(headStart)\n }\n function abi_decode_tuple_t_bytes32t_bytes32t_bytes32t_address(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 128) { revert(value1, value1) }\n value0 := calldataload(headStart)\n value1 := calldataload(add(headStart, 32))\n value2 := calldataload(add(headStart, 64))\n let value := calldataload(add(headStart, 96))\n validator_revert_t_address(value)\n value3 := value\n }\n function abi_decode_tuple_t_bytes32t_uint256(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(value0, value0) }\n value0 := calldataload(headStart)\n value1 := calldataload(add(headStart, 32))\n }\n function abi_decode_tuple_t_string_calldata_ptr(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 32) { revert(value0, value0) }\n let offset := calldataload(headStart)\n if gt(offset, 0xffffffffffffffff) { revert(value0, value0) }\n let value0_1, value1_1 := abi_decode_t_string_calldata(add(headStart, offset), dataEnd)\n value0 := value0_1\n value1 := value1_1\n }\n function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(value0, value0) }\n value0 := calldataload(headStart)\n }\n function abi_decode_tuple_t_uint256_fromMemory(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(value0, value0) }\n value0 := mload(headStart)\n }\n function abi_decode_tuple_t_uint256t_address_payablet_array$_t_uint256_$dyn_memory_ptr(headStart, dataEnd) -> value0, value1, value2\n {\n if slt(sub(dataEnd, headStart), 96) { revert(value0, value0) }\n value0 := calldataload(headStart)\n let value := calldataload(add(headStart, 32))\n validator_revert_t_address(value)\n value1 := value\n let offset := calldataload(add(headStart, 64))\n if gt(offset, 0xffffffffffffffff) { revert(value2, value2) }\n value2 := abi_decode_t_array$_t_uint256_$dyn(add(headStart, offset), dataEnd)\n }\n function abi_decode_tuple_t_uint256t_address_payablet_uint256t_array$_t_uint256_$dyn_memory_ptr(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 128) { revert(value0, value0) }\n value0 := calldataload(headStart)\n let value := calldataload(add(headStart, 32))\n validator_revert_t_address(value)\n value1 := value\n value2 := calldataload(add(headStart, 64))\n let offset := calldataload(add(headStart, 96))\n if gt(offset, 0xffffffffffffffff) { revert(value3, value3) }\n value3 := abi_decode_t_array$_t_uint256_$dyn(add(headStart, offset), dataEnd)\n }\n function abi_decode_tuple_t_uint256t_address_payablet_uint256t_uint256(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 128) { revert(value0, value0) }\n value0 := calldataload(headStart)\n let value := calldataload(add(headStart, 32))\n validator_revert_t_address(value)\n value1 := value\n value2 := calldataload(add(headStart, 64))\n value3 := calldataload(add(headStart, 96))\n }\n function abi_decode_tuple_t_uint256t_string_calldata_ptr(headStart, dataEnd) -> value0, value1, value2\n {\n if slt(sub(dataEnd, headStart), 64) { revert(value0, value0) }\n value0 := calldataload(headStart)\n let offset := calldataload(add(headStart, 32))\n if gt(offset, 0xffffffffffffffff) { revert(value1, value1) }\n let value1_1, value2_1 := abi_decode_t_string_calldata(add(headStart, offset), dataEnd)\n value1 := value1_1\n value2 := value2_1\n }\n function abi_decode_tuple_t_uint256t_uint256(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(value0, value0) }\n value0 := calldataload(headStart)\n value1 := calldataload(add(headStart, 32))\n }\n function abi_decode_tuple_t_uint256t_uint256_fromMemory(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(value0, value0) }\n value0 := mload(headStart)\n value1 := mload(add(headStart, 32))\n }\n function abi_decode_tuple_t_uint256t_uint256t_uint256(headStart, dataEnd) -> value0, value1, value2\n {\n if slt(sub(dataEnd, headStart), 96) { revert(value2, value2) }\n value0 := calldataload(headStart)\n value1 := calldataload(add(headStart, 32))\n value2 := calldataload(add(headStart, 64))\n }\n function abi_encode_t_bytes(value, pos) -> end\n {\n let length := mload(value)\n mstore(pos, length)\n let i := end\n for { } lt(i, length) { i := add(i, 0x20) }\n {\n let _1 := 0x20\n mstore(add(add(pos, i), _1), mload(add(add(value, i), _1)))\n }\n if gt(i, length)\n {\n mstore(add(add(pos, length), 0x20), end)\n }\n end := add(add(pos, and(add(length, 31), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0)), 0x20)\n }\n function abi_encode_t_bytes_storage(value, pos) -> ret\n {\n let slotValue := sload(value)\n let _1 := 1\n switch and(slotValue, _1)\n case 0 {\n mstore(pos, and(div(slotValue, 2), 0x7f))\n mstore(add(pos, 0x20), and(slotValue, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00))\n ret := add(pos, 64)\n }\n case 1 {\n let length := div(slotValue, 2)\n mstore(pos, length)\n let dataPos := array_dataslot_t_bytes_storage(value)\n let i := 0\n for { } lt(i, length) { i := add(i, 0x20) }\n {\n mstore(add(add(pos, i), 0x20), sload(dataPos))\n dataPos := add(dataPos, _1)\n }\n ret := add(add(pos, i), 0x20)\n }\n }\n function abi_encode_tuple_t_address__to_t_address__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, 0xffffffffffffffffffffffffffffffffffffffff))\n }\n function abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, iszero(iszero(value0)))\n }\n function abi_encode_tuple_t_bytes32__to_t_bytes32__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, value0)\n }\n function abi_encode_tuple_t_bytes32_t_address_payable_t_uint256__to_t_bytes32_t_address_t_uint256__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n tail := add(headStart, 96)\n mstore(headStart, value0)\n mstore(add(headStart, 32), and(value1, 0xffffffffffffffffffffffffffffffffffffffff))\n mstore(add(headStart, 64), value2)\n }\n function abi_encode_tuple_t_bytes32_t_bytes32_t_address_t_bytes32_t_bytes32_t_address__to_t_bytes32_t_bytes32_t_address_t_bytes32_t_bytes32_t_address__fromStack_reversed(headStart, value5, value4, value3, value2, value1, value0) -> tail\n {\n tail := add(headStart, 192)\n mstore(headStart, value0)\n mstore(add(headStart, 32), value1)\n let _1 := 0xffffffffffffffffffffffffffffffffffffffff\n mstore(add(headStart, 64), and(value2, _1))\n mstore(add(headStart, 96), value3)\n mstore(add(headStart, 128), value4)\n mstore(add(headStart, 160), and(value5, _1))\n }\n function abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed(headStart, value0) -> tail\n {\n mstore(headStart, 32)\n tail := abi_encode_t_bytes(value0, add(headStart, 32))\n }\n function abi_encode_tuple_t_bytes_storage__to_t_bytes_memory_ptr__fromStack_reversed(headStart, value0) -> tail\n {\n mstore(headStart, 32)\n tail := abi_encode_t_bytes_storage(value0, add(headStart, 32))\n }\n function abi_encode_tuple_t_contract$_IArbitrator_$1847__to_t_address__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, 0xffffffffffffffffffffffffffffffffffffffff))\n }\n function abi_encode_tuple_t_enum$_Status_$95_t_address_t_uint256_t_uint256__to_t_uint8_t_address_t_uint256_t_uint256__fromStack_reversed(headStart, value3, value2, value1, value0) -> tail\n {\n tail := add(headStart, 128)\n if iszero(lt(value0, 4)) { invalid() }\n mstore(headStart, value0)\n mstore(add(headStart, 32), and(value1, 0xffffffffffffffffffffffffffffffffffffffff))\n mstore(add(headStart, 64), value2)\n mstore(add(headStart, 96), value3)\n }\n function abi_encode_tuple_t_string_calldata_ptr__to_t_string_memory_ptr__fromStack_reversed(headStart, value1, value0) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), value1)\n calldatacopy(add(headStart, 64), value0, value1)\n mstore(add(add(headStart, value1), 64), tail)\n tail := add(add(headStart, and(add(value1, 31), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0)), 64)\n }\n function abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack_reversed(headStart, value0) -> tail\n {\n mstore(headStart, 32)\n tail := abi_encode_t_bytes(value0, add(headStart, 32))\n }\n function abi_encode_tuple_t_stringliteral_0345b6b07b3f7ea23ce7c0682ae193a7b3933d232b736d656630025e0007450f__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 46)\n mstore(add(headStart, 64), \"Funding must be made within the \")\n mstore(add(headStart, 96), \"appeal period.\")\n tail := add(headStart, 128)\n }\n function abi_encode_tuple_t_stringliteral_1587ae476a4c91cb27e60192a738172f2d3bd86eda002a76489557322fbcd606__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 23)\n mstore(add(headStart, 64), \"Only arbitrator allowed\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_55423884b287f9932d36a37128861bfbe4d8feea42af3dd3ab8bbf80c9ba5cb7__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 29)\n mstore(add(headStart, 64), \"Arbitration already requested\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_7a8ecda55f6cca96c1978f4fd25ea15366a0d0c7eef1b0ddd6bb2039bf48c978__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 14)\n mstore(add(headStart, 64), \"Invalid ruling\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_7b12e68595b54b95620c01e48f1dc5573a4c5ef17b89e01ed1eb1d416d772095__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 27)\n mstore(add(headStart, 64), \"The status should be Ruled.\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_7f704123736d1b3a92e260c8141259bdf1f9f67d73c4011b0e241b32535a29c0__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 31)\n mstore(add(headStart, 64), \"Only governor can execute this.\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_807f252b41bd7d25b9b54c1160c4b1e87b4c73129edc3c10cb4da24c4632a9c3__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 23)\n mstore(add(headStart, 64), \"Answer is out of bounds\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_9591a49cf5d9e3ba9b3aea5505a2b8a639d2f239a0cb6a9059466b60c54a080f__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 23)\n mstore(add(headStart, 64), \"There is no ruling yet.\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_977851d5d407d7cd7d94a1de96a1bef813f7600043d5e83553db2bd20019e46d__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 21)\n mstore(add(headStart, 64), \"No dispute to appeal.\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_aa7d933803aa49666b2a880b5e0ce2616fb839013df37734e6f96b996f511bfc__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 29)\n mstore(add(headStart, 64), \"There is no metaevidence yet.\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_c2f2256a77e1cd7cdc564a3b966df4f3e5bfbdc15f00156637ffbff138e529be__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 33)\n mstore(add(headStart, 64), \"Appeal fee has already been paid\")\n mstore(add(headStart, 96), \".\")\n tail := add(headStart, 128)\n }\n function abi_encode_tuple_t_stringliteral_ca4412daad1a7629a806d6ed5fb65348818aea0846591a9cf2015068ce96fd51__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 45)\n mstore(add(headStart, 64), \"Cannot submit evidence to a reso\")\n mstore(add(headStart, 96), \"lved dispute.\")\n tail := add(headStart, 128)\n }\n function abi_encode_tuple_t_stringliteral_eff7a83c06f307332f22e019405c9ddb8a5159f654bea9234a3c2d855632b2b1__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 26)\n mstore(add(headStart, 64), \"Invalid arbitration status\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, value0)\n }\n function abi_encode_tuple_t_uint256_t_bytes_storage__to_t_uint256_t_bytes_memory_ptr__fromStack_reversed(headStart, value1, value0) -> tail\n {\n mstore(headStart, value0)\n mstore(add(headStart, 32), 64)\n tail := abi_encode_t_bytes_storage(value1, add(headStart, 64))\n }\n function abi_encode_tuple_t_uint256_t_uint256__to_t_uint256_t_uint256__fromStack_reversed(headStart, value1, value0) -> tail\n {\n tail := add(headStart, 64)\n mstore(headStart, value0)\n mstore(add(headStart, 32), value1)\n }\n function abi_encode_tuple_t_uint256_t_uint256_t_uint256_t_uint256__to_t_uint256_t_uint256_t_uint256_t_uint256__fromStack_reversed(headStart, value3, value2, value1, value0) -> tail\n {\n tail := add(headStart, 128)\n mstore(headStart, value0)\n mstore(add(headStart, 32), value1)\n mstore(add(headStart, 64), value2)\n mstore(add(headStart, 96), value3)\n }\n function array_dataslot_t_bytes_storage(ptr) -> data\n {\n mstore(data, ptr)\n data := keccak256(data, 0x20)\n }\n function validator_revert_t_address(value)\n {\n if iszero(eq(value, and(value, 0xffffffffffffffffffffffffffffffffffffffff))) { revert(0, 0) }\n }\n}", + "id": 12, + "language": "Yul", + "name": "#utility.yul" + } + ], + "sourceMap": "1135:2191:6:-:0;;;1879:36:2;;;-1:-1:-1;;;;;;1879:36:2;1905:10;1879:36;;;2479:4;2440:43;;2634:4;2596:42;;2795:4;2750:49;;1557:247:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6169:20:2;-1:-1:-1;;;;;6169:20:2;;;;;6199;;1745:9:6;;1756;;1767:11;;1780:20;;6199::2;;:8;;:20;;;;;:::i;:::-;-1:-1:-1;6229:24:2;-1:-1:-1;;;;;6229:24:2;;;;;6263:42;;;;:19;;:42;;;;;:::i;:::-;;6005:307;;;;1557:247:6;;;;1135:2191;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1135:2191:6;;;-1:-1:-1;1135:2191:6;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:768:12;;-1:-1:-1;;;;;162:2:12;154:6;151:14;148:2;;;168:9;148:2;208;202:9;230:4;304:2;281:17;;-1:-1:-1;;277:31:12;265:44;;261:53;;329:18;;;349:22;;;326:46;323:2;;;375:9;323:2;406:10;402:2;395:22;;435:6;426:15;;465:6;457;450:22;505:3;496:6;491:3;487:16;484:25;481:2;;;522:1;519;512:12;481:2;544:1;535:10;;554:125;568:6;565:1;562:13;554:125;;;656:11;;;650:18;629:14;;;625:23;;618:51;583:10;;;;554:125;;;697:6;694:1;691:13;688:2;;;764:1;759:2;750:6;742;738:19;734:28;727:39;688:2;;;;101:681;;;;;:::o;787:1144::-;;;;;1000:3;988:9;979:7;975:23;971:33;968:2;;;1022:6;1014;1007:22;968:2;1059:9;1053:16;1078:33;1105:5;1078:33;:::i;:::-;1179:2;1164:18;;1158:25;1130:5;;-1:-1:-1;;;;;;1232:14:12;;;1229:2;;;1264:6;1256;1249:22;1229:2;1307:6;1296:9;1292:22;1282:32;;1352:7;1345:4;1341:2;1337:13;1333:27;1323:2;;1379:6;1371;1364:22;1323:2;1407:79;1478:7;1473:2;1467:9;1462:2;1458;1454:11;1407:79;:::i;:::-;1397:89;;1531:2;1520:9;1516:18;1510:25;1495:40;;1544:35;1571:7;1544:35;:::i;:::-;1651:2;1636:18;;1630:25;1598:7;;-1:-1:-1;1667:16:12;;;1664:2;;;1701:6;1693;1686:22;1664:2;-1:-1:-1;1729:24:12;;1784:4;1776:13;;1772:27;-1:-1:-1;1762:2:12;;1818:6;1810;1803:22;1762:2;1846:79;1917:7;1912:2;1906:9;1901:2;1897;1893:11;1846:79;:::i;:::-;1836:89;;;958:973;;;;;;;:::o;1936:133::-;-1:-1:-1;;;;;2013:31:12;;2003:42;;1993:2;;2059:1;2056;2049:12;1993:2;1983:86;:::o;:::-;1135:2191:6;;;;;;;;;;;;;;;;;;", + "deployedSourceMap": "1135:2191:6:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2750:49:2;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1879:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;1701:32::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;16457:538::-;;;;;;;;;;-1:-1:-1;16457:538:2;;;;;:::i;:::-;;:::i;:::-;;2596:42;;;;;;;;;;;;;:::i;9425:1074::-;;;;;;;;;;-1:-1:-1;9425:1074:2;;;;;:::i;:::-;;:::i;18917:826::-;;;;;;;;;;-1:-1:-1;18917:826:2;;;;;:::i;:::-;;:::i;1970:31::-;;;;;;;;;;;;;:::i;13860:365::-;;;;;;;;;;-1:-1:-1;13860:365:2;;;;;:::i;:::-;;:::i;11127:2042::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;4786:65::-;;;;;;;;;;-1:-1:-1;4786:65:2;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;1630:39::-;;;;;;;;;;;;;:::i;2058:34::-;;;;;;;;;;;;;:::i;15366:397::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;2440:43::-;;;;;;;;;;;;;:::i;17802:520::-;;;;;;;;;;-1:-1:-1;17802:520:2;;;;;:::i;:::-;;:::i;14377:135::-;;;;;;;;;;-1:-1:-1;14377:135:2;;;;;:::i;:::-;;:::i;7187:184::-;;;;;;;;;;-1:-1:-1;7187:184:2;;;;;:::i;:::-;;:::i;14682:148::-;;;;;;;;;;-1:-1:-1;14682:148:2;;;;;:::i;:::-;;:::i;6490:425::-;;;;;;;;;;-1:-1:-1;6490:425:2;;;;;:::i;:::-;;:::i;7719:1439::-;;;;;;:::i;:::-;;:::i;1544:42::-;;;;;;;;;;;;;:::i;4923:63::-;;;;;;;;;;-1:-1:-1;4923:63:2;;;;;:::i;:::-;;:::i;20153:889::-;;;;;;;;;;-1:-1:-1;20153:889:2;;;;;:::i;:::-;;:::i;2581:718:6:-;;;;;;;;;;-1:-1:-1;2581:718:6;;;;;:::i;:::-;;:::i;13300:102:2:-;;;;;;;;;;-1:-1:-1;13300:102:2;;;;;:::i;:::-;;:::i;2997:54::-;;;;;;;;;;;;;:::i;710:40:7:-;;;;;;;;;;;;;:::i;2750:49:2:-;;;;:::o;1879:36::-;;;;;;:::o;1701:32::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;16457:538::-;16643:45;16691:32;;;:19;:32;;;;;16754:25;;;:32;16691;;16797:192;16841:10;16827:11;:24;16797:192;;;16882:96;16923:11;16936:12;16950:11;16963:14;16882:40;:96::i;:::-;16853:13;;16797:192;;;;16457:538;;;;;:::o;2596:42::-;;;;:::o;9425:1074::-;9502:18;9523:31;;;:19;:31;;;;;;;;;9612;;;:19;:31;;;;;;9674:10;9662:37;9689:10;9662:37;;9654:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;3141:21;9745:35;;;9737:62;;;;;;;;;;;;:::i;:::-;9846:15;9817:25;;;;:44;;;;;;;;;9809:83;;;;;;;;;;;;:::i;:::-;9925:25;;;9951:32;;9903:19;;9925:25;9951:36;;;;9925:63;;;;;;;;;;;;;;;;9903:85;;10159:19;10182:5;:19;;:26;;;;10212:1;10182:31;10181:68;;10242:7;10181:68;;;10217:5;:19;;10237:1;10217:22;;;;;;;;;;;;;;;;10181:68;10260:25;;;;:39;;;10309:40;;;;;;;10390:56;;10260:39;;-1:-1:-1;10422:10:2;;10409;;10390:56;;;;10260:39;;10390:56;:::i;:::-;;;;;;;;9425:1074;;;;;;:::o;18917:826::-;19102:14;19176:32;;;:19;:32;;;;;19241:25;;;:39;;19102:14;;19241:25;19267:12;;19241:39;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19327:15:2;19299:25;;;;:43;;;;;;;;;19291:79;;;;;;;;;;;;:::i;:::-;19390:78;19412:5;19419:12;19433:7;19442:18;:25;;;19390:21;:78::i;:::-;19381:87;-1:-1:-1;19483:11:2;;19479:258;;19510:33;;;19555:1;19510:33;;;:19;;;:33;;;;;;;;:42;;;;;;;;;:46;;;19570:25;;;;;;19588:6;;19570:25;;19555:1;19570:25;19588:6;19510:33;19570:25;;;;;;;;19705:12;19658:68;;19682:12;19669:11;19658:68;19696:7;19719:6;19658:68;;;;;;;:::i;:::-;;;;;;;;19479:258;18917:826;;;;;;;;:::o;1970:31::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13860:365;5603:8;;;;5589:10;:22;5581:66;;;;;;;;;;;;:::i;:::-;14050:21:::1;:46:::0;;;;14106:20:::1;:44:::0;14160:27:::1;:58:::0;13860:365::o;11127:2042::-;11220:16;3141:21;11256:35;;;11248:71;;;;;;;;;;;;:::i;:::-;11329:45;11377:32;;;:19;:32;;;;;11439:28;;;;;;11485:25;;;;:44;;;;;;;;;11477:78;;;;;;;;;;;;:::i;:::-;11590:35;;;;;11566:21;;11590:24;:10;:24;;;;:35;;11615:9;;11590:35;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11566:59;;11636:52;11654:9;11665:7;11674:13;11636:17;:52::i;:::-;11699:20;11721:17;11742:45;11753:9;11764:7;11773:13;11742:10;:45::i;:::-;11823:25;;;:32;;11698:89;;-1:-1:-1;11698:89:2;;-1:-1:-1;11823:36:2;;;;11798:22;;11823:25;:36;;11895:41;;;;;;;;;;;;;;11955:26;;;:17;11895:41;;;;;11955:17;;;:26;;;;;;;11895:41;;-1:-1:-1;11955:26:2;;11954:27;11946:73;;;;;;;;;;;;:::i;:::-;12030:20;12070:27;;;;;;;;;;;12101:9;;12053:45;;:9;;:16;:45::i;:::-;:57;:117;;12142:18;:27;;;;;;;;;;;12125:45;;:9;;:16;:45::i;:::-;12053:117;;;12113:9;12053:117;12030:140;;12236:10;12185:76;;12211:14;12198:11;12185:76;12227:7;12248:12;12185:76;;;;;;;:::i;:::-;;;;;;;;12296:10;12272:35;;;;:23;;;:35;;;;;;;;:44;;;;;;;;:60;;;;;;12342:27;;;;;;:43;;;;;;;;12400:40;-1:-1:-1;12396:289:2;;12480:18;:27;;;;;;;;;;;;12456:20;;;:51;;;;;;;12521:23;;;:37;;-1:-1:-1;12521:37:2;;;;;;;;;;;;;;;12572:26;;;:17;;;:26;;;;;;:33;;;;;;;;;;12624:50;12499:7;;12650:14;;12637:11;;12624:50;;;12396:289;12699:23;;;:30;12733:1;12699:35;12695:322;;;12811:25;;;;:32;;;;;;-1:-1:-1;12811:32:2;12881:20;;;:41;;12909:12;12881:27;:41::i;:::-;12858:20;;;:64;12936:70;;;;;:17;:10;:17;;;;12961:12;;12936:70;;12975:9;;12986:19;;12936:70;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12695:322;13027:10;:47;13043:30;:9;13060:12;13043:16;:30::i;:::-;13027:47;;;;;;;;;;;;;;;;-1:-1:-1;;;13136:26:2;;;;:17;;;;:26;;-1:-1:-1;;13136:26:2;;;;;;;;-1:-1:-1;;;;;;;;11127:2042:2;;;;;:::o;4786:65::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;1630:39::-;;;:::o;2058:34::-;;;;:::o;15366:397::-;15659:21;;15682:20;;15704:27;;3046:5;15366:397;;;;:::o;2440:43::-;;;;:::o;17802:520::-;18056:21;;18022:31;18087:229;18145:23;18124:18;:44;18087:229;;;18206:99;18229:11;18242:12;18256;18270:14;18285:18;18270:34;;;;;;;;;;;;;;18206:22;:99::i;:::-;-1:-1:-1;18170:20:2;;18087:229;;14377:135;-1:-1:-1;3141:21:2;;14377:135::o;7187:184::-;5603:8;;;;5589:10;:22;5581:66;;;;;;;;;;;;:::i;:::-;7298:19:::1;;7285:48;7319:13;;7285:48;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1::0;;7343:19:2::1;:21:::0;;::::1;;::::0;;7187:184::o;14682:148::-;14776:47;;;;;14746:11;;14776:26;:10;:26;;;;:47;;14746:11;;14776:47;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;6490:425::-;6593:45;6641:32;;;:19;:32;;;;;6719:12;6691:25;;;;:40;;;;;;;;;6683:98;;;;;;;;;;;;:::i;:::-;6830:10;6796:59;;6817:11;6805:10;6796:59;;;6842:12;;6796:59;;;;;;;:::i;:::-;;;;;;;;6490:425;;;;:::o;7719:1439::-;7816:17;7875:1;7853:19;;:23;7845:65;;;;;;;;;;;;:::i;:::-;7921:45;7969:41;;;:19;:41;;;;;;8028:25;;;;:40;;;;;;;;;8020:82;;;;;;;;;;;;:::i;:::-;8164:47;;;;;8138:23;;8164:26;:10;:26;;;;:47;;8138:23;;8164:47;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8233:95;;;;;8138:73;;-1:-1:-1;8233:24:2;:10;:24;;;;8138:73;;8233:95;;3141:21;;8308:19;;8233:95;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8221:107;;8363:9;8351:10;8343:77;;;8396:1;8374:19;;:23;8407:11;8399:20;;;8343:77;;;;;;;:::i;:::-;;;;;;;;8517:9;8495:45;8528:11;8495:45;;;;;;:::i;:::-;;;;;;;;8643:30;;;;:19;:30;;;;;;:53;;;8740:40;;-1:-1:-1;8740:40:2;;;;8770:10;8740:40;;;;;;;8790:43;;;;;;8843:28;;;:40;;;8893:25;;;:32;;;;;;;;;8963:89;;;;:50;8977:8;8963:50;;;;:89;;8643:53;;9039:12;;8963:89;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9063:10:2;;-1:-1:-1;9063:50:2;;-1:-1:-1;9079:33:2;;-1:-1:-1;9079:9:2;9096:15;9079:16;:33::i;:::-;9063:50;;;;;;;;;;;;;;;;;;;;;;7719:1439;;;;;;:::o;1544:42::-;;;:::o;4923:63::-;;;;;;;;;;;;;:::o;20153:889::-;20335:11;20406:32;;;:19;:32;;;;;20480:12;20452:25;;;;:40;;;;;;;;;20448:54;;;20501:1;20494:8;;;;;20448:54;20533:25;;;:32;20597:25;;;;20512:18;20633:403;20677:10;20663:11;:24;20633:403;;;20718:19;20740:18;:25;;20766:11;20740:38;;;;;;;;;;;;;;;;;;20718:60;;20797:26;20792:234;20850:14;:21;20829:18;:42;20792:234;;;20920:91;20942:5;20949:12;20963:14;20978:18;20963:34;;;;;;;;;;;;;;20999:11;20920:21;:91::i;:::-;20913:98;;;;20873:20;;20792:234;;;-1:-1:-1;;20689:13:2;;20633:403;;;;20153:889;;;;;;;;;:::o;2581:718:6:-;2765:45;2813:41;;;:19;:41;;;;;2901:12;2872:25;;;;:41;;;;;;;;;2864:81;;;;;;;;;;;;:::i;:::-;2956:43;;;;2984:15;2956:43;;;;3172:25;;;;3086:206;;;;;3101:8;3086:64;;;;;;;:206;;3151:11;;3172:29;;;;;3204:27;;;;;;;3233:16;;3251:25;;3278:13;;3086:206;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2581:718;;;;;:::o;13300:102:2:-;5603:8;;;;5589:10;:22;5581:66;;;;;;;;;;;;:::i;:::-;13375:8:::1;:20:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;13300:102::o;2997:54::-;3046:5;2997:54;:::o;710:40:7:-;;;;;;;;;;;;;;;;;;;:::o;21478:1270:2:-;21660:14;21691:30;;;:14;;;:30;;;;;;;;21686:1056;;-1:-1:-1;21832:34:2;;;;;;;:20;;;:34;;;;;;;;:50;;;;;;;;;21686:1056;;;21996:12;21978:14;:30;21974:758;;;22133:1;22099:31;;;;;;;;;;;:148;;22246:1;22099:148;;;22212:15;:31;;;;;;;;;;;;22191:17;;;;22138:34;;;;;:20;;;:34;;;;;:50;;;;;;;;;:70;22212:31;22137:106;;;;;22099:148;22090:157;;21974:758;;;22272:20;;;:27;22303:1;-1:-1:-1;22272:32:2;;;:65;;-1:-1:-1;22309:28:2;;;;:14;;;:28;;;;;;;;22308:29;22272:65;22268:464;;;22676:6;:15;;:40;22692:6;:20;;22713:1;22692:23;;;;;;;;;;;;;;;;22676:40;;;;;;;;;;;;22633:6;:15;;:40;22649:6;:20;;22670:1;22649:23;;;;;;;;;;;;;;;;;;;;22633:40;;;;;;;;;;;;;;;;22611:17;;;;22558:34;;;;;:20;;;:34;;;;;:50;;;;;;;;;;22633:83;;;22558:70;22633:83;22557:160;;;;;22548:169;;22268:464;21478:1270;;;;;;:::o;24177:669::-;24320:21;24343:19;24366:10;:23;;;24390:10;24366:35;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;24319:82;;;;24434:7;24416:14;:25;24412:428;;;24484:13;24465:15;:32;;:65;;;;;24519:11;24501:15;:29;24465:65;24457:124;;;;;;;;;;;;:::i;:::-;24412:428;;;24639:13;24620:15;:32;;:158;;;;;3046:5;24724:27;;24707:13;24693:11;:27;24692:59;24691:86;;;;;;24675:13;:102;24656:15;:122;24620:158;24612:217;;;;;;;;;;;;:::i;:::-;24177:669;;;;;:::o;23239:522::-;23373:20;23395;23427:18;23470:14;23459:7;:25;23455:113;;;-1:-1:-1;23499:21:2;;23455:113;;;-1:-1:-1;23548:20:2;;23455:113;23599:54;;;;;23579:17;;23599:21;:10;:21;;;;:54;;23621:10;;23579:17;;23599:54;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;23579:74;-1:-1:-1;23579:74:2;23682:71;3046:5;23699:28;23579:74;23716:10;23699:16;:28::i;:::-;:53;;;;;23682:9;;23699:53;;23682:16;:71::i;:::-;23663:91;;;;;;23239:522;;;;;;:::o;699:154:11:-;756:4;781:2;776;:7;772:74;;;-1:-1:-1;804:1:11;797:8;;772:74;-1:-1:-1;839:7:11;;;832:14;;952:403;1009:4;1248:7;1244:33;;-1:-1:-1;1276:1:11;1269:8;;1244:33;1297:7;;;1302:2;1297;:7;:2;1321:6;;;;;:12;:27;;378:10;1321:27;;482:135;539:4;564:7;;;588;;;;:22;;378:10;588:22;;14:908:12;;127:3;120:4;112:6;108:17;104:27;94:2;;149:5;142;135:20;94:2;189:6;176:20;215:4;238:18;275:2;271;268:10;265:2;;;281:9;265:2;319;315;311:11;351:2;345:9;402:2;397;389:6;385:15;381:24;455:6;443:10;440:22;435:2;423:10;420:18;417:46;414:2;;;466:9;414:2;493;486:22;543:18;;;577:15;;;;-1:-1:-1;612:15:12;;;646;;;642:24;;639:33;-1:-1:-1;636:2:12;;;689:5;682;675:20;636:2;715:5;706:14;;729:163;743:2;740:1;737:9;729:163;;;800:17;;788:30;;838:12;;;;761:1;754:9;;;;;870:12;;729:163;;;-1:-1:-1;910:6:12;84:838;-1:-1:-1;;;;;;;84:838:12:o;927:378::-;;;1045:3;1038:4;1030:6;1026:17;1022:27;1012:2;;1070:8;1060;1053:26;1012:2;-1:-1:-1;1100:20:12;;1143:18;1132:30;;1129:2;;;1182:8;1172;1165:26;1129:2;1226:4;1218:6;1214:17;1202:29;;1278:3;1271:4;1262:6;1254;1250:19;1246:30;1243:39;1240:2;;;1295:1;1292;1285:12;1240:2;1002:303;;;;;:::o;1310:259::-;;1422:2;1410:9;1401:7;1397:23;1393:32;1390:2;;;1443:6;1435;1428:22;1390:2;1487:9;1474:23;1506:33;1533:5;1506:33;:::i;1574:190::-;;1686:2;1674:9;1665:7;1661:23;1657:32;1654:2;;;1707:6;1699;1692:22;1654:2;-1:-1:-1;1735:23:12;;1644:120;-1:-1:-1;1644:120:12:o;1769:464::-;;;;;1932:3;1920:9;1911:7;1907:23;1903:33;1900:2;;;1954:6;1946;1939:22;1900:2;1995:9;1982:23;1972:33;;2052:2;2041:9;2037:18;2024:32;2014:42;;2103:2;2092:9;2088:18;2075:32;2065:42;;2157:2;2146:9;2142:18;2129:32;2170:33;2197:5;2170:33;:::i;:::-;1890:343;;;;-1:-1:-1;1890:343:12;;-1:-1:-1;;1890:343:12:o;2238:258::-;;;2367:2;2355:9;2346:7;2342:23;2338:32;2335:2;;;2388:6;2380;2373:22;2335:2;-1:-1:-1;;2416:23:12;;;2486:2;2471:18;;;2458:32;;-1:-1:-1;2325:171:12:o;2501:433::-;;;2633:2;2621:9;2612:7;2608:23;2604:32;2601:2;;;2654:6;2646;2639:22;2601:2;2699:9;2686:23;2732:18;2724:6;2721:30;2718:2;;;2769:6;2761;2754:22;2718:2;2813:61;2866:7;2857:6;2846:9;2842:22;2813:61;:::i;:::-;2893:8;;2787:87;;-1:-1:-1;2591:343:12;-1:-1:-1;;;;2591:343:12:o;3134:194::-;;3257:2;3245:9;3236:7;3232:23;3228:32;3225:2;;;3278:6;3270;3263:22;3225:2;-1:-1:-1;3306:16:12;;3215:113;-1:-1:-1;3215:113:12:o;3333:587::-;;;;3512:2;3500:9;3491:7;3487:23;3483:32;3480:2;;;3533:6;3525;3518:22;3480:2;3574:9;3561:23;3551:33;;3634:2;3623:9;3619:18;3606:32;3647:33;3674:5;3647:33;:::i;:::-;3699:5;-1:-1:-1;3755:2:12;3740:18;;3727:32;3782:18;3771:30;;3768:2;;;3819:6;3811;3804:22;3768:2;3847:67;3906:7;3897:6;3886:9;3882:22;3847:67;:::i;:::-;3837:77;;;3470:450;;;;;:::o;3925:656::-;;;;;4121:3;4109:9;4100:7;4096:23;4092:33;4089:2;;;4143:6;4135;4128:22;4089:2;4184:9;4171:23;4161:33;;4244:2;4233:9;4229:18;4216:32;4257:33;4284:5;4257:33;:::i;:::-;4309:5;-1:-1:-1;4361:2:12;4346:18;;4333:32;;-1:-1:-1;4416:2:12;4401:18;;4388:32;4443:18;4432:30;;4429:2;;;4480:6;4472;4465:22;4429:2;4508:67;4567:7;4558:6;4547:9;4543:22;4508:67;:::i;:::-;4498:77;;;4079:502;;;;;;;:::o;4586:472::-;;;;;4757:3;4745:9;4736:7;4732:23;4728:33;4725:2;;;4779:6;4771;4764:22;4725:2;4820:9;4807:23;4797:33;;4880:2;4869:9;4865:18;4852:32;4893:33;4920:5;4893:33;:::i;:::-;4715:343;;4945:5;;-1:-1:-1;;;;4997:2:12;4982:18;;4969:32;;5048:2;5033:18;5020:32;;4715:343::o;5063:501::-;;;;5212:2;5200:9;5191:7;5187:23;5183:32;5180:2;;;5233:6;5225;5218:22;5180:2;5274:9;5261:23;5251:33;;5335:2;5324:9;5320:18;5307:32;5362:18;5354:6;5351:30;5348:2;;;5399:6;5391;5384:22;5348:2;5443:61;5496:7;5487:6;5476:9;5472:22;5443:61;:::i;:::-;5170:394;;5523:8;;-1:-1:-1;5417:87:12;;-1:-1:-1;;;;5170:394:12:o;5832:255::-;;;5972:2;5960:9;5951:7;5947:23;5943:32;5940:2;;;5993:6;5985;5978:22;5940:2;-1:-1:-1;;6021:16:12;;6077:2;6062:18;;;6056:25;6021:16;;6056:25;;-1:-1:-1;5930:157:12:o;6092:326::-;;;;6238:2;6226:9;6217:7;6213:23;6209:32;6206:2;;;6259:6;6251;6244:22;6206:2;-1:-1:-1;;6287:23:12;;;6357:2;6342:18;;6329:32;;-1:-1:-1;6408:2:12;6393:18;;;6380:32;;6196:222;-1:-1:-1;6196:222:12:o;6423:536::-;;6504:5;6498:12;6531:6;6526:3;6519:19;6556:3;6568:162;6582:6;6579:1;6576:13;6568:162;;;6644:4;6700:13;;;6696:22;;6690:29;6672:11;;;6668:20;;6661:59;6597:12;6568:162;;;6748:6;6745:1;6742:13;6739:2;;;6814:3;6807:4;6798:6;6793:3;6789:16;6785:27;6778:40;6739:2;-1:-1:-1;6873:2:12;6861:15;6878:66;6857:88;6848:98;;;;6948:4;6844:109;;6474:485;-1:-1:-1;;6474:485:12:o;6964:814::-;;7056:5;7050:12;7081:1;7113:2;7102:9;7098:18;7130:1;7125:223;;;;7362:1;7357:415;;;;7091:681;;7125:223;7181:4;7177:1;7166:9;7162:17;7158:28;7153:3;7146:41;7238:66;7227:9;7223:82;7216:4;7211:3;7207:14;7200:106;7335:2;7330:3;7326:12;7319:19;;7125:223;;7357:415;7407:1;7396:9;7392:17;7434:6;7429:3;7422:19;7469:37;7500:5;7469:37;:::i;:::-;7528:1;7542:178;7556:6;7553:1;7550:13;7542:178;;;7653:7;7647:14;7640:4;7636:1;7631:3;7627:11;7623:22;7616:46;7703:2;7694:7;7690:16;7679:27;;7578:4;7575:1;7571:12;7566:17;;7542:178;;;7744:11;;7757:4;7740:22;;-1:-1:-1;;;7091:681:12;;;;7023:755;;;;:::o;7783:226::-;7959:42;7947:55;;;;7929:74;;7917:2;7902:18;;7884:125::o;8014:187::-;8179:14;;8172:22;8154:41;;8142:2;8127:18;;8109:92::o;8206:177::-;8352:25;;;8340:2;8325:18;;8307:76::o;8388:376::-;8598:25;;;8671:42;8659:55;;;;8654:2;8639:18;;8632:83;8746:2;8731:18;;8724:34;8586:2;8571:18;;8553:211::o;8769:614::-;9056:25;;;9112:2;9097:18;;9090:34;;;;9143:42;9221:15;;;9216:2;9201:18;;9194:43;9268:2;9253:18;;9246:34;;;;9311:3;9296:19;;9289:35;9361:15;9355:3;9340:19;;9333:44;9043:3;9028:19;;9010:373::o;9388:219::-;;9535:2;9524:9;9517:21;9555:46;9597:2;9586:9;9582:18;9574:6;9555:46;:::i;9612:224::-;;9756:2;9745:9;9738:21;9776:54;9826:2;9815:9;9811:18;9803:6;9776:54;:::i;10092:494::-;10317:3;10302:19;;10351:1;10340:13;;10330:2;;10357:9;10330:2;10377:25;;;10450:42;10438:55;;;;10433:2;10418:18;;10411:83;10525:2;10510:18;;10503:34;;;;10568:2;10553:18;;;10546:34;10284:302;:::o;10591:452::-;;10750:2;10739:9;10732:21;10789:6;10784:2;10773:9;10769:18;10762:34;10846:6;10838;10833:2;10822:9;10818:18;10805:48;10873:22;;;10897:2;10869:31;;;10862:45;;;;10959:2;10947:15;;;10964:66;10943:88;10928:104;10924:113;;10722:321;-1:-1:-1;10722:321:12:o;11274:410::-;11476:2;11458:21;;;11515:2;11495:18;;;11488:30;11554:34;11549:2;11534:18;;11527:62;11625:16;11620:2;11605:18;;11598:44;11674:3;11659:19;;11448:236::o;11689:347::-;11891:2;11873:21;;;11930:2;11910:18;;;11903:30;11969:25;11964:2;11949:18;;11942:53;12027:2;12012:18;;11863:173::o;12041:353::-;12243:2;12225:21;;;12282:2;12262:18;;;12255:30;12321:31;12316:2;12301:18;;12294:59;12385:2;12370:18;;12215:179::o;12399:338::-;12601:2;12583:21;;;12640:2;12620:18;;;12613:30;12679:16;12674:2;12659:18;;12652:44;12728:2;12713:18;;12573:164::o;12742:351::-;12944:2;12926:21;;;12983:2;12963:18;;;12956:30;13022:29;13017:2;13002:18;;12995:57;13084:2;13069:18;;12916:177::o;13098:355::-;13300:2;13282:21;;;13339:2;13319:18;;;13312:30;13378:33;13373:2;13358:18;;13351:61;13444:2;13429:18;;13272:181::o;13458:347::-;13660:2;13642:21;;;13699:2;13679:18;;;13672:30;13738:25;13733:2;13718:18;;13711:53;13796:2;13781:18;;13632:173::o;13810:347::-;14012:2;13994:21;;;14051:2;14031:18;;;14024:30;14090:25;14085:2;14070:18;;14063:53;14148:2;14133:18;;13984:173::o;14162:345::-;14364:2;14346:21;;;14403:2;14383:18;;;14376:30;14442:23;14437:2;14422:18;;14415:51;14498:2;14483:18;;14336:171::o;14512:353::-;14714:2;14696:21;;;14753:2;14733:18;;;14726:30;14792:31;14787:2;14772:18;;14765:59;14856:2;14841:18;;14686:179::o;14870:397::-;15072:2;15054:21;;;15111:2;15091:18;;;15084:30;15150:34;15145:2;15130:18;;15123:62;15221:3;15216:2;15201:18;;15194:31;15257:3;15242:19;;15044:223::o;15272:409::-;15474:2;15456:21;;;15513:2;15493:18;;;15486:30;15552:34;15547:2;15532:18;;15525:62;15623:15;15618:2;15603:18;;15596:43;15671:3;15656:19;;15446:235::o;15686:350::-;15888:2;15870:21;;;15927:2;15907:18;;;15900:30;15966:28;15961:2;15946:18;;15939:56;16027:2;16012:18;;15860:176::o;16223:295::-;;16395:6;16384:9;16377:25;16438:2;16433;16422:9;16418:18;16411:30;16458:54;16508:2;16497:9;16493:18;16485:6;16458:54;:::i;16523:248::-;16697:25;;;16753:2;16738:18;;16731:34;16685:2;16670:18;;16652:119::o;16776:391::-;17007:25;;;17063:2;17048:18;;17041:34;;;;17106:2;17091:18;;17084:34;17149:2;17134:18;;17127:34;16994:3;16979:19;;16961:206::o;17172:128::-;;17239:17;;;17289:4;17273:21;;;17229:71::o;17305:156::-;17393:42;17386:5;17382:54;17375:5;17372:65;17362:2;;17451:1;17448;17441:12;17362:2;17352:109;:::o", + "source": "// SPDX-License-Identifier: MIT\n\n/**\n * @authors: [@ferittuncer]\n * @reviewers: [@unknownunknown1*, @hbarcelos*, @MerlinEgalite*]\n * @auditors: []\n * @bounties: []\n * @deployments: []\n */\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./IRealitio_v2_1.sol\";\nimport \"../RealitioArbitratorWithAppealsBase.sol\";\n\n/**\n * @title Realitio_v2_1_ArbitratorWithAppeals\n * @dev A Realitio arbitrator implementation that uses Realitio v2.1 and Kleros. It notifies Realitio contract for arbitration requests and creates corresponding dispute on Kleros. Transmits Kleros ruling to Realitio contract. Maintains crowdfunded appeals and notifies Kleros contract. Provides a function to submit evidence for Kleros dispute.\n * There is a conversion between Kleros ruling and Realitio answer and there is a need for shifting by 1. This is because ruling 0 in Kleros signals tie or no-ruling but in Realitio 0 is a valid answer. For reviewers this should be a focus as it's quite easy to get confused. Any mistakes on this conversion will render this contract useless.\n * NOTE: This contract trusts the Kleros arbitrator and Realitio.\n */\ncontract Realitio_v2_1_ArbitratorWithAppeals is RealitioArbitratorWithAppealsBase {\n /** @dev Constructor.\n * @param _realitio The address of the Realitio contract.\n * @param _metadata The metadata required for RealitioArbitrator.\n * @param _arbitrator The address of the ERC792 arbitrator.\n * @param _arbitratorExtraData The extra data used to raise a dispute in the ERC792 arbitrator.\n */\n constructor(\n address _realitio,\n string memory _metadata,\n IArbitrator _arbitrator,\n bytes memory _arbitratorExtraData\n ) RealitioArbitratorWithAppealsBase(_realitio, _metadata, _arbitrator, _arbitratorExtraData) {}\n\n /** @dev Reports the answer to a specified question from the Kleros arbitrator to the Realitio v2.1 contract.\n * This can be called by anyone, after the dispute gets a ruling from Kleros.\n We can't directly call `assignWinnerAndSubmitAnswerByArbitrator` inside `rule` because of extra parameters (e.g. _lastHistoryHash).\n * @param _questionID The ID of Realitio question.\n * @param _lastHistoryHash The history hash given with the last answer to the question in the Realitio contract.\n * @param _lastAnswerOrCommitmentID The last answer given, or its commitment ID if it was a commitment, to the question in the Realitio contract, in bytes32.\n * @param _lastAnswerer The last answerer to the question in the Realitio contract.\n */\n function reportAnswer(\n bytes32 _questionID,\n bytes32 _lastHistoryHash,\n bytes32 _lastAnswerOrCommitmentID,\n address _lastAnswerer\n ) external {\n ArbitrationRequest storage arbitrationRequest = arbitrationRequests[uint256(_questionID)];\n require(arbitrationRequest.status == Status.Ruled, \"The status should be Ruled.\");\n\n arbitrationRequest.status = Status.Reported;\n\n // Note that answer(ruling) is shift by -1 before calling Realitio.\n IRealitio_v2_1(realitio).assignWinnerAndSubmitAnswerByArbitrator(_questionID, bytes32(arbitrationRequest.answer - 1), arbitrationRequest.disputer, _lastHistoryHash, _lastAnswerOrCommitmentID, _lastAnswerer);\n }\n\n /* Private Views */\n}\n", + "sourcePath": "/home/f/repos/realitio-arbitrator-with-appeals/contracts/v2.1/Realitio_v2_1_ArbitratorWithAppeals.sol", + "ast": { + "absolutePath": "/home/f/repos/realitio-arbitrator-with-appeals/contracts/v2.1/Realitio_v2_1_ArbitratorWithAppeals.sol", + "exportedSymbols": { + "CappedMath": [ + 1969 + ], + "IArbitrable": [ + 1755 + ], + "IArbitrator": [ + 1847 + ], + "IDisputeResolver": [ + 1733 + ], + "IEvidence": [ + 1881 + ], + "IRealitioArbitrator": [ + 24 + ], + "IRealitioBase": [ + 38 + ], + "IRealitio_v2_1": [ + 1502 + ], + "RealitioArbitratorWithAppealsBase": [ + 1234 + ], + "Realitio_v2_1_ArbitratorWithAppeals": [ + 1587 + ] + }, + "id": 1588, + "license": "MIT", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1504, + "literals": [ + "solidity", + "^", + "0.7", + ".0" + ], + "nodeType": "PragmaDirective", + "src": "194:23:6" + }, + { + "id": 1505, + "literals": [ + "abicoder", + "v2" + ], + "nodeType": "PragmaDirective", + "src": "218:19:6" + }, + { + "absolutePath": "/home/f/repos/realitio-arbitrator-with-appeals/contracts/v2.1/IRealitio_v2_1.sol", + "file": "./IRealitio_v2_1.sol", + "id": 1506, + "nodeType": "ImportDirective", + "scope": 1588, + "sourceUnit": 1503, + "src": "239:30:6", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/home/f/repos/realitio-arbitrator-with-appeals/contracts/RealitioArbitratorWithAppealsBase.sol", + "file": "../RealitioArbitratorWithAppealsBase.sol", + "id": 1507, + "nodeType": "ImportDirective", + "scope": 1588, + "sourceUnit": 1235, + "src": "270:50:6", + "symbolAliases": [], + "unitAlias": "" + }, + { + "abstract": false, + "baseContracts": [ + { + "baseName": { + "id": 1509, + "name": "RealitioArbitratorWithAppealsBase", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 1234, + "src": "1183:33:6", + "typeDescriptions": { + "typeIdentifier": "t_contract$_RealitioArbitratorWithAppealsBase_$1234", + "typeString": "contract RealitioArbitratorWithAppealsBase" + } + }, + "id": 1510, + "nodeType": "InheritanceSpecifier", + "src": "1183:33:6" + } + ], + "contractDependencies": [ + 24, + 1234, + 1733, + 1755, + 1881 + ], + "contractKind": "contract", + "documentation": { + "id": 1508, + "nodeType": "StructuredDocumentation", + "src": "322:812:6", + "text": " @title Realitio_v2_1_ArbitratorWithAppeals\n @dev A Realitio arbitrator implementation that uses Realitio v2.1 and Kleros. It notifies Realitio contract for arbitration requests and creates corresponding dispute on Kleros. Transmits Kleros ruling to Realitio contract. Maintains crowdfunded appeals and notifies Kleros contract. Provides a function to submit evidence for Kleros dispute.\n There is a conversion between Kleros ruling and Realitio answer and there is a need for shifting by 1. This is because ruling 0 in Kleros signals tie or no-ruling but in Realitio 0 is a valid answer. For reviewers this should be a focus as it's quite easy to get confused. Any mistakes on this conversion will render this contract useless.\n NOTE: This contract trusts the Kleros arbitrator and Realitio." + }, + "fullyImplemented": true, + "id": 1587, + "linearizedBaseContracts": [ + 1587, + 1234, + 24, + 1733, + 1881, + 1755 + ], + "name": "Realitio_v2_1_ArbitratorWithAppeals", + "nodeType": "ContractDefinition", + "nodes": [ + { + "body": { + "id": 1528, + "nodeType": "Block", + "src": "1802:2:6", + "statements": [] + }, + "documentation": { + "id": 1511, + "nodeType": "StructuredDocumentation", + "src": "1223:329:6", + "text": "@dev Constructor.\n @param _realitio The address of the Realitio contract.\n @param _metadata The metadata required for RealitioArbitrator.\n @param _arbitrator The address of the ERC792 arbitrator.\n @param _arbitratorExtraData The extra data used to raise a dispute in the ERC792 arbitrator." + }, + "id": 1529, + "implemented": true, + "kind": "constructor", + "modifiers": [ + { + "arguments": [ + { + "id": 1522, + "name": "_realitio", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1513, + "src": "1745:9:6", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 1523, + "name": "_metadata", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1515, + "src": "1756:9:6", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + }, + { + "id": 1524, + "name": "_arbitrator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1517, + "src": "1767:11:6", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IArbitrator_$1847", + "typeString": "contract IArbitrator" + } + }, + { + "id": 1525, + "name": "_arbitratorExtraData", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1519, + "src": "1780:20:6", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "id": 1526, + "modifierName": { + "id": 1521, + "name": "RealitioArbitratorWithAppealsBase", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1234, + "src": "1711:33:6", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_RealitioArbitratorWithAppealsBase_$1234_$", + "typeString": "type(contract RealitioArbitratorWithAppealsBase)" + } + }, + "nodeType": "ModifierInvocation", + "src": "1711:90:6" + } + ], + "name": "", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1520, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1513, + "mutability": "mutable", + "name": "_realitio", + "nodeType": "VariableDeclaration", + "scope": 1529, + "src": "1578:17:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 1512, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1578:7:6", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1515, + "mutability": "mutable", + "name": "_metadata", + "nodeType": "VariableDeclaration", + "scope": 1529, + "src": "1605:23:6", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 1514, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "1605:6:6", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1517, + "mutability": "mutable", + "name": "_arbitrator", + "nodeType": "VariableDeclaration", + "scope": 1529, + "src": "1638:23:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IArbitrator_$1847", + "typeString": "contract IArbitrator" + }, + "typeName": { + "id": 1516, + "name": "IArbitrator", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 1847, + "src": "1638:11:6", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IArbitrator_$1847", + "typeString": "contract IArbitrator" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1519, + "mutability": "mutable", + "name": "_arbitratorExtraData", + "nodeType": "VariableDeclaration", + "scope": 1529, + "src": "1671:33:6", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 1518, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "1671:5:6", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "1568:142:6" + }, + "returnParameters": { + "id": 1527, + "nodeType": "ParameterList", + "parameters": [], + "src": "1802:0:6" + }, + "scope": 1587, + "src": "1557:247:6", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + }, + { + "body": { + "id": 1585, + "nodeType": "Block", + "src": "2755:544:6", + "statements": [ + { + "assignments": [ + 1542 + ], + "declarations": [ + { + "constant": false, + "id": 1542, + "mutability": "mutable", + "name": "arbitrationRequest", + "nodeType": "VariableDeclaration", + "scope": 1585, + "src": "2765:45:6", + "stateVariable": false, + "storageLocation": "storage", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ArbitrationRequest_$107_storage_ptr", + "typeString": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest" + }, + "typeName": { + "id": 1541, + "name": "ArbitrationRequest", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 107, + "src": "2765:18:6", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ArbitrationRequest_$107_storage_ptr", + "typeString": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest" + } + }, + "visibility": "internal" + } + ], + "id": 1549, + "initialValue": { + "baseExpression": { + "id": 1543, + "name": "arbitrationRequests", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 131, + "src": "2813:19:6", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint256_$_t_struct$_ArbitrationRequest_$107_storage_$", + "typeString": "mapping(uint256 => struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage ref)" + } + }, + "id": 1548, + "indexExpression": { + "arguments": [ + { + "id": 1546, + "name": "_questionID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1532, + "src": "2841:11:6", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 1545, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "2833:7:6", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + }, + "typeName": { + "id": 1544, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2833:7:6", + "typeDescriptions": {} + } + }, + "id": 1547, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "2833:20:6", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "2813:41:6", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ArbitrationRequest_$107_storage", + "typeString": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage ref" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "2765:89:6" + }, + { + "expression": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_enum$_Status_$95", + "typeString": "enum RealitioArbitratorWithAppealsBase.Status" + }, + "id": 1555, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 1551, + "name": "arbitrationRequest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1542, + "src": "2872:18:6", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ArbitrationRequest_$107_storage_ptr", + "typeString": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage pointer" + } + }, + "id": 1552, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "status", + "nodeType": "MemberAccess", + "referencedDeclaration": 97, + "src": "2872:25:6", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Status_$95", + "typeString": "enum RealitioArbitratorWithAppealsBase.Status" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "expression": { + "id": 1553, + "name": "Status", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 95, + "src": "2901:6:6", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Status_$95_$", + "typeString": "type(enum RealitioArbitratorWithAppealsBase.Status)" + } + }, + "id": 1554, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "Ruled", + "nodeType": "MemberAccess", + "src": "2901:12:6", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Status_$95", + "typeString": "enum RealitioArbitratorWithAppealsBase.Status" + } + }, + "src": "2872:41:6", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "546865207374617475732073686f756c642062652052756c65642e", + "id": 1556, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2915:29:6", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_7b12e68595b54b95620c01e48f1dc5573a4c5ef17b89e01ed1eb1d416d772095", + "typeString": "literal_string \"The status should be Ruled.\"" + }, + "value": "The status should be Ruled." + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_7b12e68595b54b95620c01e48f1dc5573a4c5ef17b89e01ed1eb1d416d772095", + "typeString": "literal_string \"The status should be Ruled.\"" + } + ], + "id": 1550, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 4294967278, + 4294967278 + ], + "referencedDeclaration": 4294967278, + "src": "2864:7:6", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 1557, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "2864:81:6", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1558, + "nodeType": "ExpressionStatement", + "src": "2864:81:6" + }, + { + "expression": { + "id": 1564, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "expression": { + "id": 1559, + "name": "arbitrationRequest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1542, + "src": "2956:18:6", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ArbitrationRequest_$107_storage_ptr", + "typeString": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage pointer" + } + }, + "id": 1561, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "status", + "nodeType": "MemberAccess", + "referencedDeclaration": 97, + "src": "2956:25:6", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Status_$95", + "typeString": "enum RealitioArbitratorWithAppealsBase.Status" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "expression": { + "id": 1562, + "name": "Status", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 95, + "src": "2984:6:6", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Status_$95_$", + "typeString": "type(enum RealitioArbitratorWithAppealsBase.Status)" + } + }, + "id": 1563, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "Reported", + "nodeType": "MemberAccess", + "src": "2984:15:6", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Status_$95", + "typeString": "enum RealitioArbitratorWithAppealsBase.Status" + } + }, + "src": "2956:43:6", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Status_$95", + "typeString": "enum RealitioArbitratorWithAppealsBase.Status" + } + }, + "id": 1565, + "nodeType": "ExpressionStatement", + "src": "2956:43:6" + }, + { + "expression": { + "arguments": [ + { + "id": 1570, + "name": "_questionID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1532, + "src": "3151:11:6", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1576, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 1573, + "name": "arbitrationRequest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1542, + "src": "3172:18:6", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ArbitrationRequest_$107_storage_ptr", + "typeString": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage pointer" + } + }, + "id": 1574, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "answer", + "nodeType": "MemberAccess", + "referencedDeclaration": 103, + "src": "3172:25:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "hexValue": "31", + "id": 1575, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3200:1:6", + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "3172:29:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 1572, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "3164:7:6", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": { + "id": 1571, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3164:7:6", + "typeDescriptions": {} + } + }, + "id": 1577, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3164:38:6", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "expression": { + "id": 1578, + "name": "arbitrationRequest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1542, + "src": "3204:18:6", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ArbitrationRequest_$107_storage_ptr", + "typeString": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage pointer" + } + }, + "id": 1579, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "disputer", + "nodeType": "MemberAccess", + "referencedDeclaration": 99, + "src": "3204:27:6", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 1580, + "name": "_lastHistoryHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1534, + "src": "3233:16:6", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1581, + "name": "_lastAnswerOrCommitmentID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1536, + "src": "3251:25:6", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1582, + "name": "_lastAnswerer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1538, + "src": "3278:13:6", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "expression": { + "arguments": [ + { + "id": 1567, + "name": "realitio", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 56, + "src": "3101:8:6", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 1566, + "name": "IRealitio_v2_1", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1502, + "src": "3086:14:6", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_IRealitio_v2_1_$1502_$", + "typeString": "type(contract IRealitio_v2_1)" + } + }, + "id": 1568, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3086:24:6", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_contract$_IRealitio_v2_1_$1502", + "typeString": "contract IRealitio_v2_1" + } + }, + "id": 1569, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "assignWinnerAndSubmitAnswerByArbitrator", + "nodeType": "MemberAccess", + "referencedDeclaration": 1501, + "src": "3086:64:6", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_bytes32_$_t_bytes32_$_t_address_$_t_bytes32_$_t_bytes32_$_t_address_$returns$__$", + "typeString": "function (bytes32,bytes32,address,bytes32,bytes32,address) external" + } + }, + "id": 1583, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3086:206:6", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1584, + "nodeType": "ExpressionStatement", + "src": "3086:206:6" + } + ] + }, + "documentation": { + "id": 1530, + "nodeType": "StructuredDocumentation", + "src": "1810:766:6", + "text": "@dev Reports the answer to a specified question from the Kleros arbitrator to the Realitio v2.1 contract.\n This can be called by anyone, after the dispute gets a ruling from Kleros.\nWe can't directly call `assignWinnerAndSubmitAnswerByArbitrator` inside `rule` because of extra parameters (e.g. _lastHistoryHash).\n @param _questionID The ID of Realitio question.\n @param _lastHistoryHash The history hash given with the last answer to the question in the Realitio contract.\n @param _lastAnswerOrCommitmentID The last answer given, or its commitment ID if it was a commitment, to the question in the Realitio contract, in bytes32.\n @param _lastAnswerer The last answerer to the question in the Realitio contract." + }, + "functionSelector": "e32511da", + "id": 1586, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "reportAnswer", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1539, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1532, + "mutability": "mutable", + "name": "_questionID", + "nodeType": "VariableDeclaration", + "scope": 1586, + "src": "2612:19:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1531, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2612:7:6", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1534, + "mutability": "mutable", + "name": "_lastHistoryHash", + "nodeType": "VariableDeclaration", + "scope": 1586, + "src": "2641:24:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1533, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2641:7:6", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1536, + "mutability": "mutable", + "name": "_lastAnswerOrCommitmentID", + "nodeType": "VariableDeclaration", + "scope": 1586, + "src": "2675:33:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1535, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2675:7:6", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1538, + "mutability": "mutable", + "name": "_lastAnswerer", + "nodeType": "VariableDeclaration", + "scope": 1586, + "src": "2718:21:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 1537, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2718:7:6", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "2602:143:6" + }, + "returnParameters": { + "id": 1540, + "nodeType": "ParameterList", + "parameters": [], + "src": "2755:0:6" + }, + "scope": 1587, + "src": "2581:718:6", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + } + ], + "scope": 1588, + "src": "1135:2191:6" + } + ], + "src": "194:3133:6" + }, + "legacyAST": { + "attributes": { + "absolutePath": "/home/f/repos/realitio-arbitrator-with-appeals/contracts/v2.1/Realitio_v2_1_ArbitratorWithAppeals.sol", + "exportedSymbols": { + "CappedMath": [ + 1969 + ], + "IArbitrable": [ + 1755 + ], + "IArbitrator": [ + 1847 + ], + "IDisputeResolver": [ + 1733 + ], + "IEvidence": [ + 1881 + ], + "IRealitioArbitrator": [ + 24 + ], + "IRealitioBase": [ + 38 + ], + "IRealitio_v2_1": [ + 1502 + ], + "RealitioArbitratorWithAppealsBase": [ + 1234 + ], + "Realitio_v2_1_ArbitratorWithAppeals": [ + 1587 + ] + }, + "license": "MIT" + }, + "children": [ + { + "attributes": { + "literals": [ + "solidity", + "^", + "0.7", + ".0" + ] + }, + "id": 1504, + "name": "PragmaDirective", + "src": "194:23:6" + }, + { + "attributes": { + "literals": [ + "abicoder", + "v2" + ] + }, + "id": 1505, + "name": "PragmaDirective", + "src": "218:19:6" + }, + { + "attributes": { + "SourceUnit": 1503, + "absolutePath": "/home/f/repos/realitio-arbitrator-with-appeals/contracts/v2.1/IRealitio_v2_1.sol", + "file": "./IRealitio_v2_1.sol", + "scope": 1588, + "symbolAliases": [ + null + ], + "unitAlias": "" + }, + "id": 1506, + "name": "ImportDirective", + "src": "239:30:6" + }, + { + "attributes": { + "SourceUnit": 1235, + "absolutePath": "/home/f/repos/realitio-arbitrator-with-appeals/contracts/RealitioArbitratorWithAppealsBase.sol", + "file": "../RealitioArbitratorWithAppealsBase.sol", + "scope": 1588, + "symbolAliases": [ + null + ], + "unitAlias": "" + }, + "id": 1507, + "name": "ImportDirective", + "src": "270:50:6" + }, + { + "attributes": { + "abstract": false, + "contractDependencies": [ + 24, + 1234, + 1733, + 1755, + 1881 + ], + "contractKind": "contract", + "fullyImplemented": true, + "linearizedBaseContracts": [ + 1587, + 1234, + 24, + 1733, + 1881, + 1755 + ], + "name": "Realitio_v2_1_ArbitratorWithAppeals", + "scope": 1588 + }, + "children": [ + { + "attributes": { + "text": " @title Realitio_v2_1_ArbitratorWithAppeals\n @dev A Realitio arbitrator implementation that uses Realitio v2.1 and Kleros. It notifies Realitio contract for arbitration requests and creates corresponding dispute on Kleros. Transmits Kleros ruling to Realitio contract. Maintains crowdfunded appeals and notifies Kleros contract. Provides a function to submit evidence for Kleros dispute.\n There is a conversion between Kleros ruling and Realitio answer and there is a need for shifting by 1. This is because ruling 0 in Kleros signals tie or no-ruling but in Realitio 0 is a valid answer. For reviewers this should be a focus as it's quite easy to get confused. Any mistakes on this conversion will render this contract useless.\n NOTE: This contract trusts the Kleros arbitrator and Realitio." + }, + "id": 1508, + "name": "StructuredDocumentation", + "src": "322:812:6" + }, + { + "attributes": {}, + "children": [ + { + "attributes": { + "name": "RealitioArbitratorWithAppealsBase", + "referencedDeclaration": 1234, + "type": "contract RealitioArbitratorWithAppealsBase" + }, + "id": 1509, + "name": "UserDefinedTypeName", + "src": "1183:33:6" + } + ], + "id": 1510, + "name": "InheritanceSpecifier", + "src": "1183:33:6" + }, + { + "attributes": { + "implemented": true, + "isConstructor": true, + "kind": "constructor", + "name": "", + "scope": 1587, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + }, + "children": [ + { + "attributes": { + "text": "@dev Constructor.\n @param _realitio The address of the Realitio contract.\n @param _metadata The metadata required for RealitioArbitrator.\n @param _arbitrator The address of the ERC792 arbitrator.\n @param _arbitratorExtraData The extra data used to raise a dispute in the ERC792 arbitrator." + }, + "id": 1511, + "name": "StructuredDocumentation", + "src": "1223:329:6" + }, + { + "children": [ + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "_realitio", + "scope": 1529, + "stateVariable": false, + "storageLocation": "default", + "type": "address", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "address", + "stateMutability": "nonpayable", + "type": "address" + }, + "id": 1512, + "name": "ElementaryTypeName", + "src": "1578:7:6" + } + ], + "id": 1513, + "name": "VariableDeclaration", + "src": "1578:17:6" + }, + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "_metadata", + "scope": 1529, + "stateVariable": false, + "storageLocation": "memory", + "type": "string", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "string", + "type": "string" + }, + "id": 1514, + "name": "ElementaryTypeName", + "src": "1605:6:6" + } + ], + "id": 1515, + "name": "VariableDeclaration", + "src": "1605:23:6" + }, + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "_arbitrator", + "scope": 1529, + "stateVariable": false, + "storageLocation": "default", + "type": "contract IArbitrator", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "IArbitrator", + "referencedDeclaration": 1847, + "type": "contract IArbitrator" + }, + "id": 1516, + "name": "UserDefinedTypeName", + "src": "1638:11:6" + } + ], + "id": 1517, + "name": "VariableDeclaration", + "src": "1638:23:6" + }, + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "_arbitratorExtraData", + "scope": 1529, + "stateVariable": false, + "storageLocation": "memory", + "type": "bytes", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "bytes", + "type": "bytes" + }, + "id": 1518, + "name": "ElementaryTypeName", + "src": "1671:5:6" + } + ], + "id": 1519, + "name": "VariableDeclaration", + "src": "1671:33:6" + } + ], + "id": 1520, + "name": "ParameterList", + "src": "1568:142:6" + }, + { + "attributes": { + "parameters": [ + null + ] + }, + "children": [], + "id": 1527, + "name": "ParameterList", + "src": "1802:0:6" + }, + { + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1234, + "type": "type(contract RealitioArbitratorWithAppealsBase)", + "value": "RealitioArbitratorWithAppealsBase" + }, + "id": 1521, + "name": "Identifier", + "src": "1711:33:6" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1513, + "type": "address", + "value": "_realitio" + }, + "id": 1522, + "name": "Identifier", + "src": "1745:9:6" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1515, + "type": "string memory", + "value": "_metadata" + }, + "id": 1523, + "name": "Identifier", + "src": "1756:9:6" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1517, + "type": "contract IArbitrator", + "value": "_arbitrator" + }, + "id": 1524, + "name": "Identifier", + "src": "1767:11:6" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1519, + "type": "bytes memory", + "value": "_arbitratorExtraData" + }, + "id": 1525, + "name": "Identifier", + "src": "1780:20:6" + } + ], + "id": 1526, + "name": "ModifierInvocation", + "src": "1711:90:6" + }, + { + "attributes": { + "statements": [ + null + ] + }, + "children": [], + "id": 1528, + "name": "Block", + "src": "1802:2:6" + } + ], + "id": 1529, + "name": "FunctionDefinition", + "src": "1557:247:6" + }, + { + "attributes": { + "functionSelector": "e32511da", + "implemented": true, + "isConstructor": false, + "kind": "function", + "modifiers": [ + null + ], + "name": "reportAnswer", + "scope": 1587, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + "children": [ + { + "attributes": { + "text": "@dev Reports the answer to a specified question from the Kleros arbitrator to the Realitio v2.1 contract.\n This can be called by anyone, after the dispute gets a ruling from Kleros.\nWe can't directly call `assignWinnerAndSubmitAnswerByArbitrator` inside `rule` because of extra parameters (e.g. _lastHistoryHash).\n @param _questionID The ID of Realitio question.\n @param _lastHistoryHash The history hash given with the last answer to the question in the Realitio contract.\n @param _lastAnswerOrCommitmentID The last answer given, or its commitment ID if it was a commitment, to the question in the Realitio contract, in bytes32.\n @param _lastAnswerer The last answerer to the question in the Realitio contract." + }, + "id": 1530, + "name": "StructuredDocumentation", + "src": "1810:766:6" + }, + { + "children": [ + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "_questionID", + "scope": 1586, + "stateVariable": false, + "storageLocation": "default", + "type": "bytes32", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "bytes32", + "type": "bytes32" + }, + "id": 1531, + "name": "ElementaryTypeName", + "src": "2612:7:6" + } + ], + "id": 1532, + "name": "VariableDeclaration", + "src": "2612:19:6" + }, + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "_lastHistoryHash", + "scope": 1586, + "stateVariable": false, + "storageLocation": "default", + "type": "bytes32", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "bytes32", + "type": "bytes32" + }, + "id": 1533, + "name": "ElementaryTypeName", + "src": "2641:7:6" + } + ], + "id": 1534, + "name": "VariableDeclaration", + "src": "2641:24:6" + }, + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "_lastAnswerOrCommitmentID", + "scope": 1586, + "stateVariable": false, + "storageLocation": "default", + "type": "bytes32", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "bytes32", + "type": "bytes32" + }, + "id": 1535, + "name": "ElementaryTypeName", + "src": "2675:7:6" + } + ], + "id": 1536, + "name": "VariableDeclaration", + "src": "2675:33:6" + }, + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "_lastAnswerer", + "scope": 1586, + "stateVariable": false, + "storageLocation": "default", + "type": "address", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "address", + "stateMutability": "nonpayable", + "type": "address" + }, + "id": 1537, + "name": "ElementaryTypeName", + "src": "2718:7:6" + } + ], + "id": 1538, + "name": "VariableDeclaration", + "src": "2718:21:6" + } + ], + "id": 1539, + "name": "ParameterList", + "src": "2602:143:6" + }, + { + "attributes": { + "parameters": [ + null + ] + }, + "children": [], + "id": 1540, + "name": "ParameterList", + "src": "2755:0:6" + }, + { + "children": [ + { + "attributes": { + "assignments": [ + 1542 + ] + }, + "children": [ + { + "attributes": { + "constant": false, + "mutability": "mutable", + "name": "arbitrationRequest", + "scope": 1585, + "stateVariable": false, + "storageLocation": "storage", + "type": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest", + "visibility": "internal" + }, + "children": [ + { + "attributes": { + "name": "ArbitrationRequest", + "referencedDeclaration": 107, + "type": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest" + }, + "id": 1541, + "name": "UserDefinedTypeName", + "src": "2765:18:6" + } + ], + "id": 1542, + "name": "VariableDeclaration", + "src": "2765:45:6" + }, + { + "attributes": { + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "type": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage ref" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 131, + "type": "mapping(uint256 => struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage ref)", + "value": "arbitrationRequests" + }, + "id": 1543, + "name": "Identifier", + "src": "2813:19:6" + }, + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": [ + null + ], + "tryCall": false, + "type": "uint256", + "type_conversion": true + }, + "children": [ + { + "attributes": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "type": "type(uint256)" + }, + "children": [ + { + "attributes": { + "name": "uint256" + }, + "id": 1544, + "name": "ElementaryTypeName", + "src": "2833:7:6" + } + ], + "id": 1545, + "name": "ElementaryTypeNameExpression", + "src": "2833:7:6" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1532, + "type": "bytes32", + "value": "_questionID" + }, + "id": 1546, + "name": "Identifier", + "src": "2841:11:6" + } + ], + "id": 1547, + "name": "FunctionCall", + "src": "2833:20:6" + } + ], + "id": 1548, + "name": "IndexAccess", + "src": "2813:41:6" + } + ], + "id": 1549, + "name": "VariableDeclarationStatement", + "src": "2765:89:6" + }, + { + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": [ + null + ], + "tryCall": false, + "type": "tuple()", + "type_conversion": false + }, + "children": [ + { + "attributes": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_7b12e68595b54b95620c01e48f1dc5573a4c5ef17b89e01ed1eb1d416d772095", + "typeString": "literal_string \"The status should be Ruled.\"" + } + ], + "overloadedDeclarations": [ + 4294967278, + 4294967278 + ], + "referencedDeclaration": 4294967278, + "type": "function (bool,string memory) pure", + "value": "require" + }, + "id": 1550, + "name": "Identifier", + "src": "2864:7:6" + }, + { + "attributes": { + "commonType": { + "typeIdentifier": "t_enum$_Status_$95", + "typeString": "enum RealitioArbitratorWithAppealsBase.Status" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "==", + "type": "bool" + }, + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "status", + "referencedDeclaration": 97, + "type": "enum RealitioArbitratorWithAppealsBase.Status" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1542, + "type": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage pointer", + "value": "arbitrationRequest" + }, + "id": 1551, + "name": "Identifier", + "src": "2872:18:6" + } + ], + "id": 1552, + "name": "MemberAccess", + "src": "2872:25:6" + }, + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "member_name": "Ruled", + "type": "enum RealitioArbitratorWithAppealsBase.Status" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 95, + "type": "type(enum RealitioArbitratorWithAppealsBase.Status)", + "value": "Status" + }, + "id": 1553, + "name": "Identifier", + "src": "2901:6:6" + } + ], + "id": 1554, + "name": "MemberAccess", + "src": "2901:12:6" + } + ], + "id": 1555, + "name": "BinaryOperation", + "src": "2872:41:6" + }, + { + "attributes": { + "hexvalue": "546865207374617475732073686f756c642062652052756c65642e", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "token": "string", + "type": "literal_string \"The status should be Ruled.\"", + "value": "The status should be Ruled." + }, + "id": 1556, + "name": "Literal", + "src": "2915:29:6" + } + ], + "id": 1557, + "name": "FunctionCall", + "src": "2864:81:6" + } + ], + "id": 1558, + "name": "ExpressionStatement", + "src": "2864:81:6" + }, + { + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "enum RealitioArbitratorWithAppealsBase.Status" + }, + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "member_name": "status", + "referencedDeclaration": 97, + "type": "enum RealitioArbitratorWithAppealsBase.Status" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1542, + "type": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage pointer", + "value": "arbitrationRequest" + }, + "id": 1559, + "name": "Identifier", + "src": "2956:18:6" + } + ], + "id": 1561, + "name": "MemberAccess", + "src": "2956:25:6" + }, + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "member_name": "Reported", + "type": "enum RealitioArbitratorWithAppealsBase.Status" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 95, + "type": "type(enum RealitioArbitratorWithAppealsBase.Status)", + "value": "Status" + }, + "id": 1562, + "name": "Identifier", + "src": "2984:6:6" + } + ], + "id": 1563, + "name": "MemberAccess", + "src": "2984:15:6" + } + ], + "id": 1564, + "name": "Assignment", + "src": "2956:43:6" + } + ], + "id": 1565, + "name": "ExpressionStatement", + "src": "2956:43:6" + }, + { + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": [ + null + ], + "tryCall": false, + "type": "tuple()", + "type_conversion": false + }, + "children": [ + { + "attributes": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "member_name": "assignWinnerAndSubmitAnswerByArbitrator", + "referencedDeclaration": 1501, + "type": "function (bytes32,bytes32,address,bytes32,bytes32,address) external" + }, + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": [ + null + ], + "tryCall": false, + "type": "contract IRealitio_v2_1", + "type_conversion": true + }, + "children": [ + { + "attributes": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1502, + "type": "type(contract IRealitio_v2_1)", + "value": "IRealitio_v2_1" + }, + "id": 1566, + "name": "Identifier", + "src": "3086:14:6" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 56, + "type": "address", + "value": "realitio" + }, + "id": 1567, + "name": "Identifier", + "src": "3101:8:6" + } + ], + "id": 1568, + "name": "FunctionCall", + "src": "3086:24:6" + } + ], + "id": 1569, + "name": "MemberAccess", + "src": "3086:64:6" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1532, + "type": "bytes32", + "value": "_questionID" + }, + "id": 1570, + "name": "Identifier", + "src": "3151:11:6" + }, + { + "attributes": { + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": [ + null + ], + "tryCall": false, + "type": "bytes32", + "type_conversion": true + }, + "children": [ + { + "attributes": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "type": "type(bytes32)" + }, + "children": [ + { + "attributes": { + "name": "bytes32" + }, + "id": 1571, + "name": "ElementaryTypeName", + "src": "3164:7:6" + } + ], + "id": 1572, + "name": "ElementaryTypeNameExpression", + "src": "3164:7:6" + }, + { + "attributes": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "-", + "type": "uint256" + }, + "children": [ + { + "attributes": { + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "answer", + "referencedDeclaration": 103, + "type": "uint256" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1542, + "type": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage pointer", + "value": "arbitrationRequest" + }, + "id": 1573, + "name": "Identifier", + "src": "3172:18:6" + } + ], + "id": 1574, + "name": "MemberAccess", + "src": "3172:25:6" + }, + { + "attributes": { + "hexvalue": "31", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "token": "number", + "type": "int_const 1", + "value": "1" + }, + "id": 1575, + "name": "Literal", + "src": "3200:1:6" + } + ], + "id": 1576, + "name": "BinaryOperation", + "src": "3172:29:6" + } + ], + "id": 1577, + "name": "FunctionCall", + "src": "3164:38:6" + }, + { + "attributes": { + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "disputer", + "referencedDeclaration": 99, + "type": "address" + }, + "children": [ + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1542, + "type": "struct RealitioArbitratorWithAppealsBase.ArbitrationRequest storage pointer", + "value": "arbitrationRequest" + }, + "id": 1578, + "name": "Identifier", + "src": "3204:18:6" + } + ], + "id": 1579, + "name": "MemberAccess", + "src": "3204:27:6" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1534, + "type": "bytes32", + "value": "_lastHistoryHash" + }, + "id": 1580, + "name": "Identifier", + "src": "3233:16:6" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1536, + "type": "bytes32", + "value": "_lastAnswerOrCommitmentID" + }, + "id": 1581, + "name": "Identifier", + "src": "3251:25:6" + }, + { + "attributes": { + "overloadedDeclarations": [ + null + ], + "referencedDeclaration": 1538, + "type": "address", + "value": "_lastAnswerer" + }, + "id": 1582, + "name": "Identifier", + "src": "3278:13:6" + } + ], + "id": 1583, + "name": "FunctionCall", + "src": "3086:206:6" + } + ], + "id": 1584, + "name": "ExpressionStatement", + "src": "3086:206:6" + } + ], + "id": 1585, + "name": "Block", + "src": "2755:544:6" + } + ], + "id": 1586, + "name": "FunctionDefinition", + "src": "2581:718:6" + } + ], + "id": 1587, + "name": "ContractDefinition", + "src": "1135:2191:6" + } + ], + "id": 1588, + "name": "SourceUnit", + "src": "194:3133:6" + }, + "compiler": { + "name": "solc", + "version": "0.7.6+commit.7338295f.Emscripten.clang" + }, + "networks": {}, + "schemaVersion": "3.4.0", + "updatedAt": "2021-05-24T04:53:05.339Z", + "devdoc": { + "details": "A Realitio arbitrator implementation that uses Realitio v2.1 and Kleros. It notifies Realitio contract for arbitration requests and creates corresponding dispute on Kleros. Transmits Kleros ruling to Realitio contract. Maintains crowdfunded appeals and notifies Kleros contract. Provides a function to submit evidence for Kleros dispute. There is a conversion between Kleros ruling and Realitio answer and there is a need for shifting by 1. This is because ruling 0 in Kleros signals tie or no-ruling but in Realitio 0 is a valid answer. For reviewers this should be a focus as it's quite easy to get confused. Any mistakes on this conversion will render this contract useless. NOTE: This contract trusts the Kleros arbitrator and Realitio.", + "kind": "dev", + "methods": { + "changeGovernor(address)": { + "params": { + "_governor": "The address of the new governor." + } + }, + "changeMetaEvidence(string)": { + "details": "Updates the meta evidence used for disputes. This function needs to be executed at least once before requesting arbitration, because we don't emit MetaEvidence during construction.", + "params": { + "_metaEvidence": "URI to the new meta evidence file." + } + }, + "changeMultipliers(uint256,uint256,uint256)": { + "details": "Changes the proportion of appeal fees that must be paid by winner and loser and changes the appeal period portion for losers.", + "params": { + "_loserAppealPeriodMultiplier": "The new loser appeal period multiplier respect to DENOMINATOR.", + "_loserStakeMultiplier": "The new loser stake multiplier value respect to DENOMINATOR.", + "_winnerStakeMultiplier": "The new winner stake multiplier value respect to DENOMINATOR." + } + }, + "constructor": { + "details": "Constructor.", + "params": { + "_arbitrator": "The address of the ERC792 arbitrator.", + "_arbitratorExtraData": "The extra data used to raise a dispute in the ERC792 arbitrator.", + "_metadata": "The metadata required for RealitioArbitrator.", + "_realitio": "The address of the Realitio contract." + } + }, + "fundAppeal(uint256,uint256)": { + "details": "TRUSTED. Manages crowdfunded appeals contributions and calls appeal function of the Kleros arbitrator to appeal a dispute. Note that we don’t need to check that msg.value is enough to pay arbitration fees as it’s the responsibility of the arbitrator contract.", + "params": { + "_questionID": "Identifier of the Realitio question, casted to uint. This also serves as the local identifier in this contract.", + "_ruling": "The ruling option to which the caller wants to contribute to." + }, + "returns": { + "fullyFunded": "True if the ruling option got fully funded as a result of this contribution." + } + }, + "getDisputeFee(bytes32)": { + "details": "Returns arbitration fee by calling arbitrationCost function in the arbitrator contract.", + "returns": { + "fee": "Arbitration that needs to be paid." + } + }, + "getMultipliers()": { + "details": "Calculate history has for givenReturns multipliers for appeals.", + "returns": { + "_denominator": "Multiplier denominator in basis points. Required for achieving floating-point-like behavior.", + "_loserAppealPeriodMultiplier": "Losers appeal period multiplier. The loser is given less time to fund its appeal to defend against last minute appeal funding attacks.", + "_loserStakeMultiplier": "Losers stake multiplier.", + "_winnerStakeMultiplier": "Winners stake multiplier." + } + }, + "getTotalWithdrawableAmount(uint256,address,uint256[])": { + "details": "Returns the sum of withdrawable amount.", + "params": { + "_contributedTo": "Ruling options to look for potential withdrawals.", + "_contributor": "The contributor for which to query.", + "_questionID": "Identifier of the Realitio question, casted to uint. This also serves as the local identifier in this contract." + }, + "returns": { + "sum": "The total amount available to withdraw." + } + }, + "numberOfRulingOptions(uint256)": { + "details": "Returns number of possible ruling options. Valid rulings are [0, count].", + "returns": { + "count": "The number of ruling options." + } + }, + "reportAnswer(bytes32,bytes32,bytes32,address)": { + "details": "Reports the answer to a specified question from the Kleros arbitrator to the Realitio v2.1 contract. This can be called by anyone, after the dispute gets a ruling from Kleros. We can't directly call `assignWinnerAndSubmitAnswerByArbitrator` inside `rule` because of extra parameters (e.g. _lastHistoryHash).", + "params": { + "_lastAnswerOrCommitmentID": "The last answer given, or its commitment ID if it was a commitment, to the question in the Realitio contract, in bytes32.", + "_lastAnswerer": "The last answerer to the question in the Realitio contract.", + "_lastHistoryHash": "The history hash given with the last answer to the question in the Realitio contract.", + "_questionID": "The ID of Realitio question." + } + }, + "requestArbitration(bytes32,uint256)": { + "details": "Request arbitration from Kleros for given _questionID.", + "params": { + "_maxPrevious": "If specified, reverts if a bond higher than this was submitted after you sent your transaction.", + "_questionID": "The question identifier in Realitio contract." + }, + "returns": { + "disputeID": "ID of the resulting dispute on arbitrator." + } + }, + "rule(uint256,uint256)": { + "details": "Receives ruling from Kleros and enforces it.", + "params": { + "_disputeID": "ID of Kleros dispute.", + "_ruling": "Ruling that is given by Kleros. This needs to be converted to Realitio answer before reporting the answer by shifting by 1." + } + }, + "submitEvidence(uint256,string)": { + "details": "Allows to submit evidence for a given dispute.", + "params": { + "_evidenceURI": "Link to evidence.", + "_questionID": "Realitio question identifier." + } + }, + "withdrawFeesAndRewards(uint256,address,uint256,uint256)": { + "details": "Allows to withdraw any reimbursable fees or rewards after the dispute gets solved.", + "params": { + "_contributor": "The address whose rewards to withdraw.", + "_questionID": "Identifier of the Realitio question, casted to uint. This also serves as the local identifier in this contract.", + "_roundNumber": "The number of the round caller wants to withdraw from.", + "_ruling": "Ruling that received contribution from contributor." + }, + "returns": { + "amount": "The amount available to withdraw for given question, contributor, round number and ruling option." + } + }, + "withdrawFeesAndRewardsForAllRounds(uint256,address,uint256[])": { + "details": "Allows to withdraw any rewards or reimbursable fees after the dispute gets resolved. For multiple rulings options and for all rounds at once. This function has O(m*n) time complexity where m is number of rounds and n is the number of ruling options contributed by given user. It is safe to assume m is always less than 10 as appeal cost growth order is O(m^2).", + "params": { + "_contributedTo": "Rulings that received contributions from contributor.", + "_contributor": "The address whose rewards to withdraw.", + "_questionID": "Identifier of the Realitio question, casted to uint. This also serves as the local identifier in this contract." + } + }, + "withdrawFeesAndRewardsForMultipleRulings(uint256,address,uint256,uint256[])": { + "details": "Allows to withdraw any reimbursable fees or rewards after the dispute gets solved. For multiple ruling options at once. This function has O(n) time complexity where n is number of ruling options contributed by given user. It is safe to assume n is always less than 3 as it does not make sense to contribute to different ruling options in the same round, so it will rarely be greater than 1.", + "params": { + "_contributedTo": "Rulings that received contributions from contributor.", + "_contributor": "The address whose rewards to withdraw.", + "_questionID": "Identifier of the Realitio question, casted to uint. This also serves as the local identifier in this contract.", + "_roundNumber": "The number of the round caller wants to withdraw from." + } + } + }, + "title": "Realitio_v2_1_ArbitratorWithAppeals", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "changeGovernor(address)": { + "notice": "Changes the address of the governor." + } + }, + "version": 1 + } +} \ No newline at end of file diff --git a/lib/create-db.ts b/lib/create-db.ts index af034e6..2ec739d 100644 --- a/lib/create-db.ts +++ b/lib/create-db.ts @@ -45,9 +45,30 @@ const Database = require('better-sqlite3'); report_allowance INTEGER, evidence_allowance INTEGER, timestamp_refresh INTEGER, + timestamp_parole INTEGER, PRIMARY KEY (platform, group_id, user_id))` ); + /** + * `question_id` is the id of the question in reality.eth + * `platform` can be `telegram`, `reddit`, etc. + * `group_id` is the id of the group on the platform (eg. group on telegram, subreddit on reddit, etc.). + * `user_id` is the id of the banned user in `platform`. + * `chat_id` is the id of the banned user in `platform`. + * `active` indicates whether the user is currently banned. + * `finalized` indicates if the question has finalized. + */ + await db.exec( + `CREATE TABLE banHistory ( + platform TEXT, + group_id TEXT, + user_id TEXT, + ban_level INTEGER, + count_current_level_optimistic_bans INTEGER, + timestamp_ban INTEGER, + PRIMARY KEY (platform, group_id, user_id))` + ); + /** * `platform` can be `telegram`, `reddit`, etc. * `group_id` is the id of the group on the platform (eg. group on telegram, subreddit on reddit, etc.). @@ -78,9 +99,17 @@ const Database = require('better-sqlite3'); platform TEXT, group_id TEXT, user_id TEXT, + username TEXT, msg_id TEXT, timestamp INTEGER, - evidenceIndex INTEGER + evidenceIndex INTEGER, + msgBackup TEXT, + active_timestamp INTEGER, + active BIT, + banLevel BIT, + finalized BIT, + timestamp_finalized INTEGER, + disputed BIT )` ); @@ -101,5 +130,22 @@ const Database = require('better-sqlite3'); PRIMARY KEY (platform, owner_user_id))` ); + /** + * `question_id` is the id of the question in reality.eth + * `platform` can be `telegram`, `reddit`, etc. + * `group_id` is the id of the group on the platform (eg. group on telegram, subreddit on reddit, etc.). + * `user_id` is the id of the banned user in `platform`. + * `chat_id` is the id of the banned user in `platform`. + * `active` indicates whether the user is currently banned. + * `finalized` indicates if the question has finalized. + */ + await db.exec( + `CREATE TABLE cron ( + bot_index INTEGER, + last_block INTEGER, + last_timestamp INTEGER, + PRIMARY KEY (bot_index))` + ); + db.close(); })(); \ No newline at end of file diff --git a/lib/cron.ts b/lib/cron.ts index b1b9a0c..ce9e9a7 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -1,16 +1,18 @@ require('dotenv').config() -const ModeratorBot = require('node-telegram-bot-api'); -import {openDb, getChannelID, getLang} from "./db"; +import {openDb, getGroupSettings, getRule, getCron, setCron, getReportMessageTimestampAndActive, setBanHistory, setReport, getBanHistory} from "./db"; import request from "graphql-request"; import {BigNumber} from "ethers"; import TelegramBot from "node-telegram-bot-api"; import langJson from "./telegram/assets/lang.json"; import {Wallet} from "@ethersproject/wallet"; - +import {groupSettings, groupSettingsUnderspecified} from "../types"; +const ModeratorBot = require('node-telegram-bot-api'); +const NodeCache = require( "node-cache" ); +const Web3 = require('web3') +const realitio_bot = require('./realitioReporting') +const myCache = new NodeCache( { stdTTL: 900, checkperiod: 1200 } ); const db = openDb(); const bot: TelegramBot = new ModeratorBot(process.env.BOT_TOKEN, {polling: false}); -const channelIDs : Map = new Map(); -const lang : Map = new Map(); // Only need DB for // - channelID @@ -21,18 +23,23 @@ const lang : Map = new Map(); (async ()=> { const botaddress = await (await new Wallet(process.env.PRIVATE_KEY)).address; - const timestampLastUpdated = 0; - const timestampNew = Math.floor(Date.now()/1000); + var history = getCron(db) + const web3 = new Web3(process.env.WEB3_PROVIDER_URL) + const privateKey = process.env.PRIVATE_KEY + const account = web3.eth.accounts.privateKeyToAccount(privateKey) + web3.eth.accounts.wallet.add(account) + const currentTime = Math.floor(Date.now()/1000) + const currentBlock = await web3.eth.getBlockNumber() + if (!history) + history = { + last_timestamp: currentTime, + last_block: currentBlock + } const graphSyncingPeriod = 300; - + const timestampNew = currentTime + const timestampLastUpdated = history.last_timestamp const reports = {}; - /* - var moderationTypes: string = ''; - for (const lang in templates[process.env.CHAIN_ID]) - for (const template in templates[process.env.CHAIN_ID][lang]) - moderationTypes += '\"'+process.env.REALITY_ETH_V30+'-0x'+Number(templates[process.env.CHAIN_ID][lang][template]).toString(16)+"\","; - */ // dispute final // dispute appealsPossible // dispute disputesAppeal @@ -46,23 +53,27 @@ const lang : Map = new Map(); const lastPageUpdated = 0; const queryModeration = getQuery(lastPageUpdated, timestampLastUpdated, botaddress, timestampNew, graphSyncingPeriod) - console.log(queryModeration); - + //console.log(queryModeration); + //console.log('graphtime'); + //console.log(queryModeration) const moderationActions = await request( 'https://api.thegraph.com/subgraphs/name/shotaronowhere/kleros-moderate-goerli', queryModeration ); - + console.log(JSON.stringify(moderationActions)) + for (const data of moderationActions.disputesFinal) { - const settings = getGroupSettings(data.moderationInfo.user.group.groupID); + const settings = validate(data.moderationInfo.UserHistory.group.groupID); // settings[1] language try{ - const msgLink = data.message; - const disputeURL = `https://resolve.kleros.io/${BigNumber.from(data.id).toNumber()}`; - // check rulings, note down shift since reality uses 0,1 for no, yes and kleros uses 1,2 for yes, no - const message = (data.finalRuling === 1)? 'broke the rules' : 'did not break the rules' + const msgLink = data.moderationInfo.message; + const disputeURL = `https://resolve.kleros.io/cases/${BigNumber.from(data.id).toNumber()}`; + // check rulings, note down shift since reality uses 0,1 for no, yes and kleros uses 1,2 for no, yes + const message = (data.finalRuling === 2)? 'broke the rules' : 'did not break the rules' + console.log(data.finalRuling) try{ - await bot.sendMessage(settings[0], `The [dispute](${disputeURL}) over *${data.moderationInfo.user.username}*'s [message](${msgLink}) ([backup](${data.moderationInfo.messageBackup})) resolved. *${data.moderationInfo.user.username}* ${message}`, {parse_mode: 'Markdown'}); + bot.sendMessage(settings.channelID, `The [dispute](${disputeURL}) over *${data.moderationInfo.UserHistory.user.username}*'s [message](${msgLink}) ([backup](${data.moderationInfo.messageBackup})) resolved. *${data.moderationInfo.UserHistory.user.username}* ${message}`, {parse_mode: 'Markdown'}); + handleTelegramUpdate(db, bot,settings, data.moderationInfo,timestampNew, data.finalRuling === 2, true); } catch(e){ console.log(e) } @@ -73,208 +84,221 @@ const lang : Map = new Map(); } for (const data of moderationActions.disputesAppealPossible) { - const settings = getGroupSettings(data.moderationInfo.user.group.groupID); + const settings = validate(data.moderationInfo.UserHistory.group.groupID); + const msgLink = data.moderationInfo.message; + const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; + const disputeURL = `https://resolve.kleros.io/cases/${BigNumber.from(data.id).toNumber()}`; // settings[1] language try{ - bot.sendMessage(settings[0], `The dispute id ${data.id} has concluded it's current round. The ruling is ${data.currentRuling}. An appeal is possible.`); //TODO - //await bot.sendMessage(settings[0], `The current dispute over the [question](${realityURL}) about *${report.username}*'s conduct due to the [message](${msgLink}) ([backup](${report.msgBackup})) has concluded it's current round. *${report.username}*'s conduct ${disputeInfo[question.disputeId].currentRulling == 2? 'broke the rules': 'did not break the rules'} If you think the decision is incorrect, you can request an [appeal](https://resolve.kleros.io/cases/${BigNumber.from(question.disputeId).toNumber()})`, {parse_mode: 'Markdown'}); + bot.sendMessage(settings.channelID, `The dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'} If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, {parse_mode: 'Markdown', disable_web_page_preview: true}); } catch(e){ console.log(e) } } for (const data of moderationActions.disputesCreated) { - const settings = getGroupSettings(data.moderationInfo.user.group.groupID); + const settings = validate(data.moderationInfo.UserHistory.group.groupID); // settings[1] language const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; - const disputeURL = `https://resolve.kleros.io/${BigNumber.from(data.id).toNumber()}`; + const disputeURL = `https://resolve.kleros.io/cases/${BigNumber.from(data.id).toNumber()}`; try{ - await bot.sendMessage(settings[0], `Arbitration is requested for the [question](${realityURL}) about *${data.moderationInfo.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})). Consequences of the report are lifted for the duration of the [dispute](${disputeURL}) (on Gnosis Chain).`, {parse_mode: 'Markdown'}); - handleTelegramUpdateRestrict(bot,settings[0],data,timestampNew, false); + bot.sendMessage(settings.channelID, `Arbitration is requested for the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})). Consequences of the report are lifted for the duration of the [dispute](${disputeURL}) (on Gnosis Chain).`, {parse_mode: 'Markdown', disable_web_page_preview: true}); + handleTelegramUpdate(db, bot,settings, data.moderationInfo,timestampNew, false, false); } catch (e){ console.log(e) } } for (const data of moderationActions.disputesAppealFunded) { - const settings = getGroupSettings(data.moderationInfo.user.group.groupID); + const settings = validate(data.moderationInfo.UserHistory.group.groupID); // settings[1] language try{ - bot.sendMessage(settings[0], "An appeal has been funded"); + bot.sendMessage(settings.channelID, "An appeal has been funded"); } catch(e){ console.log(e) } } - +/* for(const data of moderationActions.realityQuestionUnansweredFinalized){ - const settings = getGroupSettings(data.user.group.groupID); + const settings = validate(data.moderationInfo.UserHistory.group.groupID); // settings[1] language try{ - bot.sendMessage(settings[0], `The reality question ${data.id} was unanswered`); + bot.sendMessage(settings.channelID, `The reality question ${data.id} was unanswered`); } catch(e){ console.log(e) } } - +*/ for(const data of moderationActions.realityQuestionAnsweredFinalized){ - const settings = getGroupSettings(data.moderationInfo.user.group.groupID); + const settings = validate(data.moderationInfo.UserHistory.group.groupID); // settings[1] language try{ //bot.sendMessage(settings[0], `The reality question ${data.id} is finalized with ${data.currentAnswer}`); - - await bot.sendMessage(settings[0], `The report on Reality is finalized.`, {parse_mode: 'Markdown'}); + const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; + + bot.sendMessage(settings.channelID, `The [report](${realityURL}) is finalized.`, {parse_mode: 'Markdown'}); // finalize - await handleTelegramFinalize(bot, settings[0], data, timestampNew, botaddress); + handleTelegramUpdate(db, bot, settings, data.moderationInfo, timestampNew, data.finalRuling === "0x0000000000000000000000000000000000000000000000000000000000000001", true); } catch(e){ console.log(e) } } for(const data of moderationActions.realityQuestionAnsweredNotFinalized){ - const settings = getGroupSettings(data.moderationInfo.user.group.groupID); + console.log(data.moderationInfo.UserHistory.group) + const settings = validate(data.moderationInfo.UserHistory.group.groupID); // settings[1] language try{ - bot.sendMessage(settings[0], `The reality question ${data.id} was answered with ${data.currentAnswer}`); const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; - await bot.sendMessage(settings[0], `The question, \n\n\"Did *${data.moderationInfo.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) violate the [rules](${data.moderationInfo.rules})?\",\n\nis answered with *Yes*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, {parse_mode: 'Markdown'}); - handleTelegramUpdateRestrict(bot,settings[0], data,timestampNew, data.currentAnswer.equals("0x0000000000000000000000000000000000000000000000000000000000000001")); + const answer = data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001" ? "yes" : "no"; + bot.sendMessage(settings.channelID, `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) violate the [rules](${data.moderationInfo.rules})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, {parse_mode: 'Markdown', disable_web_page_preview: true}); + handleTelegramUpdate(db, bot,settings, data.moderationInfo,timestampNew, data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001", false); } catch(e){ console.log(e) } } - for(const data of moderationActions.sheriff){ - const settings = getGroupSettings(data.group.groupID); + for(const data of moderationActions.sheriffs){ + const settings = validate(data.group.groupID); // settings[1] language try{ - bot.sendMessage(settings[0], `There's a new sheriff in town ${data.sheriff.userID}`); + const sherrif = await bot.getChatMember(data.group.groupID, data.sheriff.user.userID) + bot.sendMessage(settings.channelID, `There's a new sheriff in town 👑🥇🤠[${sherrif.user.username}](tg://user?id=${sherrif.user.id})🤠🥇👑`,{parse_mode: "Markdown"}); } catch(e){ console.log(e) } } - for(const data of moderationActions.deputySheriff){ - const settings = getGroupSettings(data.group.groupID); + for(const data of moderationActions.deputySheriffs){ + const settings = validate(data.group.groupID); // settings[1] language try{ - bot.sendMessage(settings[0], `There's a new deputy sheriff in town ${data.sheriff.userID}`); + const deputysherrif = await bot.getChatMember(data.group.groupID, data.sheriff.user.userID) + bot.sendMessage(settings.channelID, `There's a new deputy sheriff in town 🥈[${deputysherrif.user.username}](tg://user?id=${deputysherrif.user.id})🥈`); } catch(e){ console.log(e) } } + + await realitio_bot(web3, history.last_block, process.env.REALITY_ETH_V30, process.env.REALITIO_ARBITRATOR); + setCron(db, currentBlock,currentTime) return; })() -const getGroupSettings = async (chatId: number): Promise<[string, string]> => { - var language = lang.get(chatId); - if (!language){ - language = getLang(db, 'telegram', String(chatId)); - lang.set(chatId, language); - } - var channelId = channelIDs.get(chatId) - if (!channelId){ - channelId = getChannelID(db, 'telegram', String(chatId)) - if (channelId === '0'){ - channelIDs.set(chatId, String(chatId)); - channelId = String(chatId) - }else - channelIDs.set(chatId, channelId); - } - return [channelId, language] +const validate = (chatId: string): groupSettings=> { + const defaultSettings: groupSettings = { + lang: 'en', + rules: langJson['en'].defaultRules, + channelID: '', + greeting_mode: false, + thread_id_rules: '', + thread_id_welcome: '', + thread_id_notifications: '' + } + var groupSettings : groupSettingsUnderspecified = myCache.get(chatId) + if (!groupSettings){ + const rules = getRule(db, 'telegram', chatId, Math.floor(Date.now()/1000)) + groupSettings = getGroupSettings(db, 'telegram', chatId) + groupSettings.rules = rules + myCache.set(chatId, groupSettings) + } + const fullSettings = { + lang: groupSettings?.lang ?? defaultSettings.lang, + rules: groupSettings?.rules ?? defaultSettings.rules, + channelID: groupSettings?.channelID ?? chatId, + greeting_mode: groupSettings?.greeting_mode ?? defaultSettings.greeting_mode, + thread_id_rules: groupSettings?.thread_id_rules ?? defaultSettings.thread_id_rules, + thread_id_welcome: groupSettings?.thread_id_welcome ?? defaultSettings.thread_id_rules, + thread_id_notifications: groupSettings?.thread_id_notifications ?? defaultSettings.thread_id_notifications + } + return fullSettings } - -const handleTelegramUpdateRestrict = async (bot: TelegramBot, channelID: string, moderationInfo: any, timestampNew: number, restrict: boolean) => { +const handleTelegramUpdate = async (db: any, bot: TelegramBot, settings: groupSettings, moderationInfo: any, timestampNew: number, restrict: boolean, finalize: boolean) => { try{ + const reportInfo = getReportMessageTimestampAndActive(db, moderationInfo.id) + console.log(moderationInfo.id) + console.log(reportInfo) + const banHistory = getBanHistory(db, 'telegram',moderationInfo.UserHistory.group.groupID, moderationInfo.UserHistory.user.userID)?? {ban_level: 0, timestamp_ban: 0, count_current_level_optimistic_bans: 0} + setReport(db, moderationInfo.id,restrict,finalize,timestampNew) if (restrict){ var duration: string; - if(moderationInfo.user.history.countBrokeRulesArbitrated == 1) - duration = 'first time and is subject to a 1 day'; - else if (moderationInfo.user.history.countBrokeRulesArbitrated == 2) - duration = 'second time and is subject to a 1 week'; - else - duration = 'third time and is subject to a 1 year'; - - await bot.sendMessage(channelID, `*${moderationInfo.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messsageBackup})) violated the [rules](${moderationInfo.rulesUrl}) for the ${duration} ban.`, {parse_mode: 'Markdown'}); - await bot.banChatMember(moderationInfo.user.group.groupID, moderationInfo.user.userID, Number(moderationInfo.user.history.timestampParole)); + var parole: number; + if (reportInfo.timestamp > banHistory.timestamp_ban){ + if(banHistory.ban_level == 0){ + duration = 'first time and is subject to a 1 day'; + parole = timestampNew + 86400 + } else if (banHistory.ban_level == 1){ + duration = 'second time and is subject to a 1 week'; + parole = timestampNew + 604800 + } else{ + duration = 'atleast three times and is subject to a 1 year'; + parole = timestampNew + 220147200 + } + if(finalize){ + banHistory.ban_level++ + banHistory.count_current_level_optimistic_bans = 0 + banHistory.timestamp_ban = timestampNew + bot.banChatMember(moderationInfo.user.group.groupID, moderationInfo.userID, parole); + } + const options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false, until_date: parole}; + bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}) for the ${duration} ban.`, {parse_mode: 'Markdown', disable_web_page_preview: true}); + if(!finalize && reportInfo?.active !== Number(restrict)){ + //TODO Federation + bot.restrictChatMember(moderationInfo.UserHistory.group.groupID, moderationInfo.UserHistory.user.userID, options); + banHistory.count_current_level_optimistic_bans++ + } + setBanHistory(db, 'telegram',moderationInfo.UserHistory.group.groupID, moderationInfo.UserHistory.user.userID,banHistory.ban_level,banHistory.timestamp_ban,banHistory.count_current_level_optimistic_bans) + } else{ + bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messsageBackup})) violated the [rules](${moderationInfo.rulesUrl}). The conduct occured before *${moderationInfo.UserHistory.user.username}*'s latest effective ban.\nModeration is about both rehabilitation and punishment. We all make mistakes and we deserve second chances. Let's give ${moderationInfo.UserHistory.user.username} another chance. The next time ${moderationInfo.UserHistory.user.username} breaks the rules, the consequences are more severe though. Here's to healthier communities : )`, {parse_mode: 'Markdown'}); + } } else { - const options = timestampNew > Number(moderationInfo.user.history.timestampParole)? {can_send_messages: true, can_send_media_messages: true, can_send_polls: true, can_send_other_messages: true, can_add_web_page_previews: true, can_change_info: false, can_pin_messages: false}: {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false, until_date: Number(moderationInfo.user.userHistory.timestampParole)}; - await bot.restrictChatMember(moderationInfo.user.group.groupID, moderationInfo.user.userID, options); - if (timestampNew > Number(moderationInfo.user.history.timestampParole)) - await bot.sendMessage(channelID, `*${moderationInfo.user.userID}* has no other active reports. All bans are lifted.`, {parse_mode: 'Markdown'}); - else { - const date = new Date(Number(moderationInfo.user.history.timestampParole) * 1000).toISOString(); - await bot.sendMessage(moderationInfo.user.group.groupID, `*${moderationInfo.user.username}* has other active reports. The ban on *${moderationInfo.user.username}* is reduced and now expires on ${date}`, {parse_mode: 'Markdown'}); + var noOptimisticReports = 0 + if(reportInfo.active != Number(restrict)){ + setBanHistory(db, 'telegram',moderationInfo.UserHistory.group.groupID, moderationInfo.UserHistory.user.userID,banHistory.ban_level,banHistory.timestamp_ban,Math.max(banHistory.count_current_level_optimistic_bans-1,0)) + noOptimisticReports = 1 + } + if (banHistory.count_current_level_optimistic_bans === noOptimisticReports){ // only optimistic report removed. + const options = {can_send_messages: true, can_send_media_messages: true, can_send_polls: true, can_send_other_messages: true, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false}; + bot.restrictChatMember(moderationInfo.UserHistory.group.groupID, moderationInfo.UserHistory.user.userID, options); + bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}* has no other active reports. All bans are lifted.`, {parse_mode: 'Markdown'}); + } else { + bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}* has other active reports, and is still restricted.`, {parse_mode: 'Markdown'}); } } } catch(e){ console.log(e) - await bot.sendMessage(moderationInfo.user.group.groupID, `My admin rights are limited. I am unable to lift the ban/mute duration for *${moderationInfo.user.username}*. Please ask an admin.`); } } -const handleTelegramFinalize = async (bot: TelegramBot, channelID: string, realityCheck: any, timestampNew: number, botaddress: string) => { - const finalizedCount = await getFinalizedCount(realityCheck.moderationInfo.user, timestampNew, botaddress); - if (finalizedCount == 1){ - - } - var duration: string; - if(finalizedCount == 1) - duration = 'first time and is subject to a 1 day'; - else if (finalizedCount == 2) - duration = 'second time and is subject to a 1 week'; - else - duration = 'third time and is subject to a 1 year'; - try{ - await bot.sendMessage(channelID, `*${realityCheck.moderationInfo.user.username}*'s conduct due to this [message](${realityCheck.moderationInfo.message}) ([backup](${realityCheck.moderationInfo.messsageBackup})) violated the [rules](${realityCheck.moderationInfo.rulesUrl}) for the ${duration} ban.`, {parse_mode: 'Markdown'}); - await bot.banChatMember(realityCheck.moderationInfo.user.group.groupID, realityCheck.moderationInfo.userID, Number(realityCheck.moderationInfo.user.history.timestampParole)); - - } catch(e){ - await bot.sendMessage(channelID, `My admin rights are limited. I am unable to lift any active mute on *${realityCheck.moderationInfo.user.username}*. Please ask an admin to remove any mute related to this question.`); - } -} - - -const getFinalizedCount = async (moderationInfo: any, timestampNew: number, botaddress: string): Promise => { - const queryOptimisticallyFinalized =`{ - realityChecks(where: {deadline_lt: ${timestampNew}, currentAnswer: "0x0000000000000000000000000000000000000000000000000000000000000001", moderationInfo_: {askedBy: "${botaddress}", user: "${moderationInfo.user}"}}) { - id - } - }`; - const moderationActions = await request( - 'https://api.thegraph.com/subgraphs/name/shotaronowhere/kleros-moderate-goerli', - queryOptimisticallyFinalized - ); - return moderationInfo.user.history.countBrokeRulesArbitrated + moderationActions.data.length; -} - const getQuery = (lastPageUpdated: number, timestampLastUpdated: number, botaddress: string, timestampNew: number, graphSyncingPeriod: number): string => { const moderationInfoContent = ` id message messageBackup moderationType rulesUrl - user { - username - userID + UserHistory{ + timestampParole + countBrokeRulesArbitrated group { groupID } - history{ - timestampParole - countBrokeRulesArbitrated + user { + username + userID } }`; const moderationInfo = `moderationInfo { ${moderationInfoContent} }`; return `{ - disputesFinal: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastAppealPossible_gt: ${timestampLastUpdated}, finalRuling_not: null, moderationInfo_: {askedBy: "${botaddress}"}}) { + disputesFinal: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastUpdated_gt: ${timestampLastUpdated}, finalRuling_not: null, moderationInfo_: {askedBy: "${botaddress}"}}) { id finalRuling + ${moderationInfo} } disputesAppealPossible: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastAppealPossible_gt: ${timestampLastUpdated}, finalRuling: null, moderationInfo_: {askedBy: "${botaddress}"}}) { id @@ -290,23 +314,26 @@ return `{ id ${moderationInfo} } - disputesAppealFunded: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastUpdated_gt: ${timestampLastUpdated}, rulingFunded_not: null, moderationInfo_: {askedBy: "${botaddress}"}}) { + disputesAppealFunded: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastAppealPossible_gt: ${timestampLastUpdated}, rulingFunded_not: null, moderationInfo_: {askedBy: "${botaddress}"}}) { id rulingFunded + currentRuling ${moderationInfo} } realityQuestionUnansweredFinalized: moderationInfos(first: 1000, skip: ${lastPageUpdated*1000}, where: {deadline_gt: ${timestampLastUpdated}, deadline_lt: ${timestampNew}, reality: null, askedBy: "${botaddress}"}) { ${moderationInfoContent} } - realityQuestionAnsweredFinalized: realityChecks(first: 1000, skip: ${lastPageUpdated*1000}, where: {deadline_gt: ${timestampLastUpdated}, deadline_lt: ${timestampNew - graphSyncingPeriod}, moderationInfo_: {askedBy: "${botaddress}"}}) { + realityQuestionAnsweredFinalized: realityChecks(first: 1000, skip: ${lastPageUpdated*1000}, where: {deadline_gt: ${timestampLastUpdated}, dispute: null, deadline_lt: ${timestampNew + graphSyncingPeriod}, moderationInfo_: {askedBy: "${botaddress}"}}) { id + timestampLastUpdated currentAnswer timeServed ${moderationInfo} } - realityQuestionAnsweredNotFinalized: realityChecks(first: 1000, skip: ${lastPageUpdated*1000}, where: {deadline_gt: ${timestampNew}, moderationInfo_: {askedBy: "${botaddress}"}}) { + realityQuestionAnsweredNotFinalized: realityChecks(first: 1000, skip: ${lastPageUpdated*1000}, where: {deadline_gt: ${timestampNew}, dispute: null, timestampLastUpdated_gt: ${timestampLastUpdated}, moderationInfo_: {askedBy: "${botaddress}"}}) { id currentAnswer + timestampLastUpdated ${moderationInfo} } sheriffs: jannies(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastUpdatedSheriff_gt: ${timestampLastUpdated}, group_: {botAddress: "${botaddress}"}}) { @@ -315,7 +342,9 @@ return `{ groupID } sheriff{ - userID + user{ + userID + } } } deputySheriffs: jannies(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastUpdatedDeputySheriff_gt: ${timestampLastUpdated}, group_: {botAddress: "${botaddress}"}}) { @@ -324,7 +353,9 @@ return `{ groupID } deputySheriff{ - userID + user{ + userID + } } } }`; diff --git a/lib/db.ts b/lib/db.ts index e12da37..05f451b 100644 --- a/lib/db.ts +++ b/lib/db.ts @@ -94,7 +94,7 @@ const setChannelID = (db: any, platform: string, groupId: string, channel_id: st const getDisputedReportsInfo = (db:any, platform: string, groupId: string) => { try{ - const stmt = db.prepare('SELECT * FROM reports WHERE finalized = 0 AND group_id = ? AND platform = ? AND bond_paid > 0'); + const stmt = db.prepare('SELECT * FROM reports WHERE finalized = 0 AND group_id = ? AND platform = ? AND active_timestamp > 0'); return stmt.all(groupId, platform); } catch(err){ console.log("db error: getDisputedReports"); @@ -204,6 +204,17 @@ const getInviteURLChannel = (db: any, platform: string, groupId: string) => { } } + +const existsQuestionId = (db: any, question_id: string): boolean => { + try{ + const stmt = db.prepare('SELECT * FROM reports WHERE question_id = ?'); + return stmt.get(question_id)?.length > 0; + } catch(err){ + console.log("db error: getGreetingMode"); + console.log(err); + } +} + const getGreetingMode = (db: any, platform: string, groupId: string): boolean => { try{ const stmt = db.prepare('SELECT greeting_mode FROM groups WHERE platform = ? AND group_id = ?'); @@ -267,7 +278,7 @@ const getConcurrentReports = (db: any, platform: string, groupId: string, userId const getDisputedReportsUserInfo = (db:any, platform: string, groupId: string, userId: string) => { try{ - const stmt = db.prepare('SELECT * FROM reports WHERE user_id = ? AND group_id = ? AND platform = ?'); + const stmt = db.prepare('SELECT question_id, active, active_timestamp,msgBackup, msg_id, evidenceIndex, timestamp FROM reports WHERE user_id = ? AND group_id = ? AND platform = ? AND finalized = 0'); return stmt.all(userId, groupId, platform); } catch(err){ console.log("db error: getDisputedReportsUserInfo"); @@ -284,6 +295,29 @@ const getQuestionId = (db: any, platform: string, groupId: string, userId: strin } } +const getCron = (db: any): {last_timestamp: number, last_block: number} => { + try{ + const stmt = db.prepare(`SELECT last_block, last_timestamp FROM cron WHERE bot_index = 0`); + return stmt.get(); + } catch{ + console.log("db error: getCron"); + } +} + +const setCron = (db: any, last_block: number, last_timestamp: number) => { + try{ + const stmt = db.prepare( + `INSERT INTO cron (bot_index, last_block, last_timestamp) + VALUES (0, ?, ?) + ON CONFLICT(bot_index) DO UPDATE SET + last_block=?, last_timestamp=?;`); + const info = stmt.run(last_block, last_timestamp,last_block, last_timestamp); + } catch(err) { + console.log("db error: setCron"); + console.log(err); + } +} + const getRecordCount = (db: any, platform: string, groupId: string) => { try{ const stmt = db.prepare( @@ -300,23 +334,54 @@ const getRecordCount = (db: any, platform: string, groupId: string) => { const getAllowance = (db: any, platform: string, groupId: string, userId: string): {report_allowance: number, evidence_allowance: number, timestamp_refresh: number, question_id_last: string, timestamp_last_question: number} | undefined => { try{ const stmt = db.prepare('SELECT report_allowance, evidence_allowance, timestamp_refresh FROM allowance WHERE user_id = ? AND group_id = ? AND platform = ?'); - return stmt.all(userId, groupId, platform); + return stmt.get(userId, groupId, platform); } catch(e){ console.log("db error: getAllowance "+e); } } +const setReport = (db: any, questionId: string, active: boolean, finalized: boolean, activeTimestamp: number) => { + try{ + const stmt = db.prepare( + 'UPDATE reports SET active = ?, finalized = ?, active_timestamp = ? WHERE question_id = ?', + ); + const info = stmt.run(Number(active), Number(finalized), activeTimestamp, questionId); + } catch(err) { + console.log("db error: setReport"); + console.log(err); + } +} + +const getBanHistory = (db: any, platform: string, groupId: string, userId: string): {ban_level: number, timestamp_ban: number, count_current_level_optimistic_bans: number} | undefined => { + try{ + const stmt = db.prepare('SELECT ban_level, timestamp_ban, count_current_level_optimistic_bans FROM banHistory WHERE user_id = ? AND group_id = ? AND platform = ?'); + return stmt.get(userId, groupId, platform); + } catch(e){ + console.log("db error: getBanHistory "+e); + } +} + const getActiveEvidenceGroupId = (db: any, platform: string, groupId: string, evidenceIndex: number) => { try{ const stmt = db.prepare( `SELECT question_id FROM reports WHERE platform = ? AND group_id = ? AND evidenceIndex = ? AND finalized = 0`); - return stmt.get(platform, groupId, evidenceIndex); + return stmt.get(platform, groupId, evidenceIndex)?.question_id; + } catch(err) { + console.log("db error: getActiveEvidenceGroupId"); + console.log(err); + } +} + +const getUsersWithQuestionsNotFinalized = (db: any, platform: string, groupId: string) => { + try{ + const stmt = db.prepare( `SELECT DISTINCT user_id, username FROM reports WHERE platform = ? AND group_id = ? AND finalized = 0`); + return stmt.all(platform, groupId); } catch(err) { console.log("db error: getActiveEvidenceGroupId"); console.log(err); } } -const setAllowance = async( +const setAllowance = ( db: any, platform: string, groupId: string, @@ -338,6 +403,28 @@ const setAllowance = async( } } +const setBanHistory = ( + db: any, + platform: string, + groupId: string, + userId: string, + ban_level: number, + timestamp_ban: number, + count_current_level_optimistic_bans: number + ) => { + try{ + const stmt = db.prepare( + `INSERT INTO banHistory (platform, group_id, user_id, ban_level, timestamp_ban, count_current_level_optimistic_bans) + VALUES (?, ?, ?, ?, ?, ?) + ON CONFLICT(platform, group_id, user_id) DO UPDATE SET + ban_level=?, timestamp_ban = ?, count_current_level_optimistic_bans=?;` + ); + const info = stmt.run(platform, groupId, userId, ban_level, timestamp_ban,count_current_level_optimistic_bans,ban_level, timestamp_ban,count_current_level_optimistic_bans); + } catch(e) { + console.log("db error: setBanHistory"+e); + } +} + const getThreadIDWelcome = (db: any, platform: string, groupId: string) => { try{ const stmt = db.prepare('SELECT thread_id_welcome FROM groups WHERE platform = ? AND group_id = ?'); @@ -368,6 +455,16 @@ const getLang = (db:any, platform: string, groupId: string): string => { } } +const getReportMessageTimestampAndActive = (db:any, question_id: string): {timestamp: number, active: number} | undefined => { + try{ + const stmt = db.prepare('SELECT timestamp, active FROM reports WHERE question_id = ?'); + return stmt.get(question_id); + } catch(err){ + console.log("db error: getReportMessageTimestamp"); + console.log(err); + } +} + const setRules = (db:any, platform: string, groupId: string, rules: string, timestamp: number) => { try{ const stmt = db.prepare( @@ -402,7 +499,8 @@ const addReport = ( username: string, msgId: string, msgTimestamp: number, - evidenceIndex: number + evidenceIndex: number, + msgBackup: string ) => { try{ const stmt = db.prepare( @@ -411,9 +509,14 @@ const addReport = ( platform, group_id, user_id, + username, msg_id, timestamp, - evidenceIndex) + evidenceIndex, + finalized, + active, + active_timestamp, + msgBackup) VALUES ( ?, ?, @@ -422,6 +525,10 @@ const addReport = ( ?, ?, ?, + ?, + 0, + 0, + 0, ?);`); const info = stmt.run( questionId, @@ -431,7 +538,8 @@ const addReport = ( username, msgId, msgTimestamp, - evidenceIndex); + evidenceIndex, + msgBackup); } catch(e) { console.log("db error: addReport."+e); } @@ -440,6 +548,7 @@ const addReport = ( export { getInviteURL, + existsQuestionId, setInviteURL, getInviteURLChannel, setInviteURLChannel, @@ -448,11 +557,16 @@ export { setThreadIDWelcome, setAllowance, getAllowance, + setReport, addReport, + getUsersWithQuestionsNotFinalized, getQuestionId, getConcurrentReports, getActiveEvidenceGroupId, setChannelID, + setBanHistory, + getBanHistory, + getReportMessageTimestampAndActive, getDisputedReportsUserInfo, getChannelID, getDisputedReportsInfo, @@ -464,6 +578,8 @@ export { setGreetingMode, getRecordCount, setLang, + getCron, + setCron, getLang, setRules, setThreadID, diff --git a/lib/realitioReporting.ts b/lib/realitioReporting.ts new file mode 100644 index 0000000..e20fee1 --- /dev/null +++ b/lib/realitioReporting.ts @@ -0,0 +1,72 @@ +const _realitio = require('./assets/contracts/Realitio_v2_1.json') +const _proxy = require('./assets/contracts/Realitio_v2_1_ArbitratorWithAppeals.json') + +module.exports = async (web3, lastBlock, realitioAddress, proxyAddress) => { + // Instantiate the contracts. + const realitioInstance = new web3.eth.Contract( + _realitio.abi, + realitioAddress + ) + const proxyInstance = new web3.eth.Contract( + _proxy.abi, + proxyAddress + ) + // console.log(lastBlock) + const ruleEvents = await proxyInstance.getPastEvents('Ruling', { + fromBlock: lastBlock, + toBlock: 'latest' + }) + console.log('realitio reporting: '+ruleEvents.length) + + // A Ruling was made + for (const eventLog of ruleEvents) { + const _disputeID = eventLog.returnValues._disputeID + + const questionIDEvent = await proxyInstance.getPastEvents('DisputeIDToQuestionID', { + filter: { + _disputeID + }, + fromBlock: 0, + toBlock: 'latest' + }) + + if (questionIDEvent.length < 1) continue + + const questionID = questionIDEvent[0].returnValues._questionID + const question = await realitioInstance.methods.questions(questionID).call() + const bestAnswer = question.best_answer + + const answerEvents = await realitioInstance.getPastEvents('LogNewAnswer', { + fromBlock: 0, + filter: { + question_id: questionID + } + }) + + // Only 1 answer + let historyHash = '0x0000000000000000000000000000000000000000000000000000000000000000' // Blank history + if (answerEvents.length > 1) { + historyHash = answerEvents[answerEvents.length - 2].returnValues.history_hash + } + const answerer = answerEvents[answerEvents.length - 1].returnValues.user + + // DEBUG + // console.log('Reporting answer for disputeID ' + _disputeID) + // console.log(`questionID: ${questionID}`) + // console.log(`historyHash: ${historyHash}`) + // console.log(`bestAnswer: ${bestAnswer}`) + // console.log(`answerer: ${answerer}`) + + const txHash = await proxyInstance.methods.reportAnswer( + questionID, + historyHash, + bestAnswer, // Aka last answer + answerer, // Owner of best answer + ).send({ + from: web3.eth.accounts.wallet[0].address, + gas: process.env.GAS_LIMIT + }) + } + +} + diff --git a/lib/telegram/commands/addEvidence.ts b/lib/telegram/commands/addEvidence.ts index 4a26a6a..5727603 100644 --- a/lib/telegram/commands/addEvidence.ts +++ b/lib/telegram/commands/addEvidence.ts @@ -1,7 +1,8 @@ import * as TelegramBot from "node-telegram-bot-api"; import {Wallet} from "@ethersproject/wallet"; -import {ipfsPublish, ipfsPublishBuffer} from "../../ipfs-publish"; -import { setAllowance, getAllowance, getActiveEvidenceGroupId } from "../../db"; +import { BigNumber} from "@ethersproject/bignumber"; +import {ipfsPublish, ipfsPublishBuffer} from "../../utils/ipfs-publish-estuary"; +import { setAllowance, getAllowance, getActiveEvidenceGroupId , existsQuestionId} from "../../db"; import fetch from 'node-fetch'; import { getQuestionsNotFinalized } from "../../graph"; import { groupSettings } from "../../../types"; @@ -13,14 +14,17 @@ const contract = new web3.eth.Contract( _contract, process.env.REALITIO_ARBITRATOR ) - var botAddress: string; -const processCommand = async (bot: TelegramBot, settings: groupSettings, msg: TelegramBot.Message, questionId: number|string, batchedSend: any ): Promise => { +const processCommand = async (bot: any, settings: groupSettings, msg: any, questionId: number|string, batchedSend: any ): Promise => { const evidencePath = await upload(bot, settings.lang, msg); const evidenceJsonPath = await uploadEvidenceJson(settings.lang, msg, evidencePath); + try{ + bot.sendMessage(msg.chat.id, `${langJson[settings.lang].addevidence.submitted}(https://ipfs.kleros.io${evidencePath}).`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}); + } catch(e){ + console.log(e) + } submitEvidence(batchedSend, evidenceJsonPath, questionId); - bot.sendMessage(settings.channelID, `${langJson[settings.lang].addevidence.submitted}(https://ipfs.kleros.io${evidencePath}).`, {parse_mode: "Markdown"}); return evidenceJsonPath; } @@ -100,13 +104,21 @@ ${langJson[lang].addevidence.Message} (${langJson[lang].addevidence.Poll}): \n const uploadTextEvidence = async (lang: string, msg: TelegramBot.Message): Promise => { const enc = new TextEncoder(); + const match = msg.text.match(regexpFull); + var remainderMatch = match[1].split(' ') + remainderMatch.shift(); + const reason = remainderMatch.join(' ') + console.log(reason) + const textReason = reason.length > 0? `Evidence Submitted with explanation: ${reason}` : '' const author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' ID:'+msg.reply_to_message.from.id ; const fileName = `${langJson[lang].addevidence.Message}.txt`; const chatHistory = `${langJson[lang].addevidence.Chat}: ${msg.chat.title} (${String(msg.chat.id)}) ${langJson[lang].addevidence.Author}: ${author} (${(new Date(msg.reply_to_message.date*1000)).toISOString()}) -${langJson[lang].addevidence.Message}: ${msg.reply_to_message.text}`; +${langJson[lang].addevidence.Message}: ${msg.reply_to_message.text} + +${textReason}`; const evidencePath = await ipfsPublish(`${fileName}`, enc.encode(chatHistory)); @@ -115,23 +127,22 @@ ${langJson[lang].addevidence.Message}: ${msg.reply_to_message.text}`; const uploadEvidenceJson = async (lang: string, msg: TelegramBot.Message, evidenceItem: string): Promise => { const _name = `Kleros Moderator Bot: ${langJson[lang].addevidence.Chat} ${langJson[lang].addevidence.History}`; + const match = msg.text.match(regexpFull); + var remainderMatch = match[1].split(' ') + remainderMatch.shift(); + const reason = remainderMatch.join(' ') + console.log(reason) + const textReason = reason.length > 0? `Evidence Submitted with explanation: ${reason}` : '' const author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' ID:'+msg.reply_to_message.from.id ; const enc = new TextEncoder(); if (!botAddress) - botAddress = await (await new Wallet(process.env.PRIVATE_KEY)).address + botAddress = process.env.TRANSACTION_BATCHER_CONTRACT_ADDRESS const _description = `${langJson[lang].addevidence.Desc1} ${botAddress}. - ${langJson[lang].addevidence.Desc2}, - - ${msg.chat.title} (${langJson[lang].addevidence.Chat} Id: ${msg.chat.id}), - - ${langJson[lang].addevidence.Author}, - - ${author}, - - ${langJson[lang].addevidence.Date}, - - (${(new Date(msg.reply_to_message.date*1000)).toISOString()}).`; + ${langJson[lang].addevidence.Desc2}: ${msg.chat.title} (${langJson[lang].addevidence.Chat} Id: ${msg.chat.id}), + ${langJson[lang].addevidence.Author}: ${author} + ${langJson[lang].addevidence.Date}: (${(new Date(msg.reply_to_message.date*1000)).toISOString()}). + ${textReason}`; const evidence = { name: _name, @@ -145,7 +156,6 @@ const uploadEvidenceJson = async (lang: string, msg: TelegramBot.Message, eviden } const submitEvidence = async (batchedSend: any, evidencePath: string, questionId: number|string) => { - batchedSend({ args: [ questionId, @@ -160,38 +170,80 @@ const submitEvidence = async (batchedSend: any, evidencePath: string, questionId */ const regexp = /\/addevidence/ const regexpFull = /\/addevidence (.+)/ +const regexpFullReason = /\/addevidence (.+) (.+)/ const callback = async (db: any, settings: groupSettings, bot: any, botID: number, msg: any, matchh: string[], batchedSend: any) => { if (!msg.reply_to_message) { - bot.sendMessage(msg.chat.id, `/addevidence ${langJson[settings.lang].errorReply}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) + try{ + bot.sendMessage(msg.chat.id, `/addevidence ${langJson[settings.lang].errorReply}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) + } catch (e){ + console.log(e) + } return; } - if (!botAddress) - botAddress = await (await new Wallet(process.env.PRIVATE_KEY)).address.toLowerCase(); - const match = msg.text.match(regexpFull); + const match = msg.text.match(regexpFull); + const opts = msg.chat.is_forum? { + parse_mode: 'Markdown', + message_thread_id: msg.message_thread_id, + reply_markup: { + inline_keyboard: [ + [ + { + text: 'DM me for help', + url: `https://t.me/KlerosModeratorBot?start=addevidencehelp${msg.chat.id}` + } + ] + ] + } + } : { + parse_mode: 'Markdown', + reply_markup: { + inline_keyboard: [ + [ + { + text: 'DM me for help', + url: `https://t.me/KlerosModeratorBot?start=addevidencehelp${msg.chat.id}` + } + ] + ] + } + } //TODO Evidence IDs and button callback UX if (!match || match.length < 2){ - const questions = await getQuestionsNotFinalized(botAddress) - bot.sendMessage(msg.chat.id, `Did you mean `+ JSON.stringify(questions)); - bot.sendMessage(msg.chat.id, `/addevidence ${langJson[settings.lang].addevidence.error1} ${langJson[settings.lang].addevidence.id}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) + try{ + bot.sendMessage(msg.chat.id, `You did not specify an evidence group.`, opts) + } catch(e){ + console.log(e) + } + //const questions = await getQuestionsNotFinalized(botAddress) + //bot.sendMessage(msg.chat.id, `Did you mean `+ JSON.stringify(questions)); + //bot.sendMessage(msg.chat.id, `/addevidence ${langJson[settings.lang].addevidence.error1} ${langJson[settings.lang].addevidence.id}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) //const errorMsg = await errorMessage(db, lang, bot, msg); //await bot.sendMessage(msg.chat.id, errorMsg, {parse_mode: "Markdown", disable_web_page_preview: true}); return; } - const result = getActiveEvidenceGroupId(db, 'telegram', String(msg.chat.id), Number(match[1])); - if (!result){ - bot.sendMessage(msg.chat.id, langJson[settings.lang].errorId, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + const remainderMatch = match[1].split(' ') + const evidenceID = getActiveEvidenceGroupId(db, 'telegram', String(msg.chat.id), Number(remainderMatch[0])); + if (!evidenceID){ + try{ + bot.sendMessage(msg.chat.id, langJson[settings.lang].addevidence.errorId, opts) + } catch(e){ + console.log(e) + } //const errorMsg = await errorMessage(db, lang, bot, msg); //await bot.sendMessage(msg.chat.id, errorMsg, {parse_mode: "Markdown", disable_web_page_preview: true}); return; } - const reportAllowance = getAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id)); if (!reportAllowance){ setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), 3, 14, Math.ceil( new Date().getTime() / 1000)); } else if ((Math.ceil( new Date().getTime() / 1000) < reportAllowance.timestamp_refresh + 5760) && reportAllowance.evidence_allowance == 0 ){ - await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorAllowance); + try{ + bot.sendMessage(msg.chat.id, langJson[settings.lang].errorAllowance); + } catch (e){ + console.log(e) + } } else{ const newReportAllowance = reportAllowance.report_allowance + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800); const newEvidenceAllowance = reportAllowance.evidence_allowance + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800)*5 - 1; @@ -200,11 +252,9 @@ const callback = async (db: any, settings: groupSettings, bot: any, botID: numbe } try { - const evidencePath = await processCommand(bot, settings, msg, match[1],batchedSend); + const evidencePath = await processCommand(bot, settings, msg, evidenceID,batchedSend); } catch (e) { console.log(e); - - await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].errorTxn}: ${e.message}.`); } } /* diff --git a/lib/telegram/commands/getAccount.ts b/lib/telegram/commands/getAccount.ts index c4f4434..755f0ad 100644 --- a/lib/telegram/commands/getAccount.ts +++ b/lib/telegram/commands/getAccount.ts @@ -1,6 +1,7 @@ import * as TelegramBot from "node-telegram-bot-api"; import {Wallet} from "@ethersproject/wallet"; import langJson from "../assets/lang.json"; +import { groupSettings } from "../../../types"; /* * /getaccount @@ -8,11 +9,14 @@ import langJson from "../assets/lang.json"; const regexp = /\/getaccount/ var address: string; -const callback = async (db: any, lang: string, bot: any, msg: any) => { - if (!address) - address = (await new Wallet(process.env.PRIVATE_KEY)).address; - - await bot.sendMessage(msg.chat.id, `${langJson[lang].getAccount}: ${address}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}); +const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { + try{ + if (!address) + address = process.env.TRANSACTION_BATCHER_CONTRACT_ADDRESS; + bot.sendMessage(settings.channelID, `${langJson[settings.lang].getAccount}: ${address}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}); + } catch(e){ + console.log('gettaccount error. '+e) + } } export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/getChannel.ts b/lib/telegram/commands/getChannel.ts index 82d0f6e..8c46138 100644 --- a/lib/telegram/commands/getChannel.ts +++ b/lib/telegram/commands/getChannel.ts @@ -1,15 +1,16 @@ import * as TelegramBot from "node-telegram-bot-api"; -import {getRule, getInviteURLChannel} from "../../db"; +import {getRule, getInviteURLChannel, getChannelID} from "../../db"; import langJson from "../assets/lang.json"; import { groupSettings } from "../../../types"; /* - * /getrules + * /getchannel */ const regexp = /\/getchannel/ const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { - const channel_invite = getInviteURLChannel(db, 'telegram', msg.chat.id); + console.log(msg.chat.id) + const channel_invite = getInviteURLChannel(db, 'telegram', String(msg.chat.id)); bot.sendMessage(msg.chat.id, `I notify this [channel](${channel_invite}) about moderation activity.`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}); } diff --git a/lib/telegram/commands/getReports.ts b/lib/telegram/commands/getReports.ts index c36fa1c..e13a540 100644 --- a/lib/telegram/commands/getReports.ts +++ b/lib/telegram/commands/getReports.ts @@ -1,56 +1,59 @@ import * as TelegramBot from "node-telegram-bot-api"; const escape = require('markdown-escape') import langJson from "../assets/lang.json"; -import {getDisputedReportsUserInfo } from "../../db"; +import {getDisputedReportsUserInfo ,getDisputedReportsInfo} from "../../db"; +import { groupSettings } from "../../../types"; /* * /getaccount */ const regexp = /\/getreports/ -const callback = async (db: any, lang: string, bot: any, msg: any) => { +const callback = async (db: any, settings: groupSettings, bot: any, botid: number, msg: any) => { try{ if(msg.reply_to_message){ - const reports = await getDisputedReportsUserInfo(db, 'telegram', String(msg.chat.id), String(msg.reply_to_message.from.id)); + const reports = getDisputedReportsUserInfo(db, 'telegram', String(msg.chat.id), String(msg.reply_to_message.from.id)); const fromUsername = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name || `no-username-set`); if (reports.length == 0){ - bot.sendMessage(msg.chat.id, `${langJson[lang].getReports.noReports} *${escape(fromUsername)}*.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}:{parse_mode: "Markdown"}); + bot.sendMessage(msg.chat.id, `${langJson[settings.lang].getReports.noReports} *${escape(fromUsername)}*.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}:{parse_mode: "Markdown"}); return; } - var reportMessage: string = `${langJson[lang].getReports.ReportsFor} ${escape(fromUsername)}:\n\n`; - await reports.forEach(async (report) => { - const reportAnswer = report.active? langJson[lang].getReports.broke : langJson[lang].getReports.nobreak; - const MsgLink = 'https://t.me/c/' + report.group_id.substring(4) + '/' + report.msg_id; - const msgTime = new Date(report.timestamp*1000).toISOString(); - const reportState = report.finalized? langJson[lang].getReports.reportFinal : langJson[lang].getReports.reportCurrent; - reportMessage += ` - [${langJson[lang].getReports.report}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), ${langJson[lang].addEvidence.Evidence} ID ${report.evidenceIndex}, [${langJson[lang].addEvidence.MessageSent} ${msgTime.substring(0,msgTime.length-4)}](${MsgLink}) ([${langJson[lang].socialConsensus.consensus5}](${report.msgBackup})), ${reportState} ${langJson[lang].answer}, ${reportAnswer}\n`; + var reportMessage: string = `${langJson[settings.lang].getReports.ReportsFor} ${escape(fromUsername)}:\n\n`; + reports.forEach( (report) => { + console.log(report) + const reportAnswer = report.active? langJson[settings.lang].getReports.broke : langJson[settings.lang].getReports.nobreak; + const MsgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + report.msg_id; + const msgTime = new Date(report.timestamp*1000).toDateString(); + const msgTimehours = new Date(report.timestamp*1000).toUTCString(); + const reportState = report.finalized? langJson[settings.lang].getReports.reportFinal : langJson[settings.lang].getReports.reportCurrent; + if (report.active_timestamp === 0) + reportMessage += ` - [${langJson[settings.lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), [${langJson[settings.lang].addevidence.MessageSent}](${MsgLink}) ${msgTime}, ${msgTimehours} ([${langJson[settings.lang].socialConsensus.consensus5}](${report.msgBackup})), ${reportState} ${langJson[settings.lang].answer}, ${reportAnswer}, \`/addevidence ${report.evidenceIndex}\`\n`; + else + reportMessage += ` - [${langJson[settings.lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), [${langJson[settings.lang].addevidence.MessageSent}](${MsgLink}) ${msgTime}, ${msgTimehours} ([${langJson[settings.lang].socialConsensus.consensus5}](${report.msgBackup})), unanswered, \`/addevidence ${report.evidenceIndex}\`\n`; + }); bot.sendMessage(msg.chat.id, reportMessage , msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown", disable_web_page_preview: true}:{parse_mode: "Markdown", disable_web_page_preview: true}); return; } else { - bot.sendMessage(msg.chat.id, "Please reply to a user to find their history", msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) + const reports = getDisputedReportsInfo(db, 'telegram', String(msg.chat.id)); + if (reports.length == 0){ + bot.sendMessage(msg.chat.id, langJson[settings.lang].getReports.noActiveReports + '\n\n' + langJson[settings.lang].getReports.specificUser, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}:{parse_mode: "Markdown"}); + return; + } + var reportMessage: string = langJson[settings.lang].getReports.reportMessage + ':\n\n'; + + await reports.forEach(async (report) => { + const reportAnswer = report.active? langJson[settings.lang].getReports.broke : langJson[settings.lang].getReports.nobreak + const MsgLink = 'https://t.me/c/' + report.group_id.substring(4) + '/' + report.msg_id; + const msgTime = new Date(report.timestamp*1000).toISOString(); + reportMessage += ` - ${report.username} ${langJson[settings.lang].getReports.reportMessage1} [${msgTime.substring(0,msgTime.length-4)}](${MsgLink}) ([${langJson[settings.lang].getReports.reportMessage2}](${report.msgBackup})): [${langJson[settings.lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), ${langJson[settings.lang].getReports.reportMessage4}, ${reportAnswer}\n`; + }); + reportMessage += '\n\n' + reportMessage += langJson[settings.lang].getReports.specificUser; + bot.sendMessage(msg.chat.id, reportMessage, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown", disable_web_page_preview: true}:{parse_mode: "Markdown", disable_web_page_preview: true}); } } catch(e){ console.log(e) } -/* - const reports = getDisputedReportsInfo(db, 'telegram', String(msg.chat.id)); - if (reports.length == 0){ - bot.sendMessage(msg.chat.id, langJson[lang].getReports.noActiveReports + '\n\n' + langJson[lang].getReports.specificUser, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}:{parse_mode: "Markdown"}); - return; - }*/ -/* - var reportMessage: string = langJson[lang].getReports.reportMessage + ':\n\n'; - - await reports.forEach(async (report) => { - const reportAnswer = report.active? langJson[lang].getReports.broke : langJson[lang].getReports.nobreak - const MsgLink = 'https://t.me/c/' + report.group_id.substring(4) + '/' + report.msg_id; - const msgTime = new Date(report.timestamp*1000).toISOString(); - reportMessage += ` - ${report.username} ${langJson[lang].getReports.reportMessage1} [${msgTime.substring(0,msgTime.length-4)}](${MsgLink}) ([${langJson[lang].getReports.reportMessage2}](${report.msgBackup})): [${langJson[lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), ${langJson[lang].getReports.reportMessage4}, ${reportAnswer}\n`; - }); - reportMessage += '\n\n' - reportMessage += langJson[lang].getReports.specificUser; - bot.sendMessage(msg.chat.id, reportMessage, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown", disable_web_page_preview: true}:{parse_mode: "Markdown", disable_web_page_preview: true}); - */ } export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/getRules.ts b/lib/telegram/commands/getRules.ts index e019bff..b6671aa 100644 --- a/lib/telegram/commands/getRules.ts +++ b/lib/telegram/commands/getRules.ts @@ -4,9 +4,9 @@ import langJson from "../assets/lang.json"; import { groupSettings } from "../../../types"; /* - * /getrules + * /rules */ -const regexp = /\/getrules/ +const regexp = /\/rules/ const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { bot.sendMessage(msg.chat.id, `${langJson[settings.lang].rules}(${settings.rules}).`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}); diff --git a/lib/telegram/commands/greeting.ts b/lib/telegram/commands/greeting.ts index e9416dc..60b6a9d 100644 --- a/lib/telegram/commands/greeting.ts +++ b/lib/telegram/commands/greeting.ts @@ -2,25 +2,24 @@ import * as TelegramBot from "node-telegram-bot-api"; import langJson from "../assets/lang.json"; import {groupSettings} from "../../../types"; -let greetingMap : Map = new Map(); +const NodeCache = require( "node-cache" ); +const myCache = new NodeCache( { stdTTL: 900, checkperiod: 1200 } ); +var myBot; + +myCache.on("expired",function(key,value){ + myBot.deleteMessage(key, value.msg1); + myBot.deleteMessage(key, value.msg2); + }); const callback = async (bot: any, settings: groupSettings, msg: any) => { - const previousMsgId = greetingMap.get(msg.chat.id); - if (previousMsgId){ - try{ - bot.deleteMessage(msg.chat.id, String(previousMsgId[0])); - bot.deleteMessage(msg.chat.id, String(previousMsgId[1])); - } catch (e){ - console.log(e) - } - } + myBot = bot try{ if(msg.chat.is_forum){ bot.sendMessage(msg.chat.id, `Welcome [${msg.from.first_name}](tg://user?id=${msg.from.id}) ${langJson[settings.lang].greeting2}(${settings.rules}). ${langJson[settings.lang].greeting3}`, {message_thread_id: settings.thread_id_welcome, parse_mode: "Markdown"}); } else { const msg1: TelegramBot.Message = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].greeting1}[Kleros Moderate](https://kleros.io/moderate/).`, {parse_mode: "Markdown"}); const msg2: TelegramBot.Message = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].greeting2}(${settings.rules}). ${langJson[settings.lang].greeting3}`, {parse_mode: "Markdown"}); - greetingMap.set(msg.chat.id, [msg1.message_id, msg2.message_id]); + myCache.set(msg.chat.id, {"msg1": msg1.message_id, "msg2": msg2.message_id}); } } catch(e){ console.log(e) diff --git a/lib/telegram/commands/help.ts b/lib/telegram/commands/help.ts index 44673da..6987a5d 100644 --- a/lib/telegram/commands/help.ts +++ b/lib/telegram/commands/help.ts @@ -3,10 +3,53 @@ import langJson from "../assets/lang.json"; import { groupSettings } from "../../../types"; /* - * /getrules + * /help */ const regexp = /\/help/ +const helpgnosis = (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { + try{ + bot.sendMessage(msg.chat.id, `⛓️ *Gnosis Chain* ⛓️ + +Susie uses [xDAI](https://docs.gnosischain.com/about/tokens/xdai), a stable coin, on [Gnosis Chain](https://www.gnosis.io/). Don't know what that means? It means Susie uses a cheap and fast decentralized tool to coordinate moderation fairly and transparently. + +Don't have any xDAI on Gnosis Chain? No problem, there's a (cheap, fast) [bridge](https://bridge.connext.network/?receivingChainId=100&receivingAssetId=0x0000000000000000000000000000000000000000) for that. + +Don't have any cryptocurrency? No problem, there's a convinient [fiat on-ramp](https://www.mtpelerin.com/buy-xdai) (credit card or bank transfer) to buy DAI on Gnosis Chain. + +Need help adding the Gnosis Chain network to your wallet? Don't worry, there's a [guide](https://docs.gnosischain.com/tools/wallets/metamask#2-configure) for that. + +Need more help? Don't worry, there's a @SusieSupport group for that` + ,{parse_mode: 'Markdown', disable_web_page_preview: true}) + } catch(e){ + console.log(e) + } +} + +const helpnotifications = (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { + try{ + bot.sendMessage(msg.chat.id, `🔔 *Notifications* 🔔 + +Susie sends notifications about moderation actions and report updates. These notifications are restricted to a separate chat in topic mode. In regular Telegram groups, notifications can be sent to a notification channel to avoid cluttering the main chat. + +How to enable notification channels: + +1. Make a channel +2. Add Susie +3. Susie will send a channel ID +4. Use that channel ID to set notifications with /setchannel in the original group + +*User commands*: +- /getchannel: Returns current notification channel +*Admin commands*: +- /setchannel : Sets the rules to the the url` + ,{parse_mode: 'Markdown', disable_web_page_preview: true}) + } catch(e){ + console.log(e) + } +} + + const callback = (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { if (msg.chat.type !== "private"){ const opts = msg.chat.is_forum? { @@ -80,11 +123,22 @@ const respond = (settings: groupSettings, bot: any, helpType: string, callbackQu text: '🚨 Report', callback_data: `3|report` }, { - text: '⚖️ Rules', + text: '📄 Rules', callback_data: `3|rules` } ], [ + { + text: '⚖️ Court', + callback_data: `3|court` + }, { + text: '🧑‍⚖️ Find a Lawyer', + callback_data: `3|lawyer` + }, { + text: '✨ Open Source', + callback_data: `3|open` + } + ],[ { text: '🔔 Notifications', callback_data: `3|notifications` @@ -92,7 +146,7 @@ const respond = (settings: groupSettings, bot: any, helpType: string, callbackQu text: '🌐 Federation', callback_data: `3|federation` }, { - text: '⬨ Web 2.5', + text: '⛓️ Gnosis Chain', callback_data: `3|web2.5` } ] @@ -153,18 +207,22 @@ To prevent important messages from deletion, pre-emptively, messages can be save case 'report': { bot.editMessageText(`🚨 *Report* 🚨 -As groups grow, so do their moderation problems. We're all busy people who don't have time to monitor groups 24/7. Often users dispute moderation actions by admins and have no recourse. Who moderates the moderator? +As groups grow, so do their moderation problems. We're all busy people who don't have time to monitor groups 24/7. Users often complain about admin abuse and have no recourse. Who moderates the moderator? -Presenting Kleros Moderate, a crowd-sourced content moderation tool using Reality.eth and Kleros. +Presenting [Kleros Moderate](https://kleros.io/moderate), a crowd-sourced content moderation tool using [Reality.eth](https://reality.eth.limo/) and [Kleros](https://kleros.gitbook.io/docs/) on [Gnosis Chain](https://www.gnosis.io/). -When users are reported, a question is created on Reality.Eth asking 'did the user break the rules?'. The question can be answered yes/no with a bond (5 DAI). Successful reports result in penalties (1 day ban, 1 week ban, 1 year ban). +When users are reported, a question is created on Reality.Eth asking 'did the user break the rules?'. The question can be answered yes/no with a bond (5 DAI). Successful reports result in penalties, + +- 1st Report: 1 day ban +- 2nd Report: 1 week ban +- 3rd Report: 1 year ban Answers to reports can be disputed, creating a case in the Kleros court. Refer to the [docs](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator) to learn more. *User commands*: - /report : Reply to a message to report it - /getreports: Returns active reports -- /getreports : Returns active reports` +- /getreports : Returns active reports for user` ,optsResponse) break; } @@ -174,7 +232,7 @@ Answers to reports can be disputed, creating a case in the Kleros court. Refer t The [Kleros Moderate Community Guidelines](https://ipfs.kleros.io/ipfs/QmYYcNfEYLtxPM8fof4wf9Tqj7gBGMDMmNnBqZKR1zSczX/Kleros%20Moderate%20Community%20Guidelines%20v1.pdf) apply as the default rules. Crafting precise policies can be challenging, if you are certain in setting a new policy, you can set new rules with /setrules *User commands*: -- /getrules: Returns current rules +- /rules: Returns current rules *Admin commands*: - /setrules : Sets the rules to the the url - /setrules : Sets the rules to a replied message` @@ -216,11 +274,50 @@ No more! With federations, Susie can enforce a ban on a user in all federate gro break; } case 'web2.5': { - bot.editMessageText(`⬨ *Web 2.5* ⬨ + bot.editMessageText(`⛓️ *Gnosis Chain* ⛓️ + +Susie uses [xDAI](https://docs.gnosischain.com/about/tokens/xdai), a stable coin, on [Gnosis Chain](https://www.gnosis.io/). Don't know what that means? It means Susie uses a cheap and fast public ledger to coordinate moderation fairly and transparently. + +Don't have any xDAI on Gnosis Chain? No problem, there's a (cheap, fast) [bridge](https://bridge.connext.network/?receivingChainId=100&receivingAssetId=0x0000000000000000000000000000000000000000) for that. + +Don't have any cryptocurrency? No problem, there's a convinient [fiat on-ramp](https://www.mtpelerin.com/buy-xdai) (credit card or bank transfer) to buy DAI on Gnosis Chain. + +Need help adding the Gnosis Chain network to your wallet? Don't worry, there's a [guide](https://docs.gnosischain.com/tools/wallets/metamask#2-configure) for that. + +Need more help? Don't worry, there's a @SusieSupport group for that` + ,optsResponse) + break; + } + case 'court': { + bot.editMessageText(`⚖️ *Court* ⚖️ + +Disputes are resolved by the [Kleros Court](https://kleros.gitbook.io/docs/) with a randomly selected jury. If the jury made a mistake, the case can be appealed, drawing a larger pool of random jurors and providing an opportunity to provide more context, analysis, and arguments. -Susie uses web3 (Reality.eth and Kleros) with *skin in the game* mechanics to moderate a web2 platform (Telegram). Susie's inner workings are [opensource](https://github.com/kleros/kleros-moderate). Feel free to make an issue, feature request, bug report, comments, suggests, PRs, forks, etc : ) +If you would like a chance to serve as a jury member, buy PNK ([Gnosis Chain](https://swapr.eth.link/#/swap?chainId=100) or [Mainnet](https://app.uniswap.org/#/swap?outputCurrency=0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d&inputCurrency=ETH)) and [stake](https://court.kleros.io/) in the curation subcourt of the Kleros Court on Gnosis Chain. -This instance of Susie is hosted as a service. You can self-host the bot, a raspberry pi or an old laptop are sufficient to keep your own instance of Susie online. To learn more about self-hosting, see this [guide](https://github.com/kleros/kleros-moderate/self-hosting.md).` +To discuss the merits of a dispute, see @klerosjuror.` + ,optsResponse) + break; + } + case 'lawyer': { + bot.editMessageText(`🧑‍⚖️ *Find a Lawyer* 🧑‍⚖️ + +Disputes over reported behavior can be complicated and nuanced. Often, disputes resolve on the merits of the message and rules alone. In some cases, disputes are better resolved by presenting the court with analysis and arguments. + +If you would like to offer your services as a lawyer or solicit services, please join this [group](https://t.me/+9fvGGkGfSZ1hZDBk). + +` + ,optsResponse) + break; + } + case 'open': { + bot.editMessageText(`✨ *Open Source* ✨ + +Susie is [open source](https://github.com/kleros/kleros-moderate). Feel free to make an issue, feature request, bug report, comments, suggests, PRs, forks, etc : ) + +Susie is hosted. You can self-host the Susie, a raspberry pi or an old laptop are sufficient to keep your own instance of Susie online. To learn more about self-hosting, see this [guide](https://github.com/kleros/kleros-moderate/self-hosting.md) *soon*. + +` ,optsResponse) break; } @@ -240,6 +337,8 @@ I have lots of handy features, such as crowd-sourced user reporting. Helpful commands: - /start: Starts me. You've probably already used this. - /help: Sends this message and I'll tell you more about myself. + +Important: I moderate groups by crowd-sourcing community input with Gnosis Chain. Make sure you or some community members get DAI on Gnosis Chain to participate actively. Select a feature to learn more. My [documentation](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator) is also helpful, or ask a question in @SusieSupport.`; @@ -268,10 +367,22 @@ const opts = { text: '🚨 Report', callback_data: `3|report` }, { - text: '⚖️ Rules', + text: '📄 Rules', callback_data: `3|rules` } ], + [ + { + text: '⚖️ Court', + callback_data: `3|court` + }, { + text: '🧑‍⚖️ Find a Lawyer', + callback_data: `3|lawyer` + }, { + text: '✨ Open Source', + callback_data: `3|open` + } + ], [ { text: '🔔 Notifications', @@ -280,7 +391,7 @@ const opts = { text: '🌐 Federation', callback_data: `3|federation` }, { - text: '⬨ Web 2.5', + text: '⛓️ Gnosis Chain', callback_data: `3|web2.5` } ] @@ -288,4 +399,4 @@ const opts = { } } -export {regexp, callback, respond}; \ No newline at end of file +export {regexp, callback, respond, helpgnosis, helpnotifications}; \ No newline at end of file diff --git a/lib/telegram/commands/report.ts b/lib/telegram/commands/report.ts index b1ec01c..3f8e70f 100644 --- a/lib/telegram/commands/report.ts +++ b/lib/telegram/commands/report.ts @@ -42,25 +42,11 @@ const callback = async (db:any, settings: groupSettings, bot: any, botId: number return; } const reportedQuestionId = getQuestionId(db, 'telegram', String(msg.chat.id), reportedUserID, String(msg.reply_to_message.message_id)); - if (reportedQuestionId){ bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.reported}(https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${reportedQuestionId})`, {parse_mode: 'Markdown'}); return; } - if (match[1] != langJson[settings.lang].socialConsensus.confirm) { - const reports = getConcurrentReports(db, 'telegram', String(msg.chat.id), reportedUserID, msg.reply_to_message.date); - if(reports.length > 0){ - var reportInfo = `${langJson[settings.lang].report.info1} *${escape(fromUsername)} (ID :${reportedUserID})* ${langJson[settings.lang].report.info2} \n\n`; - (reports).forEach((report) => { - const privateMsgLink = 'https://t.me/c/' + report.group_id.substring(4) + '/' + report.msg_id; - reportInfo += ` - [${langJson[settings.lang].addEvidence.Message} ${new Date(report.timestamp*1000).toISOString()}](${privateMsgLink}): [${langJson[settings.lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id})\n`; - }); - reportInfo += `\n${langJson[settings.lang].report.sure} \'/report ${langJson[settings.lang].socialConsensus.confirm}\'` - bot.sendMessage(msg.chat.id, reportInfo, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); - return; - } - } const rules = getRule(db, 'telegram', String(msg.chat.id), msg.reply_to_message.date); @@ -76,7 +62,7 @@ const callback = async (db:any, settings: groupSettings, bot: any, botId: number // TODO report const reportAllowance = getAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id)); - if (!reportAllowance ){ + if (!reportAllowance){ setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), 2, 15, currentTimeMs); } else if (currentTimeMs < reportAllowance.timestamp_refresh + 28800 && reportAllowance.report_allowance == 0 ){ bot.sendMessage(msg.chat.id, langJson[settings.lang].report.noallowance, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); @@ -138,12 +124,9 @@ const reportMsg = async (settings: groupSettings, db: any, bot: any, msg: any, f const msgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + msgId; - var evidenceIndex = myCache.get("evidence"+msg.chat.id) + 1; - if (!evidenceIndex){ - evidenceIndex = getRecordCount(db, 'telegram', String(msg.chat.id))+1; - } - evidenceIndexMap.set(msg.chat.id, evidenceIndex); - + const cachedEvidenceIndex = myCache.get("evidence"+msg.chat.id); + const evidenceIndex = cachedEvidenceIndex? cachedEvidenceIndex+1:getRecordCount(db, 'telegram', String(msg.chat.id))+1 + myCache.set("evidence"+msg.chat.id, evidenceIndex); const {questionId, questionUrl: appealUrl} = await reportUser( batchedSend, @@ -160,8 +143,9 @@ const reportMsg = async (settings: groupSettings, db: any, bot: any, msg: any, f msgBackup, reportedBy); - addReport(db, questionId, "telegram", String(msg.chat.id), reportedUserID, fromUsername , msgId, msg.reply_to_message.date,evidenceIndex); - bot.sendMessage(settings.channelID, `[${fromUsername}](tg://user?id=${reportedUserID})'s conduct due to this [message](${msgLink}) ([backup](${msgBackup})) is reported for breaking the [rules](${rules}).\n\nDid *${fromUsername}* break the rules? The [question](${appealUrl}) can be answered with a minimum bond of 5 DAI.\n\nTo save a record, reply to messages you want saved with the command below,\n/addevidence ${evidenceIndex}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); + addReport(db, questionId, 'telegram', String(msg.chat.id), reportedUserID, fromUsername , msgId, msg.reply_to_message.date,evidenceIndex, msgBackup); + + bot.sendMessage(settings.channelID, `[${fromUsername}](tg://user?id=${reportedUserID})'s conduct due to this [message](${msgLink}) ([backup](${msgBackup})) is reported for breaking the [rules](${rules}).\n\nDid *${fromUsername}* break the rules? The [question](${appealUrl}) can be answered with a minimum bond of 5 DAI. Need help getting DAI on Gnosis Chain for your answer? [DM](https://t.me/KlerosModeratorBot?start=helpgnosis) me for help : )\n\nTo save a record, reply to messages you want saved with \`/addevidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); return questionId; } catch (e) { console.log(e); diff --git a/lib/telegram/commands/setChannel.ts b/lib/telegram/commands/setChannel.ts index d299e36..f91be97 100644 --- a/lib/telegram/commands/setChannel.ts +++ b/lib/telegram/commands/setChannel.ts @@ -14,7 +14,7 @@ const callback = async (db: any, settings: groupSettings, bot: TelegramBot, botI try { const newmatch = msg.text.match(regexpFull); if (!newmatch || newmatch.length < 2){ - bot.sendMessage(msg.chat.id, `/setchannel must be followed by a channel id`); + bot.sendMessage(msg.chat.id, `/setchannel must be followed by a channel id. [DM](https://t.me/KlerosModeratorBot?start=helpnotifications) me if you need more help : )`, {parse_mode: "Markdown"}); return; } try{ diff --git a/lib/telegram/commands/setInviteUrl.ts b/lib/telegram/commands/setInviteUrl.ts deleted file mode 100644 index df02484..0000000 --- a/lib/telegram/commands/setInviteUrl.ts +++ /dev/null @@ -1,30 +0,0 @@ -import * as TelegramBot from "node-telegram-bot-api"; -import {CommandCallback} from "../../../types"; -import {setInviteURL} from "../../db"; -import {validateUrl} from "./setRules"; - -/* - * /setinviteurl [group invite url] - */ -const regexp = /\/setinviteurl\s?(.+)?/ - -const callback = async (db: any, bot: TelegramBot, msg: TelegramBot.Message, match: string[]) => { - try { - const user = await bot.getChatMember(msg.chat.id, String(msg.from.id)); - - if (user.status === 'creator' || user.status === 'administrator') { - if (validateUrl(match[1])) { - await setInviteURL(db, 'telegram', String(msg.chat.id), match[1]); - await bot.sendMessage(msg.chat.id, 'Group invite URL set.'); - } else { - await bot.sendMessage(msg.chat.id, '/setinviteurl must be followed by a valid invite URL to the group.'); - } - } else { - await bot.sendMessage(msg.chat.id, `Only admins can execute this command.`); - } - } catch (error) { - console.log(error); - } -} - -export {regexp, callback, validateUrl}; \ No newline at end of file diff --git a/lib/telegram/commands/socialConsensus.ts b/lib/telegram/commands/socialConsensus.ts index 3ac1a6a..202562b 100644 --- a/lib/telegram/commands/socialConsensus.ts +++ b/lib/telegram/commands/socialConsensus.ts @@ -8,7 +8,7 @@ import {Wallet} from "@ethersproject/wallet"; var botAddress: string; /* - * /getrules + * social consensus callback */ const callback = async (db: any, settings: groupSettings, bot: TelegramBot, callbackQuery: TelegramBot.CallbackQuery, batchedSend: any) => { @@ -58,7 +58,7 @@ const callback = async (db: any, settings: groupSettings, bot: TelegramBot, call bot.editMessageText("User Reported.",optsFinal) const user = (await bot.getChatMember(String(msg.chat.id), String(calldata[1]))).user; const fromUsername = user.username || user.first_name || `no-username-set`; - await reportMsg(settings, db, bot, msg, fromUsername, String(calldata[1]), msg.entities[1].url, String(calldata[2]), msg.entities[3].url, calldata[3],batchedSend); + reportMsg(settings, db, bot, msg, fromUsername, String(calldata[1]), msg.entities[1].url, String(calldata[2]), msg.entities[3].url, calldata[3],batchedSend); } else{ bot.editMessageReplyMarkup(markdown, opts) } diff --git a/lib/telegram/commands/start.ts b/lib/telegram/commands/start.ts index e581264..b1d1d13 100644 --- a/lib/telegram/commands/start.ts +++ b/lib/telegram/commands/start.ts @@ -50,11 +50,11 @@ Join my news channel @KlerosModerateNews to get information on all the latest up await topicMode(db,bot,settings,String(msg.chat.id)); } setRules(db, 'telegram', String(msg.chat.id), langJson[settings.lang].defaultRules, Math.floor(Date.now()/1000)); - bot.sendMessage(msg.chat.id, `Hi! My community moderation tools are at your service. + bot.sendMessage(msg.chat.id, `Hi! My community moderation tools are at your service. [DM](https://t.me/KlerosModeratorBot?start=help) me to find out more about how to use me to my full potential : ) -[DM](https://t.me/KlerosModeratorBot?start=help) me to find out more about how to use me to my full potential : ) - -${langJson[settings.lang].defaultRulesMsg1}(${langJson[settings.lang].defaultRules}).`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}: {parse_mode: "Markdown"}) +- Use /setrules to change the default [rules](${langJson[settings.lang].defaultRules}). +- User reports are made by replying to a message with /report +- Penalties progress from 1 day to 1 week, and 1 year bans for each violation.`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}: {parse_mode: "Markdown"}) return; } catch (e){ try{ diff --git a/lib/telegram/index.ts b/lib/telegram/index.ts index 00f8cf2..5f6b4cf 100644 --- a/lib/telegram/index.ts +++ b/lib/telegram/index.ts @@ -3,6 +3,7 @@ import * as TelegramBot from "node-telegram-bot-api"; import * as getAccount from "../../lib/telegram/commands/getAccount"; import * as setRulesCommand from "../../lib/telegram/commands/setRules"; import * as getRules from "../../lib/telegram/commands/getRules"; +import * as addEvidenceHelp from "../../lib/telegram/commands/addEvidenceHelp"; import * as report from "../../lib/telegram/commands/report"; import * as welcome from "../../lib/telegram/commands/welcome"; import * as toggleWelcome from "../../lib/telegram/commands/toggleWelcome"; @@ -15,10 +16,11 @@ import * as joinFed from "../../lib/telegram/commands/joinfed"; import * as start from "../../lib/telegram/commands/start"; import * as setLanguage from "../../lib/telegram/commands/setLanguage"; import * as setChannel from "../../lib/telegram/commands/setChannel"; +import * as getChannel from "../../lib/telegram/commands/getChannel"; import * as getReports from "../../lib/telegram/commands/getReports"; import langJson from "./assets/lang.json"; import {groupSettings, groupSettingsUnderspecified} from "../../types"; -import {openDb, getGroupSettings, getRule, eraseThreadID} from "../db"; +import {openDb, getGroupSettings, getRule, getDisputedReportsUserInfo, eraseThreadID} from "../db"; const Web3 = require('web3') const _batchedSend = require('web3-batched-send') @@ -27,7 +29,7 @@ const batchedSend = _batchedSend( web3, process.env.TRANSACTION_BATCHER_CONTRACT_ADDRESS, process.env.PRIVATE_KEY, - 20000 // The debounce timeout period in milliseconds in which transactions are batched. + 10000 // The debounce timeout period in milliseconds in which transactions are batched. ) const defaultSettings: groupSettings = { lang: 'en', @@ -39,7 +41,7 @@ const batchedSend = _batchedSend( thread_id_notifications: '' } const ModeratorBot = require('node-telegram-bot-api'); -const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: true, testEnvironment: false}); +const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: true, testEnvironment: true}); //bot. var botId: number; const db = openDb(); @@ -47,6 +49,10 @@ const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 900, checkperiod: 1200 } ); // Throttling +const delay = (delayInms) => { + return new Promise(resolve => setTimeout(resolve, delayInms)); + } + bot.on("my_chat_member", async function(myChatMember: any) { try{ if(throttled(myChatMember.from.id) || myChatMember.chat.is_forum) @@ -54,6 +60,7 @@ bot.on("my_chat_member", async function(myChatMember: any) { const settings = validate(myChatMember.chat); if(myChatMember.chat.type === "channel"){ + await delay(2000); if( myChatMember.new_chat_member.status === "administrator"){ try{ bot.sendMessage(myChatMember.chat.id, `The channel id is ${myChatMember.chat.id}`, {parse_mode: "HTML"}); @@ -68,7 +75,7 @@ bot.on("my_chat_member", async function(myChatMember: any) { return else try{ - bot.sendVideo(myChatMember.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {caption: "Group is not a supergroup. Please promote me to an admin."}); + bot.sendVideo(myChatMember.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {caption: "Hi! I'm Susie, a moderation and group management bot. Please promote me to an admin then try to /start me to unlock my full potential."}); } catch(e){ console.log(e) } @@ -105,6 +112,25 @@ bot.on('callback_query', async function onCallbackQuery(callbackQuery: TelegramB socialConsensus.callback(db, settings, bot, callbackQuery, batchedSend); } else if (Number(calldata[0]) === 3){ // report confirmations help.respond(settings, bot, calldata[1], callbackQuery); + } else if (Number(calldata[0]) === 4){ + const reports = getDisputedReportsUserInfo(db, 'telegram', calldata[1], calldata[2]); + var reportMessage: string = `To add evidence, reply to the message you want saved in the original chat with the evidence index.\n\n` + reports.forEach( (report) => { + const MsgLink = 'https://t.me/c/' + calldata[1].substring(4) + '/' + report.msg_id; + reportMessage += `- [Message](${MsgLink}) ([${langJson[settings.lang].socialConsensus.consensus5}](${report.msgBackup})) [${langJson[settings.lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), \`/addevidence ${report.evidenceIndex}\` \n`; + }); + const optsResponse = { + chat_id: callbackQuery.message.chat.id, + message_id: callbackQuery.message.message_id, + parse_mode: 'Markdown', + disable_web_page_preview: true + }; + try{ + bot.editMessageReplyMarkup({inline_keyboard: [[]]}, optsResponse) + bot.editMessageText(reportMessage , optsResponse); + } catch (e){ + console.log(e) + } } }); @@ -116,6 +142,7 @@ const commands: {regexp: RegExp, callback: any}[] = [ toggleWelcome, start, help, + getChannel, leaveFed, joinFed, setChannel, @@ -137,11 +164,20 @@ commands.forEach((command) => { if (msg.text === '/start help'){ help.callback(db, groupSettings, bot, botId, msg); return - } else if (msg.text != '/start' && msg.text != '/help') + } else if(msg.text === '/start helpgnosis'){ + help.helpgnosis(db, groupSettings, bot, botId, msg); + return + } else if(msg.text === '/start helpnotifications'){ + help.helpnotifications(db, groupSettings, bot, botId, msg); + return + } else if (msg.text.substring(0,22) === '/start addevidencehelp'){ + addEvidenceHelp.callback(db, groupSettings, bot, botId, msg); return - } else if(msg.chat.type !== "supergroup") + } else if (msg.text !== '/start' && msg.text != '/help' && msg.text !== '/start botstart') + return + } else if(msg.chat.type !== "supergroup" && !(msg.chat.type === "group" && msg.text === '/help')) return - if (command === start || command === help){ + if (command === start){ if (hasStarted(msg.chat.id)){ try{ bot.sendMessage(msg.chat.id, "Susie is already moderating this community.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id} : {}) @@ -150,7 +186,7 @@ commands.forEach((command) => { console.log(e) } } - } else if(!hasStarted(msg.chat.id)){ + } else if(!hasStarted(msg.chat.id) && command !== help){ return; } @@ -173,7 +209,11 @@ commands.forEach((command) => { } } if (!(status === 'creator' || status === 'administrator')) { - bot.sendMessage(msg.chat.id, langJson[groupSettings.lang].errorAdminOnly, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + try{ + bot.sendMessage(msg.chat.id, langJson[groupSettings.lang].errorAdminOnly, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + } catch(e){ + console.log(e) + } return; } } diff --git a/lib/utils/ipfs-publish-estuary.ts b/lib/utils/ipfs-publish-estuary.ts new file mode 100644 index 0000000..57f1088 --- /dev/null +++ b/lib/utils/ipfs-publish-estuary.ts @@ -0,0 +1,32 @@ +import fetch from 'node-fetch'; + +/** + * Send file to IPFS network via the Kleros IPFS node + * @param {string} fileName - The name that will be used to store the file. This is useful to preserve extension type. + * @param {ArrayBuffer} data - The raw data from the file to upload. + * @return {string} URL of the stored item. + */ + const ipfsPublish = async (fileName, data): Promise => { + const buffer = await Buffer.from(data) + return await ipfsPublishBuffer(fileName, buffer); +} + +const ipfsPublishBuffer = async (fileName, buffer): Promise => { + var FormData = require('form-data'); + var form_data = new FormData(); + + form_data.append('data', buffer, { filename: fileName}); + + const response = await fetch('https://shuttle-4.estuary.tech/content/add', { + method: 'POST', + body: form_data, + headers: { + "Authorization": `Bearer ${process.env.ESTUARY_API_KEY}` + } + }); + const body = await response.json(); + console.log(body) + return `/ipfs/${body.cid}` +} + +export {ipfsPublish, ipfsPublishBuffer}; \ No newline at end of file diff --git a/lib/utils/ipfs-publish.ts b/lib/utils/ipfs-publish.ts new file mode 100644 index 0000000..e215c7f --- /dev/null +++ b/lib/utils/ipfs-publish.ts @@ -0,0 +1,31 @@ +import fetch from 'node-fetch'; + +/** + * Send file to IPFS network via the Kleros IPFS node + * @param {string} fileName - The name that will be used to store the file. This is useful to preserve extension type. + * @param {ArrayBuffer} data - The raw data from the file to upload. + * @return {string} URL of the stored item. + */ + const ipfsPublish = async (fileName, data): Promise => { + const buffer = await Buffer.from(data) + return await ipfsPublishBuffer(fileName, buffer); +} + +const ipfsPublishBuffer = async (fileName, buffer): Promise => { + const response = await fetch('https://ipfs.kleros.io/add', { + method: 'POST', + body: JSON.stringify({ + fileName, + buffer + }), + headers: { + 'content-type': 'application/json' + } + }); + + const body = await response.json(); + + return `/ipfs/${body.data[1].hash}${body.data[0].path}` +} + +export {ipfsPublish, ipfsPublishBuffer}; \ No newline at end of file diff --git a/subgraph/schema.graphql b/subgraph/schema.graphql index 16b7bce..eb7fce3 100644 --- a/subgraph/schema.graphql +++ b/subgraph/schema.graphql @@ -16,7 +16,7 @@ type ModerationInfo @entity(immutable: true){ rulesUrl: String! message: String! messageBackup: String! - reportedBy: User! + reportedBy: UserHistory! askedBy: Bytes! deadline: BigInt timeout: BigInt! @@ -33,6 +33,7 @@ type RealityCheck @entity{ blocknumberLastUpdated: BigInt timestampLastUpdated: BigInt moderationInfo: ModerationInfo! @derivedFrom(field: "reality") + dispute: String } type UserHistory @entity{ @@ -59,12 +60,13 @@ type User @entity(immutable: true){ type Janny @entity{ id: ID! group: Group! + botAddress: Bytes blocknumberLastUpdatedSheriff: BigInt blocknumberLastUpdatedDeputySheriff: BigInt timestampLastUpdatedSheriff: BigInt timestampLastUpdatedDeputySheriff: BigInt - sheriff: User - deputySheriff: User + sheriff: UserHistory + deputySheriff: UserHistory } type Group @entity(immutable: true){ diff --git a/subgraph/src/KlerosLiquid.ts b/subgraph/src/KlerosLiquid.ts index bdebd0c..c04002c 100644 --- a/subgraph/src/KlerosLiquid.ts +++ b/subgraph/src/KlerosLiquid.ts @@ -9,7 +9,7 @@ import { import { BigInt, log, Address, JSONValueKind, ByteArray } from "@graphprotocol/graph-ts" export function handleAppealPossible(event: AppealPossibleEvent): void { - const dispute = ModerationDispute.load(event.params._disputeID.toHexString()) + let dispute = ModerationDispute.load(event.params._disputeID.toHexString()) if (!dispute){ log.error("Disput not found {}.", [event.params._disputeID.toHexString()]) return; @@ -22,7 +22,7 @@ import { } export function handleAppealDecision(event: AppealDecisionEvent): void { - const dispute = ModerationDispute.load(event.params._disputeID.toHexString()) + let dispute = ModerationDispute.load(event.params._disputeID.toHexString()) if (!dispute){ log.error("Disput not found {}.", [event.params._disputeID.toHexString()]) return; diff --git a/subgraph/src/Realitio_v2_1_ArbitratorWithAppeals.ts b/subgraph/src/Realitio_v2_1_ArbitratorWithAppeals.ts index 115bdbd..b66b79b 100644 --- a/subgraph/src/Realitio_v2_1_ArbitratorWithAppeals.ts +++ b/subgraph/src/Realitio_v2_1_ArbitratorWithAppeals.ts @@ -5,17 +5,24 @@ import { Evidence as EvidenceEvent } from "../generated/Realitio_v2_1_ArbitratorWithAppeals/Realitio_v2_1_ArbitratorWithAppeals" import { - ModerationDispute, ModerationInfo, UserHistory, + ModerationDispute, ModerationInfo, RealityCheck, UserHistory, } from "../generated/schema" import { log, Bytes, BigInt } from "@graphprotocol/graph-ts" export function handleDisputeIDToQuestionID( event: DisputeIDToQuestionIDEvent ): void { - const moderationDispute = new ModerationDispute(event.params._disputeID.toHexString()); + let moderationDispute = new ModerationDispute(event.params._disputeID.toHexString()); moderationDispute.moderationInfo = event.params._questionID.toHexString() moderationDispute.timestampLastUpdated = event.block.timestamp moderationDispute.save(); + let realityCheck = RealityCheck.load(event.params._questionID.toHexString()) + if (!realityCheck){ + log.error('no reality check found for dispute. {}', [event.params._questionID.toHexString()]) + return + } + realityCheck.dispute = event.params._disputeID.toHexString() + realityCheck.save() } /* export function handleEvidenceEvent( @@ -25,20 +32,21 @@ import { } */ export function handleRuling(event: RulingEvent): void { - const moderationDispute = ModerationDispute.load(event.params._disputeID.toHexString()); + let moderationDispute = ModerationDispute.load(event.params._disputeID.toHexString()); if (!moderationDispute){ log.error('Moderation Dispute not found. {}',[event.params._disputeID.toHexString()]); return; } moderationDispute.finalRuling = event.params._ruling + moderationDispute.timestampLastUpdated = event.block.timestamp moderationDispute.save() - const modinfo = ModerationInfo.load(moderationDispute.moderationInfo) + let modinfo = ModerationInfo.load(moderationDispute.moderationInfo) if (!modinfo){ log.error("ModerationInfo not found {}.", [moderationDispute.moderationInfo]); return; } - const userHistory = UserHistory.load(modinfo.UserHistory) + let userHistory = UserHistory.load(modinfo.UserHistory) if (!userHistory){ log.error("UserHistory not found {}.", [modinfo.UserHistory]); return; @@ -64,7 +72,7 @@ import { } const dispute = moderationInfo.dispute const dispute_non_null = dispute ? dispute : 'no-dispute'; - const moderationDispute = ModerationDispute.load(dispute_non_null); + let moderationDispute = ModerationDispute.load(dispute_non_null); if (!moderationDispute){ log.error('Moderation Dispute not found {}.',[]) return; diff --git a/subgraph/src/reality-ethv-30.ts b/subgraph/src/reality-ethv-30.ts index 3200b9d..d60e6ea 100644 --- a/subgraph/src/reality-ethv-30.ts +++ b/subgraph/src/reality-ethv-30.ts @@ -8,7 +8,7 @@ import { ModerationInfo, User, Group, UserHistory, RealityCheck, Janny } from ". import { Bytes, log, BigInt } from "@graphprotocol/graph-ts" export function handleLogNotifyOfArbitrationRequest(event: LogNotifyOfArbitrationRequest): void { - const moderationInfo = ModerationInfo.load(event.params.question_id.toHexString()) + let moderationInfo = ModerationInfo.load(event.params.question_id.toHexString()) if (!moderationInfo){ log.error('moderation info not found. {}',[event.params.question_id.toHexString()]) return @@ -32,13 +32,13 @@ export function handleLogNotifyOfArbitrationRequest(event: LogNotifyOfArbitratio export function handleLogNewAnswer(event: LogNewAnswer): void { - const moderationInfo = ModerationInfo.load(event.params.question_id.toHexString()) + let moderationInfo = ModerationInfo.load(event.params.question_id.toHexString()) if (!moderationInfo){ // answer to irrelevant question, skip return } - var realityCheck = RealityCheck.load(event.params.question_id.toHexString()) + let realityCheck = RealityCheck.load(event.params.question_id.toHexString()) if (!realityCheck) realityCheck = new RealityCheck(event.params.question_id.toHexString()) @@ -47,68 +47,25 @@ export function handleLogNewAnswer(event: LogNewAnswer): void { log.error('user missing {}',[moderationInfo.UserHistory]); return; } - const reportedByUserHistory = UserHistory.load(moderationInfo.reportedBy) - if (!reportedByUserHistory){ - log.error('reportedByUserHistory missing {}',[moderationInfo.reportedBy]); + let group = Group.load(userHistory.group); + if (!group){ + log.error('usrhistory group missing {}',[userHistory.group]); return; } - reportedByUserHistory.countReportsMadeAndResponded++ - reportedByUserHistory.save() - - var janny = Janny.load(userHistory.group) - if(!janny){ - janny = new Janny(userHistory.group) - janny.group = userHistory.group + let reportedByUserHistory = UserHistory.load(moderationInfo.reportedBy) + if (!reportedByUserHistory){ + log.error('reportedByUserHistory missing {}',[moderationInfo.reportedBy]); + return; } - let sheriffOld = janny.sheriff - let deputySheriffOld = janny.deputySheriff - - if (!sheriffOld){ - janny.sheriff = moderationInfo.reportedBy - janny.blocknumberLastUpdatedSheriff = event.block.number - janny.timestampLastUpdatedSheriff = event.block.number - janny.save() - } else if (!deputySheriffOld){ - janny.deputySheriff = moderationInfo.reportedBy - janny.deputySheriff = moderationInfo.reportedBy - janny.timestampLastUpdatedDeputySheriff = event.block.number - janny.save() - } else { - let non_null_sheriff: string = sheriffOld ? sheriffOld : 'null' // compiles just fine :) - const sheriff = UserHistory.load(non_null_sheriff) - if (!sheriff){ - log.error('sheriff missing {}',[non_null_sheriff]); - return; - } - if(sheriff.countReportsMadeAndResponded < reportedByUserHistory.countReportsMadeAndResponded){ - janny.sheriff = reportedByUserHistory.user - janny.blocknumberLastUpdatedSheriff = event.block.number - janny.timestampLastUpdatedSheriff = event.block.number - janny.save() - } else{ - let non_null_deputySheriff: string = deputySheriffOld ? deputySheriffOld : 'null' // compiles just fine :) - const deputySheriff = UserHistory.load(non_null_deputySheriff) - if (!deputySheriff){ - log.error('deputy sheriff missing {}',[non_null_deputySheriff]); - return; - } - if(deputySheriff.countReportsMadeAndResponded < reportedByUserHistory.countReportsMadeAndResponded){ - janny.deputySheriff = reportedByUserHistory.user - janny.blocknumberLastUpdatedDeputySheriff = event.block.number - janny.timestampLastUpdatedDeputySheriff = event.block.number - janny.save() - } - } - } - const currentAnswer = realityCheck.currentAnswer const yes = Bytes.fromHexString('0x0000000000000000000000000000000000000000000000000000000000000001') if(currentAnswer && currentAnswer.equals(yes)){ if (event.params.answer.notEqual(yes)){ + reportedByUserHistory.countReportsMadeAndResponded-- realityCheck.timeServed = event.block.timestamp.minus(realityCheck.deadline.minus(moderationInfo.timeout)); userHistory.countBrokeRulesOptimisticAndArbitrated-- userHistory.timestampLastUpdated = event.block.timestamp @@ -118,6 +75,7 @@ export function handleLogNewAnswer(event: LogNewAnswer): void { userHistory.timestampParole.minus(BigInt.fromU32(604800)) } } else if (event.params.answer.equals(yes)){ + reportedByUserHistory.countReportsMadeAndResponded++ realityCheck.timeServed = BigInt.fromU32(0) userHistory.countBrokeRulesOptimisticAndArbitrated++ userHistory.timestampLastUpdated = event.block.timestamp @@ -129,10 +87,62 @@ export function handleLogNewAnswer(event: LogNewAnswer): void { realityCheck.currentAnswer = event.params.answer realityCheck.blocknumberLastUpdated = event.block.number - realityCheck.timestampLastUpdated = event.block.number + realityCheck.timestampLastUpdated = event.block.timestamp realityCheck.deadline = event.block.timestamp.plus(moderationInfo.timeout); realityCheck.save() userHistory.save() + + reportedByUserHistory.save() + + if(reportedByUserHistory.countReportsMadeAndResponded > 0){ + let janny = Janny.load(userHistory.group) + if(!janny){ + janny = new Janny(userHistory.group) + janny.group = userHistory.group + janny.botAddress = moderationInfo.askedBy + } + + let sheriffOld = janny.sheriff + let deputySheriffOld = janny.deputySheriff + + if (!sheriffOld){//event.transaction.from.toHexString() + params[2] + params[1]+params[5]) + janny.sheriff = moderationInfo.reportedBy + janny.blocknumberLastUpdatedSheriff = event.block.number + janny.timestampLastUpdatedSheriff = event.block.timestamp + janny.save() + } else if (!deputySheriffOld){ + janny.deputySheriff = moderationInfo.reportedBy + janny.timestampLastUpdatedDeputySheriff = event.block.timestamp + janny.blocknumberLastUpdatedDeputySheriff = event.block.number + janny.save() + } else { + let non_null_sheriff: string = sheriffOld ? sheriffOld : 'null' // compiles just fine :) + const sheriff = UserHistory.load(non_null_sheriff) + if (!sheriff){ + log.error('sheriff missing {}',[non_null_sheriff]); + return; + } + if(sheriff.countReportsMadeAndResponded < reportedByUserHistory.countReportsMadeAndResponded){ + janny.sheriff = reportedByUserHistory.id + janny.blocknumberLastUpdatedSheriff = event.block.number + janny.timestampLastUpdatedSheriff = event.block.timestamp + janny.save() + } else{ + let non_null_deputySheriff: string = deputySheriffOld ? deputySheriffOld : 'null' // compiles just fine :) + const deputySheriff = UserHistory.load(non_null_deputySheriff) + if (!deputySheriff){ + log.error('deputy sheriff missing {}',[non_null_deputySheriff]); + return; + } + if(deputySheriff.countReportsMadeAndResponded < reportedByUserHistory.countReportsMadeAndResponded){ + janny.deputySheriff = reportedByUserHistory.id + janny.blocknumberLastUpdatedDeputySheriff = event.block.number + janny.timestampLastUpdatedDeputySheriff = event.block.timestamp + janny.save() + } + } + } + } } @@ -163,13 +173,27 @@ export function handleLogNewQuestion(event: LogNewQuestion): void { user.save(); } - const moderationInfo = new ModerationInfo(event.params.question_id.toHexString()); + let moderationInfo = new ModerationInfo(event.params.question_id.toHexString()); moderationInfo.moderationType = event.params.template_id; - moderationInfo.reportedBy = event.transaction.from.toHexString()+params[2] + params[9] - if (!User.load(moderationInfo.reportedBy)){ - const userReportedBy = new User(moderationInfo.reportedBy) - userReportedBy.userID = params[9] - userReportedBy.save() + moderationInfo.reportedBy = event.transaction.from.toHexString()+params[2] + params[9] +params[5] + if (!UserHistory.load(moderationInfo.reportedBy)){ + let reportedByUser = new UserHistory(event.transaction.from.toHexString() + params[2] + params[9]+params[5]) + reportedByUser.countBrokeRulesArbitrated = 0 + reportedByUser.countBrokeRulesOptimisticAndArbitrated = 0 + reportedByUser.countReportsMade = 0 + reportedByUser.countReportsMadeAndResponded = 0 + reportedByUser.timestampLastReport = BigInt.fromU32(0) + reportedByUser.timestampLastUpdated = BigInt.fromU32(0) + reportedByUser.timestampParole = BigInt.fromU32(0) + reportedByUser.user = event.transaction.from.toHexString() + params[2] + params[9] + reportedByUser.group = group.id + reportedByUser.save() + if(!User.load(reportedByUser.user)){ + let userReportedBy = new User(reportedByUser.user) + userReportedBy.userID = params[9] + userReportedBy.username = params[0] + userReportedBy.save() + } } moderationInfo.deadline = event.params.opening_ts.plus(event.params.timeout); moderationInfo.timeout = event.params.timeout; @@ -179,7 +203,7 @@ export function handleLogNewQuestion(event: LogNewQuestion): void { moderationInfo.reality = event.params.question_id.toHexString() moderationInfo.messageBackup = params[8]; - var reportedUser = UserHistory.load(event.transaction.from.toHexString() + params[2] + params[1]+params[5]) + let reportedUser = UserHistory.load(event.transaction.from.toHexString() + params[2] + params[1]+params[5]) if (!reportedUser){ reportedUser = new UserHistory(event.transaction.from.toHexString() + params[2] + params[1]+params[5]) reportedUser.countBrokeRulesArbitrated = 0 @@ -198,7 +222,7 @@ export function handleLogNewQuestion(event: LogNewQuestion): void { moderationInfo.save(); - var reportedByUserHistory = UserHistory.load(moderationInfo.reportedBy+params[5]) + let reportedByUserHistory = UserHistory.load(moderationInfo.reportedBy+params[5]) if (!reportedByUserHistory){ reportedByUserHistory = new UserHistory(moderationInfo.reportedBy+params[5]) reportedByUserHistory.user = moderationInfo.reportedBy diff --git a/types.d.ts b/types.d.ts index cd29b82..2776c07 100644 --- a/types.d.ts +++ b/types.d.ts @@ -9,4 +9,14 @@ interface groupSettings { thread_id_notifications: string; thread_id_welcome: string; greeting_mode: boolean; + } + + interface groupSettingsUnderspecified { + lang: string | undefined; + rules: string | undefined; + channelID: string | undefined; + thread_id_rules: string | undefined; + thread_id_notifications: string | undefined; + thread_id_welcome: string | undefined; + greeting_mode: boolean | undefined; } \ No newline at end of file From 68ff58e91ca9ef5f38ff44d8ef2bef3f67ab4c84 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Mon, 5 Dec 2022 00:15:39 -0700 Subject: [PATCH 008/111] feat(ux): help dialouge --- lib/telegram/commands/addEvidenceHelp.ts | 42 ++++++++++++++++++++++++ subgraph/subgraph.yaml | 6 ++-- 2 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 lib/telegram/commands/addEvidenceHelp.ts diff --git a/lib/telegram/commands/addEvidenceHelp.ts b/lib/telegram/commands/addEvidenceHelp.ts new file mode 100644 index 0000000..0dc9e04 --- /dev/null +++ b/lib/telegram/commands/addEvidenceHelp.ts @@ -0,0 +1,42 @@ +import * as TelegramBot from "node-telegram-bot-api"; +import {getRule} from "../../db"; +import langJson from "../assets/lang.json"; +import { getUsersWithQuestionsNotFinalized } from "../../db"; +import { groupSettings } from "../../../types"; + +/* + * /addevidencehelp + */ +const regexp = /\/addevidencehelp/ + +const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { + const groupId = getUsersWithQuestionsNotFinalized(db, 'telegram', msg.text.substring(22)) + if (!groupId || groupId.length === 0){ + bot.sendMessage(msg.chat.id, `There are no reports to add evidence to in your group.`); + } + var inline_keyboard_evidence = [] + var inline_keyboard_evidence_cursor = []; + groupId.forEach((element, index) => { + if (index % 3 === 0){ + if(inline_keyboard_evidence_cursor.length > 0){ + inline_keyboard_evidence.push(inline_keyboard_evidence_cursor) + } + inline_keyboard_evidence_cursor = [] + } + inline_keyboard_evidence_cursor.push({ + text: element.username, + callback_data: '4|'+msg.text.substring(22)+'|'+element.user_id + }); + }); + inline_keyboard_evidence.push(inline_keyboard_evidence_cursor) + + const opts = { + parse_mode: 'Markdown', + reply_markup: { + inline_keyboard: inline_keyboard_evidence + } + } + bot.sendMessage(msg.chat.id, `Let me help you find the report you want to add evidence to. Which user is the report about?`,opts); +} + +export {regexp, callback}; \ No newline at end of file diff --git a/subgraph/subgraph.yaml b/subgraph/subgraph.yaml index 8c92d01..5583225 100644 --- a/subgraph/subgraph.yaml +++ b/subgraph/subgraph.yaml @@ -36,7 +36,7 @@ dataSources: source: address: "0xAa5681047a16F163391377Fd9f78e84355Cc9696" #goerli "0xAa5681047a16F163391377Fd9f78e84355Cc9696" #xdai 0x2a2bAB2C2D4eB5007b0389720b287D4D19dc4001# xdai me "0x36a4e90568ce270aB671F55547C5EAe428B6c03A" abi: Realitio_v2_1_ArbitratorWithAppeals - startBlock: 7913496 #7913496 #goerli, xdai 23143918 + startBlock: 8034496 #7913496 #goerli, xdai 23143918 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -51,8 +51,6 @@ dataSources: eventHandlers: - event: DisputeIDToQuestionID(indexed uint256,bytes32) handler: handleDisputeIDToQuestionID - - event: Evidence(indexed address,indexed uint256,indexed address,string) - handler: handleEvidence - event: RulingFunded(indexed uint256,indexed uint256,indexed uint256) handler: handleRulingFunded - event: Ruling(indexed address,indexed uint256,uint256) @@ -62,7 +60,7 @@ dataSources: name: KlerosLiquid network: goerli #xdai source: - address: "0x209469C921db9d5Bd77084370e80B63d5cdD63C1" # goerli 0x209469C921db9d5Bd77084370e80B63d5cdD63C1 + address: "0x1128eD55ab2d796fa92D2F8E1f336d745354a77A" # goerli 0x209469C921db9d5Bd77084370e80B63d5cdD63C1 abi: KlerosLiquid startBlock: 7913496 #7913496 #goerli, xdai 23143918 mapping: From 71dbeb2410dbd7592f582bbd3da5429760924d0a Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Mon, 12 Dec 2022 21:17:36 -0700 Subject: [PATCH 009/111] feat: big update federations, topic mode --- lib/create-db.ts | 82 ++--- lib/cron.ts | 169 ++++++---- lib/db.ts | 432 ++++++++++++++++++++----- lib/telegram/commands/addEvidence.ts | 19 +- lib/telegram/commands/fedinfo.ts | 70 ++++ lib/telegram/commands/getReports.ts | 67 +++- lib/telegram/commands/greeting.ts | 48 ++- lib/telegram/commands/help.ts | 9 +- lib/telegram/commands/joinfed.ts | 23 +- lib/telegram/commands/newfed.ts | 70 ++++ lib/telegram/commands/report.ts | 21 +- lib/telegram/commands/setChannel.ts | 2 +- lib/telegram/commands/start.ts | 26 +- lib/telegram/commands/toggleCaptcha.ts | 27 ++ lib/telegram/commands/toggleWelcome.ts | 16 +- lib/telegram/commands/welcome.ts | 2 +- lib/telegram/index.ts | 72 ++++- package.json | 1 + types.d.ts | 8 + 19 files changed, 897 insertions(+), 267 deletions(-) create mode 100644 lib/telegram/commands/fedinfo.ts create mode 100644 lib/telegram/commands/newfed.ts create mode 100644 lib/telegram/commands/toggleCaptcha.ts diff --git a/lib/create-db.ts b/lib/create-db.ts index 2ec739d..c03d8d6 100644 --- a/lib/create-db.ts +++ b/lib/create-db.ts @@ -21,8 +21,11 @@ const Database = require('better-sqlite3'); thread_id_welcome TEXT, invite_url TEXT, invite_url_channel TEXT, - federation_owner_user_id TEXT, - greeting_mode INTEGER, + federation_id TEXT, + federation_id_following TEXT, + greeting_mode BIT, + admins_reportable BIT, + captcha BIT, lang TEXT, rules TEXT, PRIMARY KEY (platform, group_id))` @@ -45,29 +48,9 @@ const Database = require('better-sqlite3'); report_allowance INTEGER, evidence_allowance INTEGER, timestamp_refresh INTEGER, - timestamp_parole INTEGER, PRIMARY KEY (platform, group_id, user_id))` ); - /** - * `question_id` is the id of the question in reality.eth - * `platform` can be `telegram`, `reddit`, etc. - * `group_id` is the id of the group on the platform (eg. group on telegram, subreddit on reddit, etc.). - * `user_id` is the id of the banned user in `platform`. - * `chat_id` is the id of the banned user in `platform`. - * `active` indicates whether the user is currently banned. - * `finalized` indicates if the question has finalized. - */ - await db.exec( - `CREATE TABLE banHistory ( - platform TEXT, - group_id TEXT, - user_id TEXT, - ban_level INTEGER, - count_current_level_optimistic_bans INTEGER, - timestamp_ban INTEGER, - PRIMARY KEY (platform, group_id, user_id))` - ); /** * `platform` can be `telegram`, `reddit`, etc. @@ -101,44 +84,63 @@ const Database = require('better-sqlite3'); user_id TEXT, username TEXT, msg_id TEXT, - timestamp INTEGER, evidenceIndex INTEGER, msgBackup TEXT, - active_timestamp INTEGER, - active BIT, - banLevel BIT, - finalized BIT, + timestamp_msg INTEGER, + timestamp_report INTEGER, + timestamp_active INTEGER, timestamp_finalized INTEGER, - disputed BIT + disputed BIT, + answered BIT, + active BIT, + finalized BIT )` ); /** - * `question_id` is the id of the question in reality.eth * `platform` can be `telegram`, `reddit`, etc. - * `group_id` is the id of the group on the platform (eg. group on telegram, subreddit on reddit, etc.). + * `federation_id` is the user_id of the federation owner on the platform (eg. group on telegram, subreddit on reddit, etc.). * `user_id` is the id of the banned user in `platform`. - * `chat_id` is the id of the banned user in `platform`. - * `active` indicates whether the user is currently banned. - * `finalized` indicates if the question has finalized. */ await db.exec( `CREATE TABLE federations ( platform TEXT, - owner_user_id TEXT, - group_id TEXT[], - PRIMARY KEY (platform, owner_user_id))` + federation_id, + notification_channel_id, + invite_url_channel TEXT, + name TEXT, + PRIMARY KEY (platform, federation_id))` + ); + + /** + * `platform` can be `telegram`, `reddit`, etc. + * `group_id` is the id of the group on the platform (eg. group on telegram, subreddit on reddit, etc.). + * `user_id` is the id of the banned user in `platform`. + */ + await db.exec( + `CREATE TABLE federationSubscriptions ( + platform TEXT, + federation_id_subscriber, + federation_id_subscribed, + PRIMARY KEY (platform, federation_id_subscriber, federation_id_subscribed))` ); /** - * `question_id` is the id of the question in reality.eth * `platform` can be `telegram`, `reddit`, etc. * `group_id` is the id of the group on the platform (eg. group on telegram, subreddit on reddit, etc.). * `user_id` is the id of the banned user in `platform`. - * `chat_id` is the id of the banned user in `platform`. - * `active` indicates whether the user is currently banned. - * `finalized` indicates if the question has finalized. */ + await db.exec( + `CREATE TABLE federationAdmin ( + platform TEXT, + federation_id, + admin_id, + PRIMARY KEY (platform, federation_id, admin_id))` + ); + + /** + * + **/ await db.exec( `CREATE TABLE cron ( bot_index INTEGER, diff --git a/lib/cron.ts b/lib/cron.ts index ce9e9a7..8a3ae8a 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -1,10 +1,11 @@ require('dotenv').config() -import {openDb, getGroupSettings, getRule, getCron, setCron, getReportMessageTimestampAndActive, setBanHistory, setReport, getBanHistory} from "./db"; +import {openDb, getGroupSettings, getRule, getCron, getTimestampFinalized, getFederatedFollowingBanHistory, getLocalBanHistory, getFederatedBanHistory, setCron, getGroupsInAndFollowingFederation, getReportMessageTimestampAndActive, setReport} from "./db"; import request from "graphql-request"; import {BigNumber} from "ethers"; import TelegramBot from "node-telegram-bot-api"; import langJson from "./telegram/assets/lang.json"; import {Wallet} from "@ethersproject/wallet"; +const {default: PQueue} = require('p-queue'); import {groupSettings, groupSettingsUnderspecified} from "../types"; const ModeratorBot = require('node-telegram-bot-api'); const NodeCache = require( "node-cache" ); @@ -12,8 +13,8 @@ const Web3 = require('web3') const realitio_bot = require('./realitioReporting') const myCache = new NodeCache( { stdTTL: 900, checkperiod: 1200 } ); const db = openDb(); -const bot: TelegramBot = new ModeratorBot(process.env.BOT_TOKEN, {polling: false}); - +const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: false, testEnvironment: true}); +const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCount: true}); // Only need DB for // - channelID // - finalizedReportCount @@ -35,6 +36,9 @@ const bot: TelegramBot = new ModeratorBot(process.env.BOT_TOKEN, {polling: false last_timestamp: currentTime, last_block: currentBlock } + // hardcode values for tests + //history.last_timestamp = 1670802755 + //history.last_block = 25402583 const graphSyncingPeriod = 300; const timestampNew = currentTime const timestampLastUpdated = history.last_timestamp @@ -57,7 +61,7 @@ const bot: TelegramBot = new ModeratorBot(process.env.BOT_TOKEN, {polling: false //console.log('graphtime'); //console.log(queryModeration) const moderationActions = await request( - 'https://api.thegraph.com/subgraphs/name/shotaronowhere/kleros-moderate-goerli', + process.env.MODERATE_SUBGRAPH, queryModeration ); console.log(JSON.stringify(moderationActions)) @@ -72,8 +76,8 @@ const bot: TelegramBot = new ModeratorBot(process.env.BOT_TOKEN, {polling: false const message = (data.finalRuling === 2)? 'broke the rules' : 'did not break the rules' console.log(data.finalRuling) try{ - bot.sendMessage(settings.channelID, `The [dispute](${disputeURL}) over *${data.moderationInfo.UserHistory.user.username}*'s [message](${msgLink}) ([backup](${data.moderationInfo.messageBackup})) resolved. *${data.moderationInfo.UserHistory.user.username}* ${message}`, {parse_mode: 'Markdown'}); - handleTelegramUpdate(db, bot,settings, data.moderationInfo,timestampNew, data.finalRuling === 2, true); + bot.sendMessage(settings.channelID, `The [dispute](${disputeURL}) over *${data.moderationInfo.UserHistory.user.username}*'s [message](${msgLink}) ([backup](${data.moderationInfo.messageBackup})) resolved. *${data.moderationInfo.UserHistory.user.username}* ${message}`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); + handleTelegramUpdate(db, bot,settings, data.moderationInfo,timestampNew, data.finalRuling === 2, true, true); } catch(e){ console.log(e) } @@ -91,7 +95,7 @@ const bot: TelegramBot = new ModeratorBot(process.env.BOT_TOKEN, {polling: false // settings[1] language try{ //TODO - bot.sendMessage(settings.channelID, `The dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'} If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, {parse_mode: 'Markdown', disable_web_page_preview: true}); + bot.sendMessage(settings.channelID, `The dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'} If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true}); } catch(e){ console.log(e) } @@ -103,8 +107,8 @@ const bot: TelegramBot = new ModeratorBot(process.env.BOT_TOKEN, {polling: false const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; const disputeURL = `https://resolve.kleros.io/cases/${BigNumber.from(data.id).toNumber()}`; try{ - bot.sendMessage(settings.channelID, `Arbitration is requested for the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})). Consequences of the report are lifted for the duration of the [dispute](${disputeURL}) (on Gnosis Chain).`, {parse_mode: 'Markdown', disable_web_page_preview: true}); - handleTelegramUpdate(db, bot,settings, data.moderationInfo,timestampNew, false, false); + bot.sendMessage(settings.channelID, `Arbitration is requested for the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})). Consequences of the report are lifted for the duration of the [dispute](${disputeURL}) (on Gnosis Chain).`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true}); + handleTelegramUpdate(db, bot,settings, data.moderationInfo,timestampNew, false, false, true); } catch (e){ console.log(e) } @@ -114,7 +118,7 @@ const bot: TelegramBot = new ModeratorBot(process.env.BOT_TOKEN, {polling: false const settings = validate(data.moderationInfo.UserHistory.group.groupID); // settings[1] language try{ - bot.sendMessage(settings.channelID, "An appeal has been funded"); + bot.sendMessage(settings.channelID, "An appeal has been funded",settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); } catch(e){ console.log(e) } @@ -137,9 +141,9 @@ const bot: TelegramBot = new ModeratorBot(process.env.BOT_TOKEN, {polling: false //bot.sendMessage(settings[0], `The reality question ${data.id} is finalized with ${data.currentAnswer}`); const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; - bot.sendMessage(settings.channelID, `The [report](${realityURL}) is finalized.`, {parse_mode: 'Markdown'}); + bot.sendMessage(settings.channelID, `The [report](${realityURL}) is finalized.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); // finalize - handleTelegramUpdate(db, bot, settings, data.moderationInfo, timestampNew, data.finalRuling === "0x0000000000000000000000000000000000000000000000000000000000000001", true); + handleTelegramUpdate(db, bot, settings, data.moderationInfo, timestampNew, data.finalRuling === "0x0000000000000000000000000000000000000000000000000000000000000001", true, false); } catch(e){ console.log(e) } @@ -152,19 +156,20 @@ const bot: TelegramBot = new ModeratorBot(process.env.BOT_TOKEN, {polling: false try{ const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; const answer = data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001" ? "yes" : "no"; - bot.sendMessage(settings.channelID, `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) violate the [rules](${data.moderationInfo.rules})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, {parse_mode: 'Markdown', disable_web_page_preview: true}); - handleTelegramUpdate(db, bot,settings, data.moderationInfo,timestampNew, data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001", false); + bot.sendMessage(settings.channelID, `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) violate the [rules](${data.moderationInfo.rules})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true}); + handleTelegramUpdate(db, bot,settings, data.moderationInfo,timestampNew, data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001", false, false); } catch(e){ console.log(e) } } + // promise queue example for(const data of moderationActions.sheriffs){ const settings = validate(data.group.groupID); // settings[1] language try{ const sherrif = await bot.getChatMember(data.group.groupID, data.sheriff.user.userID) - bot.sendMessage(settings.channelID, `There's a new sheriff in town 👑🥇🤠[${sherrif.user.username}](tg://user?id=${sherrif.user.id})🤠🥇👑`,{parse_mode: "Markdown"}); + queue.add(() => bot.sendMessage(settings.channelID, `There's a new sheriff in town 👑🥇🤠[${sherrif.user.username}](tg://user?id=${sherrif.user.id})🤠🥇👑`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})); } catch(e){ console.log(e) } @@ -175,13 +180,13 @@ const bot: TelegramBot = new ModeratorBot(process.env.BOT_TOKEN, {polling: false // settings[1] language try{ const deputysherrif = await bot.getChatMember(data.group.groupID, data.sheriff.user.userID) - bot.sendMessage(settings.channelID, `There's a new deputy sheriff in town 🥈[${deputysherrif.user.username}](tg://user?id=${deputysherrif.user.id})🥈`); + bot.sendMessage(settings.channelID, `There's a new deputy sheriff in town 🥈[${deputysherrif.user.username}](tg://user?id=${deputysherrif.user.id})🥈`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); } catch(e){ console.log(e) } } - + await queue.onIdle() await realitio_bot(web3, history.last_block, process.env.REALITY_ETH_V30, process.env.REALITIO_ARBITRATOR); setCron(db, currentBlock,currentTime) return; @@ -194,9 +199,13 @@ const validate = (chatId: string): groupSettings=> { rules: langJson['en'].defaultRules, channelID: '', greeting_mode: false, + captcha: false, + admin_reportable: false, thread_id_rules: '', thread_id_welcome: '', - thread_id_notifications: '' + thread_id_notifications: '', + federation_id: '', + federation_id_following: '' } var groupSettings : groupSettingsUnderspecified = myCache.get(chatId) if (!groupSettings){ @@ -210,65 +219,99 @@ const validate = (chatId: string): groupSettings=> { rules: groupSettings?.rules ?? defaultSettings.rules, channelID: groupSettings?.channelID ?? chatId, greeting_mode: groupSettings?.greeting_mode ?? defaultSettings.greeting_mode, + admin_reportable: groupSettings?.admin_reportable ?? defaultSettings.admin_reportable, + captcha: groupSettings?.captcha ?? defaultSettings.captcha, thread_id_rules: groupSettings?.thread_id_rules ?? defaultSettings.thread_id_rules, thread_id_welcome: groupSettings?.thread_id_welcome ?? defaultSettings.thread_id_rules, - thread_id_notifications: groupSettings?.thread_id_notifications ?? defaultSettings.thread_id_notifications + thread_id_notifications: groupSettings?.thread_id_notifications ?? defaultSettings.thread_id_notifications, + federation_id: groupSettings?.federation_id ?? defaultSettings.federation_id, + federation_id_following: groupSettings?.federation_id_following ?? defaultSettings.federation_id, } return fullSettings } -const handleTelegramUpdate = async (db: any, bot: TelegramBot, settings: groupSettings, moderationInfo: any, timestampNew: number, restrict: boolean, finalize: boolean) => { +const calcPenalty = (ban_level: number, timestamp_finalized: number): number => { + if(ban_level == 0) + return timestamp_finalized + 86400 + else if (ban_level == 1) + return timestamp_finalized + 604800 + else + return timestamp_finalized + 220147200 +} + +const calcPenaltyPhrase = (ban_level: number): string => { + if(ban_level == 0) + return 'first time and is subject to a 1 day' + else if (ban_level == 1) + return 'second time and is subject to a 1 week' + else + return 'atleast three times and is subject to a 1 year' +} + +const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, moderationInfo: any, timestampNew: number, restrict: boolean, finalize: boolean, disputed: boolean) => { try{ const reportInfo = getReportMessageTimestampAndActive(db, moderationInfo.id) - console.log(moderationInfo.id) - console.log(reportInfo) - const banHistory = getBanHistory(db, 'telegram',moderationInfo.UserHistory.group.groupID, moderationInfo.UserHistory.user.userID)?? {ban_level: 0, timestamp_ban: 0, count_current_level_optimistic_bans: 0} - setReport(db, moderationInfo.id,restrict,finalize,timestampNew) + if (!reportInfo) return; + let calculateHistory = [] + + if (settings.federation_id) + calculateHistory = getFederatedBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,moderationInfo.UserHistory.group.groupID,finalize) + else { + if (settings.federation_id_following) + calculateHistory = getFederatedFollowingBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,moderationInfo.UserHistory.group.groupID,settings.federation_id_following,finalize) + else + calculateHistory = getLocalBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,moderationInfo.UserHistory.group.groupID,finalize) + } + + const ban_level_history = Math.max(calculateHistory.length-1,0) + + setReport(db, moderationInfo.id,restrict,true,finalize,disputed, finalize? 0 : (restrict? timestampNew: 0), finalize? timestampNew: 0) + + if (settings.federation_id){ + calculateHistory = getFederatedBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,moderationInfo.UserHistory.group.groupID,finalize) + } else { + if (settings.federation_id_following){ + calculateHistory = getFederatedFollowingBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,moderationInfo.UserHistory.group.groupID,settings.federation_id_following,finalize) + } else + calculateHistory = getLocalBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,moderationInfo.UserHistory.group.groupID,finalize) + } + + const ban_level_current = Math.max(calculateHistory.length-1,0) + + if (restrict){ - var duration: string; - var parole: number; - if (reportInfo.timestamp > banHistory.timestamp_ban){ - if(banHistory.ban_level == 0){ - duration = 'first time and is subject to a 1 day'; - parole = timestampNew + 86400 - } else if (banHistory.ban_level == 1){ - duration = 'second time and is subject to a 1 week'; - parole = timestampNew + 604800 - } else{ - duration = 'atleast three times and is subject to a 1 year'; - parole = timestampNew + 220147200 - } + // TODO federation subscriptions + const groups = settings.federation_id? getGroupsInAndFollowingFederation(db,'telegram',settings.federation_id) : [moderationInfo.UserHistory.group.groupID] + if (ban_level_current > ban_level_history){ + const parole = calcPenalty(ban_level_current,timestampNew) if(finalize){ - banHistory.ban_level++ - banHistory.count_current_level_optimistic_bans = 0 - banHistory.timestamp_ban = timestampNew - bot.banChatMember(moderationInfo.user.group.groupID, moderationInfo.userID, parole); + // if message reported timestamp is before the most recent finalized ban / penality, users deserve a second chance, no action taken + // philosophy is only escalate the penalties after the user is warned with a temporary ban. + // this report changed penalties, recalculate all + for (const group of groups) + bot.banChatMember(group.group_id, moderationInfo.UserHistory.user.userID, parole); + } else if(!finalize){ + const options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false, until_date: parole}; + for (const group of groups) + bot.restrictChatMember(group.group_id, moderationInfo.UserHistory.user.userID, options); } - const options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false, until_date: parole}; - bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}) for the ${duration} ban.`, {parse_mode: 'Markdown', disable_web_page_preview: true}); - if(!finalize && reportInfo?.active !== Number(restrict)){ - //TODO Federation - bot.restrictChatMember(moderationInfo.UserHistory.group.groupID, moderationInfo.UserHistory.user.userID, options); - banHistory.count_current_level_optimistic_bans++ - } - setBanHistory(db, 'telegram',moderationInfo.UserHistory.group.groupID, moderationInfo.UserHistory.user.userID,banHistory.ban_level,banHistory.timestamp_ban,banHistory.count_current_level_optimistic_bans) + // TODO notify federation + bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}) for the ${calcPenaltyPhrase(calculateHistory.length-1)} ban.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true}); } else{ - bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messsageBackup})) violated the [rules](${moderationInfo.rulesUrl}). The conduct occured before *${moderationInfo.UserHistory.user.username}*'s latest effective ban.\nModeration is about both rehabilitation and punishment. We all make mistakes and we deserve second chances. Let's give ${moderationInfo.UserHistory.user.username} another chance. The next time ${moderationInfo.UserHistory.user.username} breaks the rules, the consequences are more severe though. Here's to healthier communities : )`, {parse_mode: 'Markdown'}); - } - } else { - var noOptimisticReports = 0 - if(reportInfo.active != Number(restrict)){ - setBanHistory(db, 'telegram',moderationInfo.UserHistory.group.groupID, moderationInfo.UserHistory.user.userID,banHistory.ban_level,banHistory.timestamp_ban,Math.max(banHistory.count_current_level_optimistic_bans-1,0)) - noOptimisticReports = 1 + bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messsageBackup})) violated the [rules](${moderationInfo.rulesUrl}). The conduct occured before *${moderationInfo.UserHistory.user.username}*'s latest effective ban. The next time ${moderationInfo.UserHistory.user.username} breaks the rules, the consequences are more severe.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true}); } - if (banHistory.count_current_level_optimistic_bans === noOptimisticReports){ // only optimistic report removed. - const options = {can_send_messages: true, can_send_media_messages: true, can_send_polls: true, can_send_other_messages: true, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false}; - bot.restrictChatMember(moderationInfo.UserHistory.group.groupID, moderationInfo.UserHistory.user.userID, options); - bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}* has no other active reports. All bans are lifted.`, {parse_mode: 'Markdown'}); - } else { - bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}* has other active reports, and is still restricted.`, {parse_mode: 'Markdown'}); + } else if (ban_level_current < ban_level_history){ + let liftbans = true; + for (const ban_level of calculateHistory) + if (ban_level.timestamp_active > 0) + liftbans = false + if(liftbans){ + const options = {can_send_messages: true, can_send_media_messages: true, can_send_polls: true, can_send_other_messages: true, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false}; + bot.restrictChatMember(moderationInfo.UserHistory.group.groupID, moderationInfo.UserHistory.user.userID, options); + bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}* has no other active reports. All bans are lifted.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); + } else + bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}* has other active reports, and is still restricted.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); } - } } catch(e){ console.log(e) } diff --git a/lib/db.ts b/lib/db.ts index 05f451b..510cac0 100644 --- a/lib/db.ts +++ b/lib/db.ts @@ -21,28 +21,56 @@ const setLang = (db: any, platform: string, groupId: string, lang: string) => { } } -const joinFederation = (db: any, platform: string, groupId: string, owner_user_id: string) => { +const joinFederation = (db: any, platform: string, groupId: string, federation_id: string) => { try{ const stmt = db.prepare( - `INSERT INTO groups (platform, group_id, owner_user_id) + `INSERT INTO groups (platform, group_id, federation_id) VALUES (?, ?, ?) ON CONFLICT(platform, group_id) DO UPDATE SET - owner_user_id=?;`); - const info = stmt.run(platform, groupId, owner_user_id, owner_user_id); + federation_id=?;`); + const info = stmt.run(platform, groupId, federation_id, federation_id); } catch(err) { console.log("db error: joinFederation"); console.log(err); } } -const leaveFederation = (db: any, platform: string, groupId: string, owner_user_id: string) => { +const setFederation = (db: any, platform: string, name: string, federation_id: string) => { try{ const stmt = db.prepare( - `INSERT INTO groups (platform, group_id, owner_user_id) + `INSERT INTO federations (platform, federation_id, name) + VALUES (?, ?, ?) + ON CONFLICT(platform, federation_id) DO UPDATE SET + name=?;`); + const info = stmt.run(platform, federation_id, name, name); + } catch(err) { + console.log("db error: joinFederation"); + console.log(err); + } +} + +const followFederation = (db: any, platform: string, groupId: string, federation_id_following: string) => { + try{ + const stmt = db.prepare( + `INSERT INTO groups (platform, group_id, federation_id_following) VALUES (?, ?, ?) ON CONFLICT(platform, group_id) DO UPDATE SET - owner_user_id=?;`); - const info = stmt.run(platform, groupId, owner_user_id, owner_user_id); + federation_id_following=?;`); + const info = stmt.run(platform, groupId, federation_id_following, federation_id_following); + } catch(err) { + console.log("db error: joinFederation"); + console.log(err); + } +} + +const leaveFederation = (db: any, platform: string, groupId: string, federation_id: string) => { + try{ + const stmt = db.prepare( + `INSERT INTO groups (platform, group_id, federation_id) + VALUES (?, ?, ?) + ON CONFLICT(platform, group_id) DO UPDATE SET + federation_id=?;`); + const info = stmt.run(platform, groupId, federation_id, federation_id); } catch(err) { console.log("db error: leaveFederation"); console.log(err); @@ -92,9 +120,9 @@ const setChannelID = (db: any, platform: string, groupId: string, channel_id: st } } -const getDisputedReportsInfo = (db:any, platform: string, groupId: string) => { +const getActiveReportsInfo = (db:any, platform: string, groupId: string) => { try{ - const stmt = db.prepare('SELECT * FROM reports WHERE finalized = 0 AND group_id = ? AND platform = ? AND active_timestamp > 0'); + const stmt = db.prepare('SELECT * FROM reports WHERE group_id = ? AND platform = ? AND answered IS NOT NULL'); return stmt.all(groupId, platform); } catch(err){ console.log("db error: getDisputedReports"); @@ -102,11 +130,11 @@ const getDisputedReportsInfo = (db:any, platform: string, groupId: string) => { } } -const getFederationGroups = (db: any, platform: string, owner_user_id: string) => { +const getFederationGroups = (db: any, platform: string, federation_id: string) => { try{ const stmt = db.prepare( - `SELECT group_id FROM groups WHERE platform=? AND owner_user_id=?;`); - const info = stmt.run(platform, platform, owner_user_id); + `SELECT group_id FROM groups WHERE platform=? AND federation_id=?;`); + const info = stmt.run(platform, platform, federation_id); } catch(err) { console.log("db error: setLang"); console.log(err); @@ -122,8 +150,33 @@ const setGreetingMode = (db: any, platform: string, groupId: string, greeting_mo greeting_mode = ?;`); const info = stmt.run(platform, groupId, greeting_mode, greeting_mode); } catch(err) { - console.log("db error: set setGreetingMode"); - console.log(err); + console.log("db error: set setGreetingMode "+err); + } +} + +const setCaptchaMode = (db: any, platform: string, groupId: string, captcha_mode: number) => { + try{ + const stmt = db.prepare( + `INSERT INTO groups (platform, group_id, captcha) + VALUES (?, ?, ?) + ON CONFLICT (platform, group_id) DO UPDATE SET + captcha = ?;`); + const info = stmt.run(platform, groupId, captcha_mode, captcha_mode); + } catch(err) { + console.log("db error: setCaptchaMode "+ err); + } +} + +const setAdminReportableMode = (db: any, platform: string, groupId: string, admin_reportable_mode: number) => { + try{ + const stmt = db.prepare( + `INSERT INTO groups (platform, group_id, admins_reportable) + VALUES (?, ?, ?) + ON CONFLICT (platform, group_id) DO UPDATE SET + admins_reportable = ?;`); + const info = stmt.run(platform, groupId, admin_reportable_mode, admin_reportable_mode); + } catch(err) { + console.log("db error: setAdminReportableMode "+err); } } @@ -207,10 +260,20 @@ const getInviteURLChannel = (db: any, platform: string, groupId: string) => { const existsQuestionId = (db: any, question_id: string): boolean => { try{ - const stmt = db.prepare('SELECT * FROM reports WHERE question_id = ?'); + const stmt = db.prepare('SELECT question_id FROM reports WHERE question_id = ?'); return stmt.get(question_id)?.length > 0; } catch(err){ - console.log("db error: getGreetingMode"); + console.log("db error: existsQuestionId"); + console.log(err); + } +} + +const getFederationName = (db: any, platform: string, federation_id: string): string | undefined => { + try{ + const stmt = db.prepare('SELECT name FROM federations WHERE platform = ? AND federation_id = ?'); + return stmt.get(platform, federation_id)?.name; + } catch(err){ + console.log("db error: getFederationName"); console.log(err); } } @@ -249,6 +312,10 @@ const getGroupSettings = (db: any, platform: string, groupId: string): groupSett thread_id_notifications: result?.thread_id_notifications, thread_id_welcome: result?.thread_id_welcome, greeting_mode: result?.greeting_mode, + captcha: result?.captcha, + admin_reportable: result?.admin_reportable, + federation_id: result?.federation_id, + federation_id_following: result?.federation_id_following, } } catch(err){ console.log("db error: getGroupSettings"); @@ -266,22 +333,12 @@ const getThreadIDRules = (db: any, platform: string, groupId: string) => { } } -const getConcurrentReports = (db: any, platform: string, groupId: string, userId: string, timestamp: number) => { +const getReportsUserInfo = (db:any, platform: string, groupId: string, userId: string) => { try{ - const stmt = db.prepare('SELECT question_id, msg_id, group_id, timestamp FROM reports WHERE timestamp BETWEEN ? AND ? AND user_id = ? AND group_id = ? AND platform = ?'); - return stmt.all(timestamp - 3600, timestamp + 3600, userId, groupId, platform); - } catch(err){ - console.log("db error: getConcurrentReports"); - console.log(err); - } -} - -const getDisputedReportsUserInfo = (db:any, platform: string, groupId: string, userId: string) => { - try{ - const stmt = db.prepare('SELECT question_id, active, active_timestamp,msgBackup, msg_id, evidenceIndex, timestamp FROM reports WHERE user_id = ? AND group_id = ? AND platform = ? AND finalized = 0'); + const stmt = db.prepare('SELECT question_id, active,msgBackup, msg_id, evidenceIndex, timestamp_msg, finalized FROM reports WHERE user_id = ? AND group_id = ? AND platform = ?'); return stmt.all(userId, groupId, platform); } catch(err){ - console.log("db error: getDisputedReportsUserInfo"); + console.log("db error: getReportsUserInfo"); console.log(err); } } @@ -340,40 +397,252 @@ const getAllowance = (db: any, platform: string, groupId: string, userId: string } } -const setReport = (db: any, questionId: string, active: boolean, finalized: boolean, activeTimestamp: number) => { +const setReport = (db: any, questionId: string, active: boolean, answered: boolean, finalized: boolean, disputed: boolean, timestamp_active: number, timestamp_finalized: number) => { try{ const stmt = db.prepare( - 'UPDATE reports SET active = ?, finalized = ?, active_timestamp = ? WHERE question_id = ?', + `UPDATE reports SET active = ?, answered = ?, finalized = ?, disputed = ?, timestamp_active = ?, timestamp_finalized = ? + WHERE question_id = ?` ); - const info = stmt.run(Number(active), Number(finalized), activeTimestamp, questionId); + const info = stmt.run(Number(active), Number(answered),Number(finalized), Number(disputed), timestamp_active, timestamp_finalized, questionId); } catch(err) { console.log("db error: setReport"); console.log(err); } } -const getBanHistory = (db: any, platform: string, groupId: string, userId: string): {ban_level: number, timestamp_ban: number, count_current_level_optimistic_bans: number} | undefined => { +const getActiveEvidenceGroupId = (db: any, platform: string, groupId: string, evidenceIndex: number) => { try{ - const stmt = db.prepare('SELECT ban_level, timestamp_ban, count_current_level_optimistic_bans FROM banHistory WHERE user_id = ? AND group_id = ? AND platform = ?'); - return stmt.get(userId, groupId, platform); - } catch(e){ - console.log("db error: getBanHistory "+e); + const stmt = db.prepare( `SELECT question_id FROM reports WHERE platform = ? AND group_id = ? AND evidenceIndex = ? AND finalized IS NULL`); + return stmt.get(platform, groupId, evidenceIndex)?.question_id; + } catch(err) { + console.log("db error: getActiveEvidenceGroupId" + err); } } -const getActiveEvidenceGroupId = (db: any, platform: string, groupId: string, evidenceIndex: number) => { +const isInFederation = (db: any, platform: string, federationId: string) => { try{ - const stmt = db.prepare( `SELECT question_id FROM reports WHERE platform = ? AND group_id = ? AND evidenceIndex = ? AND finalized = 0`); - return stmt.get(platform, groupId, evidenceIndex)?.question_id; - } catch(err) { - console.log("db error: getActiveEvidenceGroupId"); - console.log(err); + const stmt = db.prepare( ` + SELECT group_id + FROM groups + WHERE federation_id = ? AND platform = ? + `); + return stmt.get(federationId, platform)?.length > 0 + } catch (err){ + console.log("db error: getGroupsInFederation" + err); + } +} + +const getGroupsInFederation = (db: any, platform: string, federationId: string) => { + try{ + const stmt = db.prepare( ` + SELECT group_id + FROM groups + WHERE federation_id = ? AND platform = ? + `); + return stmt.all(federationId, platform) + } catch (err){ + console.log("db error: getGroupsInFederation" + err); + } +} + +const getGroupsInAndFollowingFederation = (db: any, platform: string, federationId: string) => { + try{ + const stmt = db.prepare( ` + SELECT group_ids + FROM groups + WHERE platform = ? AND (federation_id = ? OR federation_id_following = ?) + `); + return stmt.all(platform, federationId, federationId) + } catch (err){ + console.log("db error: getGroupsInAndFollowingFederation" + err); } } +const getLocalBanHistory = (db: any, platform: string, userId: string, group_id: string, finalized: boolean) => { + const base = getLocalBanHistoryBase(db, platform, userId, group_id, finalized) + if (!base) + return []; + + // sqlit3 couldn't do recursive agregate queries + // report ban depth is capped at 3 or 4 levels (1 day, 1 week, permaban) + // just going a few inductive steps, could be more efficient in a full query + const banLevel1 = getLocalBanHistoryInduction(db,platform,userId,group_id,base.timestamp, finalized) + if(!banLevel1) + return [base] + const banLevel2 = getLocalBanHistoryInduction(db,platform,userId,group_id,banLevel1.timestamp, finalized) + if(!banLevel2) + return [base, banLevel1] + + return [base, banLevel1, banLevel2] +} + +const getLocalBanHistoryBase = (db: any, platform: string, userId: string, group_id: string, finalized: boolean) => { + try{ + const stmt = db.prepare(` + SELECT question_id, timestamp_report, timestamp_active as timestamp + FROM reports + WHERE platform = ? AND user_id = ? ${finalized? 'AND finalized = 1': ''} AND active = 1 AND group_id = ? + ORDER BY timestamp_report ASC`) + return stmt.get(platform, userId, group_id); + } catch (err){ + console.log("db error: getLocalBanHistoryBase" + err); + } +} + +const getLocalBanHistoryInduction = (db: any, platform: string, userId: string, group_id: string, timestamp_last: number, finalized: boolean) => { + try{ + const stmt = db.prepare(` + SELECT question_id, timestamp_report, timestamp_active as timestamp + FROM reports + WHERE platform = ? AND user_id = ? ${finalized? 'AND finalized = 1': ''} AND active = 1 AND group_id = ? AND timestamp_msg > ? + ORDER BY timestamp_report ASC`) + return stmt.get(platform, userId, group_id,timestamp_last); + } catch (err){ + console.log("db error: getLocalBanHistoryInduction" + err); + } +} + +const getFederatedBanHistory = (db: any, platform: string, userId: string, federation_id: string, finalized: boolean) => { + const base = getFederatedBanHistoryBase(db, platform, userId, federation_id, finalized) + if (!base) + return []; + + // sqlit3 couldn't do recursive agregate queries + // report ban depth is capped at 3 or 4 levels (1 day, 1 week, permaban) + // just going a few inductive steps, could be more efficient in a full query + const banLevel1 = getFederatedBanHistoryInduction(db,platform,userId,federation_id,base.timestamp, finalized) + if(!banLevel1) + return [base] + const banLevel2 = getFederatedBanHistoryInduction(db,platform,userId,federation_id,banLevel1.timestamp, finalized) + if(!banLevel2) + return [base, banLevel1] + + return [base, banLevel1, banLevel2] + } + +const getFederatedBanHistoryBase = (db: any, platform: string, userId: string, federation_id: string, finalized: boolean) => { + try{ + const stmt = db.prepare(` + SELECT question_id, timestamp_report, timestamp_active as timestamp + FROM reports + WHERE platform = ? AND user_id = ? AND ${finalized? 'AND finalized = 1': ''} AND active = 1 AND group_id IN ( + SELECT group_id + FROM groups + WHERE federation_id = ? AND platform = ? + ) + order by timestamp_report asc;`); + return stmt.get(platform, userId, federation_id, platform); + } catch (err){ + console.log("db error: getFederatedBanHistoryBase" + err); + } +} + +const getFederatedBanHistoryInduction = (db: any, platform: string, userId: string, federation_id: string, timestamp_last: number, finalized: boolean) => { + try{ + const stmt = db.prepare(` + SELECT question_id, timestamp_report, timestamp_active as timestamp + FROM reports + WHERE platform = ? AND user_id = ? ${finalized? 'AND finalized = 1': ''} AND active = 1 AND timestamp_msg > ? AND group_id IN ( + SELECT group_id + FROM groups + WHERE federation_id = ? AND platform = ? + ) + order by timestamp_report asc;`); + return stmt.get(platform, userId,timestamp_last,federation_id,platform); + } catch (err){ + console.log("db error: getFederatedBanHistoryInduction" + err); + } +} + +const getFederatedFollowingBanHistory = (db: any, platform: string, userId: string, group_id: string, federation_id: string, finalized: boolean) => { + const base = getFederatedFollowingBanHistoryBase(db, platform, userId, group_id, federation_id, finalized) + if (!base) + return []; + + // sqlit3 couldn't do recursive agregate queries + // report ban depth is capped at 3 or 4 levels (1 day, 1 week, permaban) + // just going a few inductive steps, could be more efficient in a full query + const banLevel1 = getFederatedFollowingBanHistoryInduction(db,platform,userId,group_id, federation_id,base.timestamp, finalized) + if(!banLevel1) + return [base] + const banLevel2 = getFederatedFollowingBanHistoryInduction(db,platform,userId,group_id,federation_id,banLevel1.timestamp, finalized) + if(!banLevel2) + return [base, banLevel1] + + return [base, banLevel1, banLevel2] + } + +const getFederatedFollowingBanHistoryBase = (db: any, platform: string, userId: string, group_id: string, federation_id: string, finalized: boolean) => { + try{ + const stmt = db.prepare(` + SELECT question_id, timestamp_report, timestamp_active as timestamp + FROM reports + WHERE platform = ? AND user_id = ? ${finalized? 'AND finalized = 1': ''} AND active = 1 AND (group_id = ? OR group_id IN ( + SELECT group_id + FROM groups + WHERE federation_id = ? AND platform = ? + )) + order by timestamp_report asc;`); + return stmt.get(platform, userId, group_id, federation_id, platform); + } catch (err){ + console.log("db error: getFederatedBanHistoryBase" + err); + } +} + +const getFederatedFollowingBanHistoryInduction = (db: any, platform: string, userId: string, group_id: string, federation_id: string, timestamp_last: number, finalized: boolean) => { + try{ + const stmt = db.prepare(` + SELECT question_id, timestamp_report, timestamp_active as timestamp + FROM reports + WHERE platform = ? AND user_id = ? ${finalized? 'AND finalized = 1': ''} AND active = 1 AND timestamp_msg > ? AND (group_id = ? OR group_id IN ( + SELECT group_id + FROM groups + WHERE federation_id = ? AND platform = ? + )) + order by timestamp_report asc;`); + return stmt.get(platform, userId,group_id, timestamp_last,federation_id,platform); + } catch (err){ + console.log("db error: getFederatedBanHistoryInduction" + err); + } +} +/* RECURSIVE ATTEMPT +const getFederatedBanHistory = (db: any, platform: string, userId: string, federationId: string) => { + try{ + const stmt = db.prepare(` + WITH calculatedBanHistory AS ( + SELECT question_id, MIN(timestamp_report) AS timestamp + FROM reports + WHERE user_id = ? AND finalized = 1 AND active = 1 AND group_id IN ( + SELECT group_id + FROM groups + WHERE federation_id = ? AND platform = ? + ) + GROUP BY question_id + + UNION ALL + + SELECT question_id, MIN(timestamp_report) + FROM reports + WHERE user_id = ? AND finalized = 1 AND active = 1 AND timestamp_msg > timestamp AND group_id IN ( + SELECT group_id + FROM groups + WHERE federation_id = ? AND platform = ? + ) + GROUP BY question_id + ) + SELECT * FROM calculatedBanHistory + `); + return stmt.all(userId, federationId, platform,userId, federationId, platform); + } catch (err){ + console.log("db error: getFederatedBanLevel" + err); + } +} +*/ + + const getUsersWithQuestionsNotFinalized = (db: any, platform: string, groupId: string) => { try{ - const stmt = db.prepare( `SELECT DISTINCT user_id, username FROM reports WHERE platform = ? AND group_id = ? AND finalized = 0`); + const stmt = db.prepare( `SELECT DISTINCT user_id, username FROM reports WHERE platform = ? AND group_id = ? AND finalized IS NULL`); return stmt.all(platform, groupId); } catch(err) { console.log("db error: getActiveEvidenceGroupId"); @@ -403,28 +672,6 @@ const setAllowance = ( } } -const setBanHistory = ( - db: any, - platform: string, - groupId: string, - userId: string, - ban_level: number, - timestamp_ban: number, - count_current_level_optimistic_bans: number - ) => { - try{ - const stmt = db.prepare( - `INSERT INTO banHistory (platform, group_id, user_id, ban_level, timestamp_ban, count_current_level_optimistic_bans) - VALUES (?, ?, ?, ?, ?, ?) - ON CONFLICT(platform, group_id, user_id) DO UPDATE SET - ban_level=?, timestamp_ban = ?, count_current_level_optimistic_bans=?;` - ); - const info = stmt.run(platform, groupId, userId, ban_level, timestamp_ban,count_current_level_optimistic_bans,ban_level, timestamp_ban,count_current_level_optimistic_bans); - } catch(e) { - console.log("db error: setBanHistory"+e); - } -} - const getThreadIDWelcome = (db: any, platform: string, groupId: string) => { try{ const stmt = db.prepare('SELECT thread_id_welcome FROM groups WHERE platform = ? AND group_id = ?'); @@ -455,9 +702,9 @@ const getLang = (db:any, platform: string, groupId: string): string => { } } -const getReportMessageTimestampAndActive = (db:any, question_id: string): {timestamp: number, active: number} | undefined => { +const getReportMessageTimestampAndActive = (db:any, question_id: string): {timestamp_report: number, active: number, timestamp_msg: number} | undefined => { try{ - const stmt = db.prepare('SELECT timestamp, active FROM reports WHERE question_id = ?'); + const stmt = db.prepare('SELECT timestamp_msg, active, timestamp_report FROM reports WHERE question_id = ?'); return stmt.get(question_id); } catch(err){ console.log("db error: getReportMessageTimestamp"); @@ -465,6 +712,16 @@ const getReportMessageTimestampAndActive = (db:any, question_id: string): {time } } +const getTimestampFinalized = (db:any, question_id: string): number | undefined => { + try{ + const stmt = db.prepare('SELECT timestamp_finalized FROM reports WHERE question_id = ?'); + return stmt.get(question_id)?.timestamp_finalized; + } catch(err){ + console.log("db error: getTimestampFinalized"); + console.log(err); + } +} + const setRules = (db:any, platform: string, groupId: string, rules: string, timestamp: number) => { try{ const stmt = db.prepare( @@ -490,6 +747,7 @@ const getRule = (db:any, platform: string, groupId: string, timestamp: number): } } + const addReport = ( db: any, questionId: string, @@ -498,7 +756,7 @@ const addReport = ( userId: string, username: string, msgId: string, - msgTimestamp: number, + timestampMsg: number, evidenceIndex: number, msgBackup: string ) => { @@ -511,11 +769,9 @@ const addReport = ( user_id, username, msg_id, - timestamp, + timestamp_msg, + timestamp_report, evidenceIndex, - finalized, - active, - active_timestamp, msgBackup) VALUES ( ?, @@ -523,12 +779,10 @@ const addReport = ( ?, ?, ?, + ?, ?, ?, ?, - 0, - 0, - 0, ?);`); const info = stmt.run( questionId, @@ -537,7 +791,8 @@ const addReport = ( userId, username, msgId, - msgTimestamp, + timestampMsg, + Math.floor(Date.now()/1000), evidenceIndex, msgBackup); } catch(e) { @@ -558,23 +813,34 @@ export { setAllowance, getAllowance, setReport, + setFederation, + getFederatedBanHistoryBase, + getFederatedFollowingBanHistoryBase, + getLocalBanHistoryBase, + followFederation, addReport, getUsersWithQuestionsNotFinalized, getQuestionId, - getConcurrentReports, getActiveEvidenceGroupId, setChannelID, - setBanHistory, - getBanHistory, getReportMessageTimestampAndActive, - getDisputedReportsUserInfo, + getReportsUserInfo, + setAdminReportableMode, + setCaptchaMode, + getTimestampFinalized, getChannelID, - getDisputedReportsInfo, + getActiveReportsInfo, leaveFederation, joinFederation, + getFederatedFollowingBanHistory, + isInFederation, + getLocalBanHistory, + getFederatedBanHistory, + getGroupsInAndFollowingFederation, getFederationGroups, getGreetingMode, eraseThreadID, + getFederationName, setGreetingMode, getRecordCount, setLang, diff --git a/lib/telegram/commands/addEvidence.ts b/lib/telegram/commands/addEvidence.ts index 5727603..d2497c2 100644 --- a/lib/telegram/commands/addEvidence.ts +++ b/lib/telegram/commands/addEvidence.ts @@ -1,7 +1,7 @@ import * as TelegramBot from "node-telegram-bot-api"; import {Wallet} from "@ethersproject/wallet"; import { BigNumber} from "@ethersproject/bignumber"; -import {ipfsPublish, ipfsPublishBuffer} from "../../utils/ipfs-publish-estuary"; +import {ipfsPublish, ipfsPublishBuffer} from "../../utils/ipfs-publish"; import { setAllowance, getAllowance, getActiveEvidenceGroupId , existsQuestionId} from "../../db"; import fetch from 'node-fetch'; import { getQuestionsNotFinalized } from "../../graph"; @@ -105,11 +105,14 @@ ${langJson[lang].addevidence.Message} (${langJson[lang].addevidence.Poll}): \n const uploadTextEvidence = async (lang: string, msg: TelegramBot.Message): Promise => { const enc = new TextEncoder(); const match = msg.text.match(regexpFull); - var remainderMatch = match[1].split(' ') - remainderMatch.shift(); - const reason = remainderMatch.join(' ') - console.log(reason) - const textReason = reason.length > 0? `Evidence Submitted with explanation: ${reason}` : '' + var textReason = '' + if (match){ + var remainderMatch = match[1].split(' ') + remainderMatch.shift(); + const reason = remainderMatch.join(' ') + console.log(reason) + textReason = reason.length > 0? `Evidence Submitted with explanation: ${reason}` : '' + } const author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' ID:'+msg.reply_to_message.from.id ; const fileName = `${langJson[lang].addevidence.Message}.txt`; const chatHistory = `${langJson[lang].addevidence.Chat}: ${msg.chat.title} (${String(msg.chat.id)}) @@ -191,7 +194,7 @@ const callback = async (db: any, settings: groupSettings, bot: any, botID: numbe [ { text: 'DM me for help', - url: `https://t.me/KlerosModeratorBot?start=addevidencehelp${msg.chat.id}` + url: `https://t.me/${process.env.BOT_USERNAME}?start=addevidencehelp${msg.chat.id}` } ] ] @@ -203,7 +206,7 @@ const callback = async (db: any, settings: groupSettings, bot: any, botID: numbe [ { text: 'DM me for help', - url: `https://t.me/KlerosModeratorBot?start=addevidencehelp${msg.chat.id}` + url: `https://t.me/${process.env.BOT_USERNAME}?start=addevidencehelp${msg.chat.id}` } ] ] diff --git a/lib/telegram/commands/fedinfo.ts b/lib/telegram/commands/fedinfo.ts new file mode 100644 index 0000000..e17acc4 --- /dev/null +++ b/lib/telegram/commands/fedinfo.ts @@ -0,0 +1,70 @@ +import * as TelegramBot from "node-telegram-bot-api"; +import { groupSettings } from "../../../types"; +import {setFederation,getFederationName} from "../../db"; +import langJson from "../assets/lang.json"; + +/* + * /joinfed + */ +const regexp = /\/fedinfo\s?(.+)?/ + +const callback = async (db: any, settings: groupSettings, bot: any, botId: string, msg: any, match: string[]) => { + try{ + if (msg.chat.type !== "private"){ + const opts = msg.chat.is_forum? { + message_thread_id: msg.message_thread_id, + parse_mode: 'Markdown', + reply_markup: { + inline_keyboard: [ + [ + { + text: 'Get Help (DM)', + url: `https://t.me/${process.env.BOT_USERNAME}?start=newfed` + } + ] + ] + } + }: { + parse_mode: 'Markdown', + reply_markup: { + inline_keyboard: [ + [ + { + text: 'Get Help (DM)', + url: `https://t.me/${process.env.BOT_USERNAME}?start=newfed` + } + ] + ] + } + } + bot.sendMessage(msg.chat.id, `DM me for to create your federation : )`, opts); + return; + } + const name = getFederationName(db, 'telegram',msg.from.id); + console.log(name) + if (name){ + bot.sendMessage(settings.channelID, `Your federation *${name}* with id \`${msg.from.id}\` already exists.`,msg.chat.is_forum? { + message_thread_id: msg.message_thread_id, + parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); + return + } + if (!match[1]){ + bot.sendMessage(settings.channelID, `Please name your federation eg: \`/newfed My New Federation\``,msg.chat.is_forum? { + message_thread_id: msg.message_thread_id, + parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); + return + } else{ + const name = match[1].substring(0,65) + setFederation(db, 'telegram',name, msg.from.id) + bot.sendMessage(settings.channelID, `Your new federation is called *${match[1].substring(0,65)}* with id ${msg.from.id}. You can add groups to your federation by sending \`/joinfed ${msg.from.id}\` in each group.`,msg.chat.is_forum? { + message_thread_id: msg.message_thread_id, + parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); + } + //joinFederation(db, 'telegram', String(msg.chat.id), String(msg.from.id)) + //bot.sendMessage(msg.chat.id, 'Your group has joined the federation.', msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) + } catch(e){ + console.log(e) + } +} + +export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/getReports.ts b/lib/telegram/commands/getReports.ts index e13a540..5d34027 100644 --- a/lib/telegram/commands/getReports.ts +++ b/lib/telegram/commands/getReports.ts @@ -1,7 +1,7 @@ import * as TelegramBot from "node-telegram-bot-api"; const escape = require('markdown-escape') import langJson from "../assets/lang.json"; -import {getDisputedReportsUserInfo ,getDisputedReportsInfo} from "../../db"; +import {getReportsUserInfo ,getActiveReportsInfo} from "../../db"; import { groupSettings } from "../../../types"; /* * /getaccount @@ -10,9 +10,52 @@ const regexp = /\/getreports/ const callback = async (db: any, settings: groupSettings, bot: any, botid: number, msg: any) => { try{ - if(msg.reply_to_message){ - const reports = getDisputedReportsUserInfo(db, 'telegram', String(msg.chat.id), String(msg.reply_to_message.from.id)); - const fromUsername = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name || `no-username-set`); + if (msg.chat.type !== "private"){ + const opts = msg.chat.is_forum? { + message_thread_id: msg.message_thread_id, + parse_mode: 'Markdown', + reply_markup: { + inline_keyboard: [ + [ + { + text: 'Get Report Info', + url: `https://t.me/${process.env.BOT_USERNAME}?start=getreport${msg.chat.id}${(msg.reply_to_message && !msg.reply_to_message.forum_topic_created)? msg.reply_to_message.from.id: ''}` + } + ] + ] + } + }: { + parse_mode: 'Markdown', + reply_markup: { + inline_keyboard: [ + [ + { + text: 'Get Report Info', + url: `https://t.me/${process.env.BOT_USERNAME}?start=getreport${msg.chat.id}${(msg.reply_to_message && !msg.reply_to_message.forum_topic_created)? msg.reply_to_message.from.id: ''}` + } + ] + ] + } + } + bot.sendMessage(msg.chat.id, `DM me for report info : )`, opts); + return; + } + + let group_id: string; + let user_id: string + if(msg.text.length > 35){ + group_id = msg.text.substring(16,30) + user_id = msg.text.substring(30) + } else if (msg.text.length > 16){ + group_id = msg.text.substring(16,30) + + } else + return; + + if(user_id){ + const reports = getReportsUserInfo(db, 'telegram', group_id, user_id); + const user = await bot.getChatMember(group_id, user_id) + const fromUsername = (user.user.username || user.user.first_name || `no-username-set`); if (reports.length == 0){ bot.sendMessage(msg.chat.id, `${langJson[settings.lang].getReports.noReports} *${escape(fromUsername)}*.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}:{parse_mode: "Markdown"}); return; @@ -20,21 +63,17 @@ const callback = async (db: any, settings: groupSettings, bot: any, botid: numbe var reportMessage: string = `${langJson[settings.lang].getReports.ReportsFor} ${escape(fromUsername)}:\n\n`; reports.forEach( (report) => { console.log(report) - const reportAnswer = report.active? langJson[settings.lang].getReports.broke : langJson[settings.lang].getReports.nobreak; + const reportAnswer = report.answered? (report.active? langJson[settings.lang].getReports.broke : langJson[settings.lang].getReports.nobreak) : 'unanswered'; const MsgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + report.msg_id; - const msgTime = new Date(report.timestamp*1000).toDateString(); - const msgTimehours = new Date(report.timestamp*1000).toUTCString(); + const msgTime = new Date(report.timestamp_msg*1000).toDateString(); + const msgTimehours = new Date(report.timestamp_msg*1000).toUTCString(); const reportState = report.finalized? langJson[settings.lang].getReports.reportFinal : langJson[settings.lang].getReports.reportCurrent; - if (report.active_timestamp === 0) - reportMessage += ` - [${langJson[settings.lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), [${langJson[settings.lang].addevidence.MessageSent}](${MsgLink}) ${msgTime}, ${msgTimehours} ([${langJson[settings.lang].socialConsensus.consensus5}](${report.msgBackup})), ${reportState} ${langJson[settings.lang].answer}, ${reportAnswer}, \`/addevidence ${report.evidenceIndex}\`\n`; - else - reportMessage += ` - [${langJson[settings.lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), [${langJson[settings.lang].addevidence.MessageSent}](${MsgLink}) ${msgTime}, ${msgTimehours} ([${langJson[settings.lang].socialConsensus.consensus5}](${report.msgBackup})), unanswered, \`/addevidence ${report.evidenceIndex}\`\n`; - + reportMessage += ` - [${langJson[settings.lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), [${langJson[settings.lang].addevidence.MessageSent}](${MsgLink}) ${msgTime}, ${msgTimehours} ([${langJson[settings.lang].socialConsensus.consensus5}](${report.msgBackup})), ${reportState} ${langJson[settings.lang].answer}, ${reportAnswer}, \`/addevidence ${report.evidenceIndex}\`\n`; }); bot.sendMessage(msg.chat.id, reportMessage , msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown", disable_web_page_preview: true}:{parse_mode: "Markdown", disable_web_page_preview: true}); return; } else { - const reports = getDisputedReportsInfo(db, 'telegram', String(msg.chat.id)); + const reports = getActiveReportsInfo(db, 'telegram', group_id); if (reports.length == 0){ bot.sendMessage(msg.chat.id, langJson[settings.lang].getReports.noActiveReports + '\n\n' + langJson[settings.lang].getReports.specificUser, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}:{parse_mode: "Markdown"}); return; @@ -44,7 +83,7 @@ const callback = async (db: any, settings: groupSettings, bot: any, botid: numbe await reports.forEach(async (report) => { const reportAnswer = report.active? langJson[settings.lang].getReports.broke : langJson[settings.lang].getReports.nobreak const MsgLink = 'https://t.me/c/' + report.group_id.substring(4) + '/' + report.msg_id; - const msgTime = new Date(report.timestamp*1000).toISOString(); + const msgTime = new Date(report.timestamp_msg*1000).toISOString(); reportMessage += ` - ${report.username} ${langJson[settings.lang].getReports.reportMessage1} [${msgTime.substring(0,msgTime.length-4)}](${MsgLink}) ([${langJson[settings.lang].getReports.reportMessage2}](${report.msgBackup})): [${langJson[settings.lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), ${langJson[settings.lang].getReports.reportMessage4}, ${reportAnswer}\n`; }); reportMessage += '\n\n' diff --git a/lib/telegram/commands/greeting.ts b/lib/telegram/commands/greeting.ts index 60b6a9d..54c966a 100644 --- a/lib/telegram/commands/greeting.ts +++ b/lib/telegram/commands/greeting.ts @@ -3,24 +3,54 @@ import langJson from "../assets/lang.json"; import {groupSettings} from "../../../types"; const NodeCache = require( "node-cache" ); -const myCache = new NodeCache( { stdTTL: 900, checkperiod: 1200 } ); +const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); var myBot; myCache.on("expired",function(key,value){ - myBot.deleteMessage(key, value.msg1); - myBot.deleteMessage(key, value.msg2); + myBot.deleteMessage(value, key); }); const callback = async (bot: any, settings: groupSettings, msg: any) => { myBot = bot try{ - if(msg.chat.is_forum){ - bot.sendMessage(msg.chat.id, `Welcome [${msg.from.first_name}](tg://user?id=${msg.from.id}) ${langJson[settings.lang].greeting2}(${settings.rules}). ${langJson[settings.lang].greeting3}`, {message_thread_id: settings.thread_id_welcome, parse_mode: "Markdown"}); - } else { - const msg1: TelegramBot.Message = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].greeting1}[Kleros Moderate](https://kleros.io/moderate/).`, {parse_mode: "Markdown"}); - const msg2: TelegramBot.Message = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].greeting2}(${settings.rules}). ${langJson[settings.lang].greeting3}`, {parse_mode: "Markdown"}); - myCache.set(msg.chat.id, {"msg1": msg1.message_id, "msg2": msg2.message_id}); + const opts = { + parse_mode: 'Markdown', + disable_web_page_preview: true, + reply_markup: { + inline_keyboard: [ + [ + { + text: 'I agree to follow the rules.', + callback_data: '5|'+String(msg.from.id) + } + ] + ] + } + }; + const optsThread = { + parse_mode: 'Markdown', + message_thread_id: settings.thread_id_welcome, + disable_web_page_preview: true, + reply_markup: { + inline_keyboard: [ + [ + { + text: 'I agree to follow the rules.', + callback_data: '5|'+String(msg.from.id) + } + ] + ] + } + }; + let msg_welcome; + if(settings.captcha){ + const options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false}; + bot.restrictChatMember(msg.chat.id, msg.from.id, options); + msg_welcome = await bot.sendMessage(msg.chat.id, `Hi 👋 Welcome [${msg.from.first_name}](tg://user?id=${msg.from.id}). ${langJson[settings.lang].greeting2}(${settings.rules}).`, msg.chat.is_forum? optsThread: opts); + } else if (settings.greeting_mode){ + msg_welcome = await bot.sendMessage(msg.chat.id, `Hi 👋 Welcome [${msg.from.first_name}](tg://user?id=${msg.from.id}). ${langJson[settings.lang].greeting2}(${settings.rules}).`, msg.chat.is_forum? {message_thread_id: settings.thread_id_welcome,disable_web_page_preview: true}: {disable_web_page_preview: true}); } + myCache.set(msg_welcome.message_id, msg.chat.id) } catch(e){ console.log(e) } diff --git a/lib/telegram/commands/help.ts b/lib/telegram/commands/help.ts index 6987a5d..53df8d1 100644 --- a/lib/telegram/commands/help.ts +++ b/lib/telegram/commands/help.ts @@ -13,6 +13,8 @@ const helpgnosis = (db: any, settings: groupSettings, bot: any, botId: number, m Susie uses [xDAI](https://docs.gnosischain.com/about/tokens/xdai), a stable coin, on [Gnosis Chain](https://www.gnosis.io/). Don't know what that means? It means Susie uses a cheap and fast decentralized tool to coordinate moderation fairly and transparently. +What's crypto? I heard about that on the news, I don't want anything to do with crypto. No problem, you can ask for help in the @KlerosModerateGuildOfJustice for help from freelance moderators. + Don't have any xDAI on Gnosis Chain? No problem, there's a (cheap, fast) [bridge](https://bridge.connext.network/?receivingChainId=100&receivingAssetId=0x0000000000000000000000000000000000000000) for that. Don't have any cryptocurrency? No problem, there's a convinient [fiat on-ramp](https://www.mtpelerin.com/buy-xdai) (credit card or bank transfer) to buy DAI on Gnosis Chain. @@ -60,7 +62,7 @@ const callback = (db: any, settings: groupSettings, bot: any, botId: number, msg [ { text: 'Get Help (DM)', - url: `tg://user?id=${botId}&start=help` + url: `https://t.me/${process.env.BOT_USERNAME}?start=help` } ] ] @@ -72,8 +74,7 @@ const callback = (db: any, settings: groupSettings, bot: any, botId: number, msg [ { text: 'Get Help (DM)', - url: `https://t.me/KlerosModeratorBot?start=help` - //url: `tg://user?id=${botId}&start=help` + url: `https://t.me/${process.env.BOT_USERNAME}?start=help` } ] ] @@ -280,6 +281,8 @@ Susie uses [xDAI](https://docs.gnosischain.com/about/tokens/xdai), a stable coin Don't have any xDAI on Gnosis Chain? No problem, there's a (cheap, fast) [bridge](https://bridge.connext.network/?receivingChainId=100&receivingAssetId=0x0000000000000000000000000000000000000000) for that. +What's crypto? I heard about that on the news, I don't want anything to do with crypto. No problem, you can ask for help in the @KlerosModerateGuildOfJustice for help from freelance moderators. + Don't have any cryptocurrency? No problem, there's a convinient [fiat on-ramp](https://www.mtpelerin.com/buy-xdai) (credit card or bank transfer) to buy DAI on Gnosis Chain. Need help adding the Gnosis Chain network to your wallet? Don't worry, there's a [guide](https://docs.gnosischain.com/tools/wallets/metamask#2-configure) for that. diff --git a/lib/telegram/commands/joinfed.ts b/lib/telegram/commands/joinfed.ts index 9494e96..0ccd602 100644 --- a/lib/telegram/commands/joinfed.ts +++ b/lib/telegram/commands/joinfed.ts @@ -1,19 +1,32 @@ import * as TelegramBot from "node-telegram-bot-api"; import { groupSettings } from "../../../types"; -import {joinFederation} from "../../db"; +import {joinFederation,followFederation,getFederationName} from "../../db"; import langJson from "../assets/lang.json"; /* * /joinfed */ -const regexp = /\/joinfed/ +const regexp = /\/joinfed\s?(.+)?/ const callback = async (db: any, settings: groupSettings, bot: any, botId: string, msg: any, match: string[]) => { try{ - joinFederation(db, 'telegram', String(msg.chat.id), String(msg.from.id)) - bot.sendMessage(msg.chat.id, 'Your group has joined the federation.', msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) + if (!match[1]){ + bot.sendMessage(settings.channelID, `Please specify a federation eg. \`/joinfed \`.`,msg.chat.is_forum? { + message_thread_id: msg.message_thread_id, + parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); + } else{ + const name = getFederationName(db, 'telegram',match[1].substring(0,65)) + if (!name) + bot.sendMessage(settings.channelID, `Federation not found. The federation id of any group can be found by sending \`/fedinfo\` in a group.`,msg.chat.is_forum? { + message_thread_id: msg.message_thread_id, + parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); + if (msg.from.id === match[1]) + joinFederation(db, 'telegram', String(msg.chat.id), match[1].substring(0,65)) + else + followFederation(db, 'telegram', String(msg.chat.id), match[1].substring(0,65)) + } } catch(e){ - console.log(e) + console.log(e) } } diff --git a/lib/telegram/commands/newfed.ts b/lib/telegram/commands/newfed.ts new file mode 100644 index 0000000..43b53e5 --- /dev/null +++ b/lib/telegram/commands/newfed.ts @@ -0,0 +1,70 @@ +import * as TelegramBot from "node-telegram-bot-api"; +import { groupSettings } from "../../../types"; +import {setFederation,getFederationName} from "../../db"; +import langJson from "../assets/lang.json"; + +/* + * /joinfed + */ +const regexp = /\/newfed\s?(.+)?/ + +const callback = async (db: any, settings: groupSettings, bot: any, botId: string, msg: any, match: string[]) => { + try{ + if (msg.chat.type !== "private"){ + const opts = msg.chat.is_forum? { + message_thread_id: msg.message_thread_id, + parse_mode: 'Markdown', + reply_markup: { + inline_keyboard: [ + [ + { + text: 'Get Help (DM)', + url: `https://t.me/${process.env.BOT_USERNAME}?start=newfed` + } + ] + ] + } + }: { + parse_mode: 'Markdown', + reply_markup: { + inline_keyboard: [ + [ + { + text: 'Get Help (DM)', + url: `https://t.me/${process.env.BOT_USERNAME}?start=newfed` + } + ] + ] + } + } + bot.sendMessage(msg.chat.id, `DM me for to create your federation : )`, opts); + return; + } + const name = getFederationName(db, 'telegram',msg.from.id); + console.log(name) + if (name){ + bot.sendMessage(settings.channelID, `Your federation *${name}* with id \`${msg.from.id}\` already exists.`,msg.chat.is_forum? { + message_thread_id: msg.message_thread_id, + parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); + return + } + if (!match[1]){ + bot.sendMessage(settings.channelID, `Please name your federation eg: \`/newfed My New Federation\``,msg.chat.is_forum? { + message_thread_id: msg.message_thread_id, + parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); + return + } else{ + const name = match[1].substring(0,65) + setFederation(db, 'telegram',name, msg.from.id) + bot.sendMessage(settings.channelID, `Your new federation is called *${match[1].substring(0,65)}* with id ${msg.from.id}. You can add groups to your federation by sending \`/joinfed ${msg.from.id}\` in each group.`,msg.chat.is_forum? { + message_thread_id: msg.message_thread_id, + parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); + } + //joinFederation(db, 'telegram', String(msg.chat.id), String(msg.from.id)) + //bot.sendMessage(msg.chat.id, 'Your group has joined the federation.', msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) + } catch(e){ + console.log(e) + } +} + +export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/report.ts b/lib/telegram/commands/report.ts index 3f8e70f..617e397 100644 --- a/lib/telegram/commands/report.ts +++ b/lib/telegram/commands/report.ts @@ -1,5 +1,5 @@ import * as TelegramBot from "node-telegram-bot-api"; -import {setInviteURL, getInviteURL, getRule,getAllowance, setAllowance, addReport, getConcurrentReports, getRecordCount, getQuestionId} from "../../db"; +import {setInviteURL, getInviteURL, getRule,getAllowance, setAllowance, addReport, getRecordCount, getQuestionId} from "../../db"; import { groupSettings } from "../../../types"; import {upload} from "./addEvidence" import {reportUser} from "../../bot-core"; @@ -9,7 +9,6 @@ import langJson from "../assets/lang.json"; * /report */ const regexp = /\/report\s?(.+)?/ -let evidenceIndexMap : Map = new Map(); // cacheIndex => groupID,reported message id => [pending report message id] const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 900, checkperiod: 1200 } ); @@ -21,6 +20,10 @@ const callback = async (db:any, settings: groupSettings, bot: any, botId: number return; } + if (msg.reply_to_message.date < Date.now()/1000-86400*7){ + bot.sendMessage(msg.chat.id, `Live and let live. This message is more than one week old. The future is asynchronous, but we believe moderation should not be punitive. Next time try to make the report sooner.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + } + // WHO WATCHES THE WATCHMEN?? // can't ban bots if (msg.reply_to_message.from.is_bot){ @@ -43,7 +46,7 @@ const callback = async (db:any, settings: groupSettings, bot: any, botId: number } const reportedQuestionId = getQuestionId(db, 'telegram', String(msg.chat.id), reportedUserID, String(msg.reply_to_message.message_id)); if (reportedQuestionId){ - bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.reported}(https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${reportedQuestionId})`, {parse_mode: 'Markdown'}); + bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.reported}(https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${reportedQuestionId})`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); return; } @@ -76,6 +79,7 @@ const callback = async (db:any, settings: groupSettings, bot: any, botId: number const opts = { parse_mode: 'Markdown', reply_to_message_id: msg.reply_to_message.message_id, + disable_web_page_preview: true, reply_markup: { inline_keyboard: [ [ @@ -91,6 +95,7 @@ const callback = async (db:any, settings: groupSettings, bot: any, botId: number parse_mode: 'Markdown', reply_to_message_id: msg.reply_to_message.message_id, message_thread_id: msg.message_thread_id, + disable_web_page_preview: true, reply_markup: { inline_keyboard: [ [ @@ -102,9 +107,9 @@ const callback = async (db:any, settings: groupSettings, bot: any, botId: number ] } }; - const msgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + msg.reply_to_message.message_id; + const msgLink = `https://t.me/c/${String(msg.chat.id).substring(4)}/${msg.chat.is_forum? `${msg.message_thread_id}/`:''}${msg.reply_to_message.message_id}`; const reportRequestMsg: TelegramBot.Message = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].socialConsensus.consensus2} [${fromUsername}](tg://user?id=${reportedUserID}) ${langJson[settings.lang].socialConsensus.consensus3}(${rules}) ${langJson[settings.lang].socialConsensus.consensus4}(${msgLink}) ([${langJson[settings.lang].socialConsensus.consensus5}](${msgBackup}))?`, msg.chat.is_forum? optsThread: opts); - myCache.set([msg.chat.id, msg.reply_to_message.message_id].toString(),reportRequestMsg.message_id) ; + myCache.set([msg.chat.id, msg.reply_to_message.message_id].toString(),`${msg.chat.is_forum? `${msg.message_thread_id}/`:''}${msg.reply_to_message.message_id}`) ; return; } catch(e){ console.log(e) @@ -122,7 +127,7 @@ const reportMsg = async (settings: groupSettings, db: any, bot: any, msg: any, f myCache.set(msg.chat.id, inviteURL) } - const msgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + msgId; + const msgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + `/${msg.chat.is_forum? `${msg.message_thread_id}/`:''}${msg.reply_to_message.message_id}`; const cachedEvidenceIndex = myCache.get("evidence"+msg.chat.id); const evidenceIndex = cachedEvidenceIndex? cachedEvidenceIndex+1:getRecordCount(db, 'telegram', String(msg.chat.id))+1 @@ -143,9 +148,9 @@ const reportMsg = async (settings: groupSettings, db: any, bot: any, msg: any, f msgBackup, reportedBy); - addReport(db, questionId, 'telegram', String(msg.chat.id), reportedUserID, fromUsername , msgId, msg.reply_to_message.date,evidenceIndex, msgBackup); + addReport(db, questionId, 'telegram', String(msg.chat.id), reportedUserID, fromUsername , (msg.chat.is_forum? `${msg.message_thread_id}/`:'')+String(msg.reply_to_message.message_id), msg.reply_to_message.date,evidenceIndex, msgBackup); - bot.sendMessage(settings.channelID, `[${fromUsername}](tg://user?id=${reportedUserID})'s conduct due to this [message](${msgLink}) ([backup](${msgBackup})) is reported for breaking the [rules](${rules}).\n\nDid *${fromUsername}* break the rules? The [question](${appealUrl}) can be answered with a minimum bond of 5 DAI. Need help getting DAI on Gnosis Chain for your answer? [DM](https://t.me/KlerosModeratorBot?start=helpgnosis) me for help : )\n\nTo save a record, reply to messages you want saved with \`/addevidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); + bot.sendMessage(settings.channelID, `[${fromUsername}](tg://user?id=${reportedUserID})'s conduct due to this [message](${msgLink}) ([backup](${msgBackup})) is reported for breaking the [rules](${rules}).\n\nDid *${fromUsername}* break the rules? The [question](${appealUrl}) can be answered with a minimum bond of 5 DAI. Need assistance answering the question? [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpgnosis) me for help : )\n\nTo save a record, reply to messages you want saved with \`/addevidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); return questionId; } catch (e) { console.log(e); diff --git a/lib/telegram/commands/setChannel.ts b/lib/telegram/commands/setChannel.ts index f91be97..762802b 100644 --- a/lib/telegram/commands/setChannel.ts +++ b/lib/telegram/commands/setChannel.ts @@ -14,7 +14,7 @@ const callback = async (db: any, settings: groupSettings, bot: TelegramBot, botI try { const newmatch = msg.text.match(regexpFull); if (!newmatch || newmatch.length < 2){ - bot.sendMessage(msg.chat.id, `/setchannel must be followed by a channel id. [DM](https://t.me/KlerosModeratorBot?start=helpnotifications) me if you need more help : )`, {parse_mode: "Markdown"}); + bot.sendMessage(msg.chat.id, `/setchannel must be followed by a channel id. [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpnotifications) me if you need more help : )`, {parse_mode: "Markdown"}); return; } try{ diff --git a/lib/telegram/commands/start.ts b/lib/telegram/commands/start.ts index b1d1d13..64b8396 100644 --- a/lib/telegram/commands/start.ts +++ b/lib/telegram/commands/start.ts @@ -19,7 +19,7 @@ const callback = async (db: any, settings: groupSettings, bot: any, botID: strin [ { text: 'Add me to your group!', - url: `https://t.me/KlerosModeratorBot?startgroup=botstart` + url: `https://t.me/${process.env.BOT_USERNAME}?startgroup=botstart` } ] ] @@ -40,17 +40,18 @@ Join my news channel @KlerosModerateNews to get information on all the latest up } if (msg.chat.is_forum){ if(!botUser.can_manage_topics){ - bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {message_thread_id: msg.message_thread_id, caption: "Must have can manage topics"}); + bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {message_thread_id: msg.message_thread_id, caption: "Susie needs permissions to manage topics to effectively moderate your community.\n\nThen try to /start community moderation again."}); return; } const thread_ids = getThreadIDNotifications(db, 'telegram', String(msg.chat.id)); if (thread_ids){ bot.sendMessage(msg.chat.id, "Already started.", {message_thread_id: msg.message_thread_id}); } - await topicMode(db,bot,settings,String(msg.chat.id)); + console.log(msg); + await topicMode(db,bot,settings,msg.chat); } setRules(db, 'telegram', String(msg.chat.id), langJson[settings.lang].defaultRules, Math.floor(Date.now()/1000)); - bot.sendMessage(msg.chat.id, `Hi! My community moderation tools are at your service. [DM](https://t.me/KlerosModeratorBot?start=help) me to find out more about how to use me to my full potential : ) + bot.sendMessage(msg.chat.id, `Hi! My community moderation tools are at your service. [DM](https://t.me/${process.env.BOT_USERNAME}?start=help) me to find out more about how to use me to my full potential : ) - Use /setrules to change the default [rules](${langJson[settings.lang].defaultRules}). - User reports are made by replying to a message with /report @@ -69,17 +70,16 @@ Join my news channel @KlerosModerateNews to get information on all the latest up } } -const topicMode = async (db:any, bot: any, settings: groupSettings, chat_id: string): Promise<[string,string]> => { +const topicMode = async (db:any, bot: any, settings: groupSettings, chat: TelegramBot.Chat): Promise<[string,string]> => { // tg bugging, won't display icon_color if set - const topicRules = await bot.createForumTopic(chat_id, 'Rules', {icon_custom_emoji_id: '4929691942553387009'}); - const topicModeration = await bot.createForumTopic(chat_id, 'Moderation', {icon_custom_emoji_id: '4929336692923432961'}); + const topicRules = await bot.createForumTopic(chat.id, 'Rules', {icon_custom_emoji_id: '4929691942553387009'}); + const topicModeration = await bot.createForumTopic(chat.id, 'Moderation Notifications', {icon_custom_emoji_id: '4929336692923432961'}); - bot.sendMessage(settings.channelID, `Please refer to the moderation topic for notifications, and the rules topic for rules. `); - bot.sendMessage(chat_id, `${langJson[settings.lang].defaultRulesMsg1alt}. ${langJson[settings.lang].defaultRulesMsg2}.`, {parse_mode: "Markdown", message_thread_id: topicRules.message_thread_id}); - //bot.sendMessage(chat_id, `${langJson[settings.lang].greeting2}(${settings.rules}). ${langJson[settings.lang].greeting3}`, {parse_mode: "Markdown", message_thread_id: topicRules.message_thread_id}); - bot.sendMessage(chat_id, `${langJson[settings.lang].greeting1}[Kleros Moderate](https://kleros.io/moderate/).`, {parse_mode: "Markdown", message_thread_id: topicModeration.message_thread_id}); - bot.closeForumTopic(chat_id, topicRules.message_thread_id) - setThreadID(db,'telegram',chat_id,String(topicRules.message_thread_id), String(topicModeration.message_thread_id)) + bot.sendMessage(chat.id, `Please follow the community [rules](${settings.rules}). Misbehavior can be reported with /report.`, {parse_mode: "Markdown", message_thread_id: topicRules.message_thread_id}); + //bot.sendMessage(chat_id, `${langJson[settings.lang].greeting2}(${settings.rules}). ${langJson[settings.lang].greeting3}`, {parse_mode: "Markdown", message_thread_id: topicRules.message_thread_id}); + bot.sendMessage(chat.id, `${langJson[settings.lang].greeting1}[Kleros Moderate](https://kleros.io/moderate/).`, {parse_mode: "Markdown", message_thread_id: topicModeration.message_thread_id}); + bot.closeForumTopic(chat.id, topicRules.message_thread_id) + setThreadID(db,'telegram',String(chat.id),String(topicRules.message_thread_id), String(topicModeration.message_thread_id)) return [topicRules.message_thread_id, topicModeration.message_thread_id] } diff --git a/lib/telegram/commands/toggleCaptcha.ts b/lib/telegram/commands/toggleCaptcha.ts new file mode 100644 index 0000000..a8a11e0 --- /dev/null +++ b/lib/telegram/commands/toggleCaptcha.ts @@ -0,0 +1,27 @@ +import * as TelegramBot from "node-telegram-bot-api"; +import {setCaptchaMode, setGreetingMode} from "../../db"; +import * as toggleWelcome from "../../../lib/telegram/commands/toggleWelcome"; +import langJson from "../assets/lang.json"; +import {groupSettings} from "../../../types"; + +/* + * /welcome + */ +const regexp = /\/captcha/ + +const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { + try{ + if (msg.chat.is_forum && !settings.thread_id_welcome){ + toggleWelcome.createWelcomeThread(db,settings,bot,msg) + } + setCaptchaMode(db, 'telegram', String(msg.chat.id),settings.captcha? 0: 1) + // if toggling on captcha, turn on greetings + if (!settings.captcha) + setGreetingMode(db, 'telegram', String(msg.chat.id),1) + bot.sendMessage(msg.chat.id, settings.captcha? "Captcha is off." : "Captcha is on.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + } catch(e){ + console.log(e) + } +} + +export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/toggleWelcome.ts b/lib/telegram/commands/toggleWelcome.ts index 2d41eed..4f160cf 100644 --- a/lib/telegram/commands/toggleWelcome.ts +++ b/lib/telegram/commands/toggleWelcome.ts @@ -10,11 +10,8 @@ const regexp = /\/welcome/ const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { try{ - if (msg.chat.is_forum){ - const topicWelcome = await bot.createForumTopic(msg.chat.id, 'Welcome', {icon_custom_emoji_id: '4929292553544531969'}); - const msg1: TelegramBot.Message = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].greeting1}[Kleros Moderate](https://kleros.io/moderate/).`, {parse_mode: "Markdown", message_thread_id: topicWelcome.message_thread_id}); - bot.pinChatMessage(msg.chat.id, msg1.message_id, {message_thread_id: topicWelcome.message_thread_id}) - setThreadIDWelcome(db, 'telegram', String(msg.chat.id), String(topicWelcome.message_thread_id)) + if (msg.chat.is_forum && !settings.thread_id_welcome){ + await createWelcomeThread(db, settings,bot,msg) } setGreetingMode(db, 'telegram', String(msg.chat.id),settings.greeting_mode? 0: 1) bot.sendMessage(msg.chat.id, settings.greeting_mode? "Welcome messages are off." : "Welcome messages are on.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); @@ -23,4 +20,11 @@ const callback = async (db: any, settings: groupSettings, bot: any, botId: numbe } } -export {regexp, callback}; \ No newline at end of file +const createWelcomeThread = async (db: any, settings: groupSettings, bot: any, msg: any) => { + const topicWelcome = await bot.createForumTopic(msg.chat.id, 'Welcome', {icon_custom_emoji_id: '4929292553544531969'}); + const msg1: TelegramBot.Message = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].greeting1}[Kleros Moderate](https://kleros.io/moderate/).\n\nPlease treat this group with the same respect you would a public park. We, too, are a shared community resource — a place to share..`, {parse_mode: "Markdown", message_thread_id: topicWelcome.message_thread_id}); + bot.pinChatMessage(msg.chat.id, msg1.message_id, {message_thread_id: topicWelcome.message_thread_id}) + setThreadIDWelcome(db, 'telegram', String(msg.chat.id), String(topicWelcome.message_thread_id)) +} + +export {regexp, callback, createWelcomeThread}; \ No newline at end of file diff --git a/lib/telegram/commands/welcome.ts b/lib/telegram/commands/welcome.ts index 34b696a..8d50802 100644 --- a/lib/telegram/commands/welcome.ts +++ b/lib/telegram/commands/welcome.ts @@ -1,6 +1,6 @@ import * as TelegramBot from "node-telegram-bot-api"; import langJson from "../assets/lang.json"; -import { groupSettings } from "./types"; +import {groupSettings} from "../../../types"; /* * Welcome Message diff --git a/lib/telegram/index.ts b/lib/telegram/index.ts index 5f6b4cf..24a4382 100644 --- a/lib/telegram/index.ts +++ b/lib/telegram/index.ts @@ -8,10 +8,12 @@ import * as report from "../../lib/telegram/commands/report"; import * as welcome from "../../lib/telegram/commands/welcome"; import * as toggleWelcome from "../../lib/telegram/commands/toggleWelcome"; import * as greeting from "../../lib/telegram/commands/greeting"; +import * as toggleCaptcha from "../../lib/telegram/commands/toggleCaptcha"; import * as help from "../../lib/telegram/commands/help"; import * as socialConsensus from "../../lib/telegram/commands/socialConsensus"; import * as addEvidence from "../../lib/telegram/commands/addEvidence"; import * as leaveFed from "../../lib/telegram/commands/leavefed"; +import * as newFed from "../../lib/telegram/commands/newfed"; import * as joinFed from "../../lib/telegram/commands/joinfed"; import * as start from "../../lib/telegram/commands/start"; import * as setLanguage from "../../lib/telegram/commands/setLanguage"; @@ -20,7 +22,7 @@ import * as getChannel from "../../lib/telegram/commands/getChannel"; import * as getReports from "../../lib/telegram/commands/getReports"; import langJson from "./assets/lang.json"; import {groupSettings, groupSettingsUnderspecified} from "../../types"; -import {openDb, getGroupSettings, getRule, getDisputedReportsUserInfo, eraseThreadID} from "../db"; +import {openDb, getGroupSettings, getRule, getReportsUserInfo,getFederatedBanHistoryBase, getFederatedFollowingBanHistoryBase, getLocalBanHistoryBase, eraseThreadID} from "../db"; const Web3 = require('web3') const _batchedSend = require('web3-batched-send') @@ -36,9 +38,13 @@ const batchedSend = _batchedSend( rules: langJson['en'].defaultRules, channelID: '', greeting_mode: false, + captcha: false, + admin_reportable: false, thread_id_rules: '', thread_id_welcome: '', - thread_id_notifications: '' + thread_id_notifications: '', + federation_id: '', + federation_id_following: '' } const ModeratorBot = require('node-telegram-bot-api'); const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: true, testEnvironment: true}); @@ -86,9 +92,20 @@ bot.on("my_chat_member", async function(myChatMember: any) { bot.on("new_chat_members", async function (chatMemberUpdated: TelegramBot.ChatMemberUpdated) { if(!hasStarted(chatMemberUpdated.chat.id)||throttled(chatMemberUpdated.from.id)||chatMemberUpdated.chat.type !== "supergroup") - return; + return; const settings = validate(chatMemberUpdated.chat); - if (settings.greeting_mode) + let calculateHistory = [] + if (settings.federation_id) + calculateHistory = getFederatedBanHistoryBase(db, 'telegram', String(chatMemberUpdated.from.id),String(chatMemberUpdated.chat.id),false) + else if (settings.federation_id_following) + calculateHistory = getFederatedFollowingBanHistoryBase(db, 'telegram', String(chatMemberUpdated.from.id),String(chatMemberUpdated.chat.id),settings.federation_id_following,false) + else + calculateHistory = getLocalBanHistoryBase(db, 'telegram', String(chatMemberUpdated.from.id),String(chatMemberUpdated.chat.id),false) + + if (calculateHistory) + return + + if(settings.captcha || settings.greeting_mode) greeting.callback(bot, settings, chatMemberUpdated); }); @@ -113,12 +130,14 @@ bot.on('callback_query', async function onCallbackQuery(callbackQuery: TelegramB } else if (Number(calldata[0]) === 3){ // report confirmations help.respond(settings, bot, calldata[1], callbackQuery); } else if (Number(calldata[0]) === 4){ - const reports = getDisputedReportsUserInfo(db, 'telegram', calldata[1], calldata[2]); + const reports = getReportsUserInfo(db, 'telegram', calldata[1], calldata[2]); var reportMessage: string = `To add evidence, reply to the message you want saved in the original chat with the evidence index.\n\n` reports.forEach( (report) => { const MsgLink = 'https://t.me/c/' + calldata[1].substring(4) + '/' + report.msg_id; - reportMessage += `- [Message](${MsgLink}) ([${langJson[settings.lang].socialConsensus.consensus5}](${report.msgBackup})) [${langJson[settings.lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), \`/addevidence ${report.evidenceIndex}\` \n`; + reportMessage += `- [Message](${MsgLink}) ([${langJson[settings.lang].socialConsensus.consensus5}](${report.msgBackup})) [${langJson[settings.lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), \`/addevidence ${report.evidenceIndex}\` \n`; }); + + reportMessage +='\n eg. /addevidence 1 This message breaks the rules because xyz.' const optsResponse = { chat_id: callbackQuery.message.chat.id, message_id: callbackQuery.message.message_id, @@ -131,6 +150,12 @@ bot.on('callback_query', async function onCallbackQuery(callbackQuery: TelegramB } catch (e){ console.log(e) } + } else if (Number(calldata[0]) === 5){ + if (callbackQuery.from.id !== Number(calldata[1])) + return; + const options = {can_send_messages: true, can_send_media_messages: true, can_send_polls: true, can_send_other_messages: true, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false}; + bot.restrictChatMember(callbackQuery.message.chat.id, callbackQuery.from.id, options); + bot.deleteMessage(callbackQuery.message.chat.id, callbackQuery.message.message_id) } }); @@ -141,7 +166,9 @@ const commands: {regexp: RegExp, callback: any}[] = [ report, toggleWelcome, start, + toggleCaptcha, help, + newFed, getChannel, leaveFed, joinFed, @@ -173,6 +200,12 @@ commands.forEach((command) => { } else if (msg.text.substring(0,22) === '/start addevidencehelp'){ addEvidenceHelp.callback(db, groupSettings, bot, botId, msg); return + } else if (msg.text.substring(0,16) === '/start getreport'){ + getReports.callback(db, groupSettings, bot, botId, msg); + return + } else if (msg.text === '/start newfed' || msg.text.substring(0,7) === '/newfed'){ + newFed.callback(db, groupSettings, bot, String(botId), msg, match); + return } else if (msg.text !== '/start' && msg.text != '/help' && msg.text !== '/start botstart') return } else if(msg.chat.type !== "supergroup" && !(msg.chat.type === "group" && msg.text === '/help')) @@ -220,7 +253,7 @@ commands.forEach((command) => { // todo success bool return val, to not always delete settings command.callback(db, groupSettings, bot, botId, msg, match,batchedSend); - if (command === setLanguage || command === setRulesCommand || command === setChannel || command === toggleWelcome) + if (command === setLanguage || command === setRulesCommand || command === setChannel || command === toggleWelcome || command === toggleCaptcha) myCache.del(msg.chat.id) if (command === start) myCache.del("started"+msg.chat.id) @@ -254,7 +287,9 @@ const hasStarted = (chatid: number): boolean=> { const validate = (chat: any): groupSettings=> { if (!hasStarted(chat.id)){ - return defaultSettings; + let settings = defaultSettings; + settings.channelID = String(chat.id) + return settings; } var groupSettings : groupSettingsUnderspecified = myCache.get(chat.id) if (!groupSettings){ @@ -268,28 +303,39 @@ const validate = (chat: any): groupSettings=> { rules: groupSettings?.rules ?? defaultSettings.rules, channelID: groupSettings?.channelID ?? String(chat.id), greeting_mode: groupSettings?.greeting_mode ?? defaultSettings.greeting_mode, + admin_reportable: groupSettings?.admin_reportable ?? defaultSettings.admin_reportable, + captcha: groupSettings?.captcha ?? defaultSettings.captcha, thread_id_rules: groupSettings?.thread_id_rules ?? defaultSettings.thread_id_rules, thread_id_welcome: groupSettings?.thread_id_welcome ?? defaultSettings.thread_id_rules, - thread_id_notifications: groupSettings?.thread_id_notifications ?? defaultSettings.thread_id_notifications + thread_id_notifications: groupSettings?.thread_id_notifications ?? defaultSettings.thread_id_notifications, + federation_id: groupSettings?.federation_id ?? defaultSettings.federation_id, + federation_id_following: groupSettings?.federation_id_following ?? defaultSettings.federation_id_following } + checkMigration(fullSettings, chat) + console.log(fullSettings); return fullSettings } -/* + const checkMigration = async (groupSettings: groupSettings, chat: any): Promise => { - await bot.sendMessage(chat.id, "Started topic mode", {messsage_thread_id: groupSettings.thread_id_notifications}) if (chat.is_forum && !groupSettings.thread_id_notifications){ // turn topics on try{ - const threads = await start.topicMode(db, bot, groupSettings, String(chat.id)); + const threads = await start.topicMode(db, bot, groupSettings, chat); + bot.sendMessage(chat.id, "Started topic mode", {messsage_thread_id: groupSettings.thread_id_notifications}) groupSettings.thread_id_rules = threads[0] groupSettings.thread_id_notifications = threads[1] groupSettings.channelID = String(chat.id) myCache.set(chat.id, groupSettings) } catch(e){ + try{ + bot.sendMessage(chat.id, "Susie cannot manage groups in topic mode with out permission to manage topics. Please ask an admin to enable this permission to allow Susie to continue help moderating your community.", {messsage_thread_id: groupSettings.thread_id_notifications}) + } catch(e){ + console.log(e) + } console.log(e) } } return groupSettings -}*/ +} console.log('Telegram bot ready...'); \ No newline at end of file diff --git a/package.json b/package.json index e0fec60..d155ac0 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "node-cache": "^5.1.2", "node-fetch": "2", "node-telegram-bot-api": "^0.60.0", + "p-queue": "^6.6.2", "pm2": "^5.2.0", "sqlite": "^4.0.23", "sqlite3": "^5.0.2", diff --git a/types.d.ts b/types.d.ts index 2776c07..4235c0d 100644 --- a/types.d.ts +++ b/types.d.ts @@ -9,6 +9,10 @@ interface groupSettings { thread_id_notifications: string; thread_id_welcome: string; greeting_mode: boolean; + admin_reportable: boolean; + captcha: boolean; + federation_id: string; + federation_id_following: string; } interface groupSettingsUnderspecified { @@ -19,4 +23,8 @@ interface groupSettings { thread_id_notifications: string | undefined; thread_id_welcome: string | undefined; greeting_mode: boolean | undefined; + captcha: boolean | undefined; + admin_reportable: boolean; + federation_id: string | undefined; + federation_id_following: string; } \ No newline at end of file From cdc5d3dd6c2a6ab93d7b667f2a8c0656d9f24e00 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Tue, 13 Dec 2022 23:01:17 -0700 Subject: [PATCH 010/111] feat: big update, captcha, report admin option --- lib/cron.ts | 82 ++++++--- lib/db.ts | 2 +- lib/graph.ts | 27 ++- lib/telegram/commands/addEvidence.ts | 20 ++- lib/telegram/commands/captcha.ts | 55 ++++++ lib/telegram/commands/fedinfo.ts | 2 +- lib/telegram/commands/getChannel.ts | 21 ++- lib/telegram/commands/getLeaderboard.ts | 52 ++++++ lib/telegram/commands/getReports.ts | 13 +- lib/telegram/commands/getRules.ts | 12 +- lib/telegram/commands/help.ts | 39 +++-- lib/telegram/commands/joinfed.ts | 8 +- lib/telegram/commands/newfed.ts | 15 +- lib/telegram/commands/report.ts | 54 ++++-- lib/telegram/commands/setChannel.ts | 8 +- lib/telegram/commands/setLanguage.ts | 8 +- lib/telegram/commands/start.ts | 15 +- .../commands/toggleAdminReportable.ts | 20 +++ lib/telegram/index.ts | 22 ++- subgraph/schema.graphql | 30 +++- .../Realitio_v2_1_ArbitratorWithAppeals.ts | 44 ++++- subgraph/src/reality-ethv-30.ts | 161 +++++++++++------- subgraph/subgraph.yaml | 8 +- 23 files changed, 550 insertions(+), 168 deletions(-) create mode 100644 lib/telegram/commands/captcha.ts create mode 100644 lib/telegram/commands/getLeaderboard.ts create mode 100644 lib/telegram/commands/toggleAdminReportable.ts diff --git a/lib/cron.ts b/lib/cron.ts index 8a3ae8a..c467a70 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -36,9 +36,12 @@ const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCo last_timestamp: currentTime, last_block: currentBlock } - // hardcode values for tests - //history.last_timestamp = 1670802755 - //history.last_block = 25402583 + + console.log(history.last_timestamp) + console.log(history.last_block) + // hardcode values for tests + history.last_timestamp = 1670992400 + history.last_block = 8131483 const graphSyncingPeriod = 300; const timestampNew = currentTime const timestampLastUpdated = history.last_timestamp @@ -64,7 +67,7 @@ const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCo process.env.MODERATE_SUBGRAPH, queryModeration ); - console.log(JSON.stringify(moderationActions)) + //console.log(JSON.stringify(moderationActions)) for (const data of moderationActions.disputesFinal) { const settings = validate(data.moderationInfo.UserHistory.group.groupID); @@ -74,7 +77,7 @@ const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCo const disputeURL = `https://resolve.kleros.io/cases/${BigNumber.from(data.id).toNumber()}`; // check rulings, note down shift since reality uses 0,1 for no, yes and kleros uses 1,2 for no, yes const message = (data.finalRuling === 2)? 'broke the rules' : 'did not break the rules' - console.log(data.finalRuling) + //console.log(data.finalRuling) try{ bot.sendMessage(settings.channelID, `The [dispute](${disputeURL}) over *${data.moderationInfo.UserHistory.user.username}*'s [message](${msgLink}) ([backup](${data.moderationInfo.messageBackup})) resolved. *${data.moderationInfo.UserHistory.user.username}* ${message}`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); handleTelegramUpdate(db, bot,settings, data.moderationInfo,timestampNew, data.finalRuling === 2, true, true); @@ -134,6 +137,7 @@ const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCo } } */ + for(const data of moderationActions.realityQuestionAnsweredFinalized){ const settings = validate(data.moderationInfo.UserHistory.group.groupID); // settings[1] language @@ -150,12 +154,16 @@ const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCo } for(const data of moderationActions.realityQuestionAnsweredNotFinalized){ - console.log(data.moderationInfo.UserHistory.group) + //console.log(data.moderationInfo.UserHistory.group) const settings = validate(data.moderationInfo.UserHistory.group.groupID); // settings[1] language try{ const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; const answer = data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001" ? "yes" : "no"; + //console.log('answeredbeg') + //console.log(data) + //console.log(data.moderationInfo.UserHistory) + //console.log('answered') bot.sendMessage(settings.channelID, `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) violate the [rules](${data.moderationInfo.rules})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true}); handleTelegramUpdate(db, bot,settings, data.moderationInfo,timestampNew, data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001", false, false); } catch(e){ @@ -163,12 +171,14 @@ const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCo } } + // promise queue example for(const data of moderationActions.sheriffs){ const settings = validate(data.group.groupID); // settings[1] language try{ const sherrif = await bot.getChatMember(data.group.groupID, data.sheriff.user.userID) + //console.log(sherrif) queue.add(() => bot.sendMessage(settings.channelID, `There's a new sheriff in town 👑🥇🤠[${sherrif.user.username}](tg://user?id=${sherrif.user.id})🤠🥇👑`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})); } catch(e){ console.log(e) @@ -179,13 +189,33 @@ const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCo const settings = validate(data.group.groupID); // settings[1] language try{ - const deputysherrif = await bot.getChatMember(data.group.groupID, data.sheriff.user.userID) + const deputysherrif = await bot.getChatMember(data.group.groupID, data.deputySheriff.user.userID) bot.sendMessage(settings.channelID, `There's a new deputy sheriff in town 🥈[${deputysherrif.user.username}](tg://user?id=${deputysherrif.user.id})🥈`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); } catch(e){ console.log(e) } } + for(const data of moderationActions.ranks){ + const settings = validate(data.group.groupID); + // settings[1] language + try{ + const userUpdate = await bot.getChatMember(data.group.groupID, data.user.userID) + let message = "" + if (data.status === "GoodSamaritan"){ + message = "🎖 ***Good Samaritan Award***🎖\n\nThe Good Samaritan award is this group's highest honor, given to members who performed exemplary deeds of service for their group or their fellow members. Thank you for your service 🙏" + } else if (data.status === "NeighborhoodWatch"){ + message = "🤝 ***Neighborhood Watch Recognition*** 🤝\n\n The Neighborhood Watch recognition is given to members who help protect their community. Thank you for your service 🙏" + } else if (data.status === "BoyWhoCriedWolf"){ + "Have you ever heard of the fable of 💩 the boy who cried wolf 💩?\n\nBe careful, too many unanswered reports could hurt your reputation, " + } + if(data.status !== "CommunityMember") + bot.sendMessage(settings.channelID, `${message} [${userUpdate.user.username}](tg://user?id=${userUpdate.user.id})`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); + } catch(e){ + console.log(e) + } + } + await queue.onIdle() await realitio_bot(web3, history.last_block, process.env.REALITY_ETH_V30, process.env.REALITIO_ARBITRATOR); setCron(db, currentBlock,currentTime) @@ -231,18 +261,18 @@ const validate = (chatId: string): groupSettings=> { } const calcPenalty = (ban_level: number, timestamp_finalized: number): number => { - if(ban_level == 0) + if(ban_level == 1) return timestamp_finalized + 86400 - else if (ban_level == 1) + else if (ban_level == 2) return timestamp_finalized + 604800 else return timestamp_finalized + 220147200 } const calcPenaltyPhrase = (ban_level: number): string => { - if(ban_level == 0) + if(ban_level == 1) return 'first time and is subject to a 1 day' - else if (ban_level == 1) + else if (ban_level == 2) return 'second time and is subject to a 1 week' else return 'atleast three times and is subject to a 1 year' @@ -263,7 +293,7 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, calculateHistory = getLocalBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,moderationInfo.UserHistory.group.groupID,finalize) } - const ban_level_history = Math.max(calculateHistory.length-1,0) + const ban_level_history = calculateHistory.length setReport(db, moderationInfo.id,restrict,true,finalize,disputed, finalize? 0 : (restrict? timestampNew: 0), finalize? timestampNew: 0) @@ -276,12 +306,16 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, calculateHistory = getLocalBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,moderationInfo.UserHistory.group.groupID,finalize) } - const ban_level_current = Math.max(calculateHistory.length-1,0) - + const ban_level_current = calculateHistory.length + console.log(ban_level_current) + console.log(ban_level_history) + console.log(calculateHistory) if (restrict){ // TODO federation subscriptions const groups = settings.federation_id? getGroupsInAndFollowingFederation(db,'telegram',settings.federation_id) : [moderationInfo.UserHistory.group.groupID] + console + if (ban_level_current > ban_level_history){ const parole = calcPenalty(ban_level_current,timestampNew) if(finalize){ @@ -289,14 +323,16 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, // philosophy is only escalate the penalties after the user is warned with a temporary ban. // this report changed penalties, recalculate all for (const group of groups) - bot.banChatMember(group.group_id, moderationInfo.UserHistory.user.userID, parole); + bot.banChatMember(group, moderationInfo.UserHistory.user.userID, parole); } else if(!finalize){ const options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false, until_date: parole}; - for (const group of groups) - bot.restrictChatMember(group.group_id, moderationInfo.UserHistory.user.userID, options); + for (const group of groups){ + console.log(group) + bot.restrictChatMember(group, moderationInfo.UserHistory.user.userID, options); + } } // TODO notify federation - bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}) for the ${calcPenaltyPhrase(calculateHistory.length-1)} ban.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true}); + bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}) for the ${calcPenaltyPhrase(ban_level_current)} ban.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true}); } else{ bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messsageBackup})) violated the [rules](${moderationInfo.rulesUrl}). The conduct occured before *${moderationInfo.UserHistory.user.username}*'s latest effective ban. The next time ${moderationInfo.UserHistory.user.username} breaks the rules, the consequences are more severe.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true}); } @@ -324,7 +360,6 @@ const getQuery = (lastPageUpdated: number, timestampLastUpdated: number, botaddr moderationType rulesUrl UserHistory{ - timestampParole countBrokeRulesArbitrated group { groupID @@ -401,5 +436,14 @@ return `{ } } } + ranks: userHistories(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampStatusUpdated_gt: ${timestampLastUpdated}, group_: {botAddress: "${botaddress}", platform: "Telegram"}}) { + status + user{ + userID + } + group{ + groupID + } + } }`; } \ No newline at end of file diff --git a/lib/db.ts b/lib/db.ts index 510cac0..48030d0 100644 --- a/lib/db.ts +++ b/lib/db.ts @@ -313,7 +313,7 @@ const getGroupSettings = (db: any, platform: string, groupId: string): groupSett thread_id_welcome: result?.thread_id_welcome, greeting_mode: result?.greeting_mode, captcha: result?.captcha, - admin_reportable: result?.admin_reportable, + admin_reportable: result?.admins_reportable, federation_id: result?.federation_id, federation_id_following: result?.federation_id_following, } diff --git a/lib/graph.ts b/lib/graph.ts index e99b25b..ad09f5a 100644 --- a/lib/graph.ts +++ b/lib/graph.ts @@ -38,6 +38,31 @@ const getAllowance = async (botAddress: string, platform: string, groupId: strin } } +const getLeaderboard = async (group_id: string) => { + const query = `{ + userHistories(first: 10, orderBy: countReportsMadeAndRespondedYes, orderDirection: desc, where:{group_:{botAddress: "${process.env.BOT_ACCOUNT}", groupID: "${group_id}", platform: "Telegram"}}) { + status + countReportsMadeAndRespondedYes + user{ + userID + } + } + }`; + try{ + return (await request( + 'https://api.thegraph.com/subgraphs/name/shotaronowhere/kleros-moderate-goerli', + query + ))?.userHistories; + } catch(e){ + console.log(e) + return undefined + } +} + +/* + +*/ + const existsQuestionId = async (question_id: string): Promise => { const query = `{ moderationInfos(where: {id: "${question_id}"}){ @@ -73,4 +98,4 @@ const getQuestionsNotFinalized = async (botaddress: string): Promise => { + myBot = bot const evidencePath = await upload(bot, settings.lang, msg); const evidenceJsonPath = await uploadEvidenceJson(settings.lang, msg, evidencePath); try{ @@ -178,7 +186,8 @@ const regexpFullReason = /\/addevidence (.+) (.+)/ const callback = async (db: any, settings: groupSettings, bot: any, botID: number, msg: any, matchh: string[], batchedSend: any) => { if (!msg.reply_to_message) { try{ - bot.sendMessage(msg.chat.id, `/addevidence ${langJson[settings.lang].errorReply}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) + const resp = bot.sendMessage(msg.chat.id, `/addevidence ${langJson[settings.lang].errorReply}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) + myCache.set(resp.message_id, msg.chat.id) } catch (e){ console.log(e) } @@ -215,7 +224,8 @@ const callback = async (db: any, settings: groupSettings, bot: any, botID: numbe //TODO Evidence IDs and button callback UX if (!match || match.length < 2){ try{ - bot.sendMessage(msg.chat.id, `You did not specify an evidence group.`, opts) + const msgresponse = await bot.sendMessage(msg.chat.id, `You did not specify an evidence group.`, opts) + myCache.set(msgresponse.message_id, msg.chat.id) } catch(e){ console.log(e) } @@ -230,7 +240,8 @@ const callback = async (db: any, settings: groupSettings, bot: any, botID: numbe const evidenceID = getActiveEvidenceGroupId(db, 'telegram', String(msg.chat.id), Number(remainderMatch[0])); if (!evidenceID){ try{ - bot.sendMessage(msg.chat.id, langJson[settings.lang].addevidence.errorId, opts) + const resp = await bot.sendMessage(msg.chat.id, langJson[settings.lang].addevidence.errorId, opts) + myCache.set(resp.message_id, msg.chat.id) } catch(e){ console.log(e) } @@ -243,7 +254,8 @@ const callback = async (db: any, settings: groupSettings, bot: any, botID: numbe setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), 3, 14, Math.ceil( new Date().getTime() / 1000)); } else if ((Math.ceil( new Date().getTime() / 1000) < reportAllowance.timestamp_refresh + 5760) && reportAllowance.evidence_allowance == 0 ){ try{ - bot.sendMessage(msg.chat.id, langJson[settings.lang].errorAllowance); + const resp = await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorAllowance); + myCache.set(resp.message_id, msg.chat.id) } catch (e){ console.log(e) } diff --git a/lib/telegram/commands/captcha.ts b/lib/telegram/commands/captcha.ts new file mode 100644 index 0000000..4a415b6 --- /dev/null +++ b/lib/telegram/commands/captcha.ts @@ -0,0 +1,55 @@ +import * as TelegramBot from "node-telegram-bot-api"; +import langJson from "../assets/lang.json"; +import {groupSettings} from "../../../types"; + +const NodeCache = require( "node-cache" ); +const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); +var myBot; + +myCache.on("expired",function(key,value){ + myBot.deleteMessage(value, key); + }); + +const callback = async (bot: any, settings: groupSettings, msg: any) => { + myBot = bot + try{ + + + const opts = { + parse_mode: 'Markdown', + disable_web_page_preview: true, + reply_markup: { + inline_keyboard: [ + [ + { + text: 'I agree to follow the rules.', + callback_data: '5|'+String(msg.from.id) + } + ] + ] + } + }; + const optsThread = { + parse_mode: 'Markdown', + reply_to_message_id: msg.reply_to_message.message_id, + message_thread_id: msg.message_thread_id, + disable_web_page_preview: true, + reply_markup: { + inline_keyboard: [ + [ + { + text: 'I agree to follow the rules.', + callback_data: '5|'+String(msg.from.id) + } + ] + ] + } + }; + const msg_welcome = bot.sendMessage(msg.chat.id, `Welcome [${msg.from.first_name}](tg://user?id=${msg.from.id}) ${langJson[settings.lang].greeting2}(${settings.rules}). ${langJson[settings.lang].greeting3}`, msg.chat.is_forum? optsThread: opts); + myCache.set(msg_welcome.message_id, msg.chat.id) + } catch(e){ + console.log(e) + } +} + +export {callback}; \ No newline at end of file diff --git a/lib/telegram/commands/fedinfo.ts b/lib/telegram/commands/fedinfo.ts index e17acc4..c14b7bd 100644 --- a/lib/telegram/commands/fedinfo.ts +++ b/lib/telegram/commands/fedinfo.ts @@ -37,7 +37,7 @@ const callback = async (db: any, settings: groupSettings, bot: any, botId: strin ] } } - bot.sendMessage(msg.chat.id, `DM me for to create your federation : )`, opts); + bot.sendMessage(msg.chat.id, `DM me for help with your federation : )`, opts); return; } const name = getFederationName(db, 'telegram',msg.from.id); diff --git a/lib/telegram/commands/getChannel.ts b/lib/telegram/commands/getChannel.ts index 8c46138..cb37347 100644 --- a/lib/telegram/commands/getChannel.ts +++ b/lib/telegram/commands/getChannel.ts @@ -2,16 +2,29 @@ import * as TelegramBot from "node-telegram-bot-api"; import {getRule, getInviteURLChannel, getChannelID} from "../../db"; import langJson from "../assets/lang.json"; import { groupSettings } from "../../../types"; +const NodeCache = require( "node-cache" ); +const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); +var myBot; + +myCache.on("expired",function(key,value){ + myBot.deleteMessage(value, key); + }); /* - * /getchannel + * /notifications */ -const regexp = /\/getchannel/ +const regexp = /\/notifications/ const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { - console.log(msg.chat.id) + myBot = bot; const channel_invite = getInviteURLChannel(db, 'telegram', String(msg.chat.id)); - bot.sendMessage(msg.chat.id, `I notify this [channel](${channel_invite}) about moderation activity.`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}); + if(!channel_invite){ + const resp = await bot.sendMessage(msg.chat.id, `Notifications channel not set. Ask an admin to /setchannel.`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}); + myCache.set(resp.message_id, msg.chat.id) + } else { + const resp = await bot.sendMessage(msg.chat.id, `I notify this [channel](${channel_invite}) about moderation activity.`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}); + myCache.set(resp.message_id, msg.chat.id) + } } export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/getLeaderboard.ts b/lib/telegram/commands/getLeaderboard.ts new file mode 100644 index 0000000..3d37768 --- /dev/null +++ b/lib/telegram/commands/getLeaderboard.ts @@ -0,0 +1,52 @@ +import * as TelegramBot from "node-telegram-bot-api"; +const escape = require('markdown-escape') +import langJson from "../assets/lang.json"; +import {getLeaderboard} from "../../graph"; +import { groupSettings } from "../../../types"; +/* + * /getaccount + */ +const regexp = /\/leaderboard/ + +/* + +(sheriffs) + +good samartian (>2/3 answered yes, >10 reports) +- perks: report as many as long as yes>total +- evidence 5*report limit + +neighborhood watch (>1/3 answered yes > 3 reports) +- perks: 6 reports per day +- 30 pieces of evidence + +community member (neutral) +- 3 reports per day +- 15 pieces of evidence + +boy who cried wolf (>2/3 answered !yes, >10 reports) +- 1 report per day +- 5 pieces of evidence + +*/ + +const callback = async (db: any, settings: groupSettings, bot: any, botid: number, msg: any) => { + try{ + const reports = await getLeaderboard(msg.chat.id); + if (reports.length == 0){ + bot.sendMessage(msg.chat.id, "No active leaderboard", msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}:{parse_mode: "Markdown"}); + return; + } + var reportMessage: string = langJson[settings.lang].getReports.reportMessage + ':\n\n'; + + await reports.forEach(async (report) => { + + reportMessage += ` - ${report.status} ${report.countReportsMadeAndRespondedYes} ${report.user.userID}\n`; + }); + bot.sendMessage(msg.chat.id, reportMessage, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown", disable_web_page_preview: true}:{parse_mode: "Markdown", disable_web_page_preview: true}); + } catch(e){ + console.log(e) + } +} + +export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/getReports.ts b/lib/telegram/commands/getReports.ts index 5d34027..94b65c2 100644 --- a/lib/telegram/commands/getReports.ts +++ b/lib/telegram/commands/getReports.ts @@ -3,12 +3,20 @@ const escape = require('markdown-escape') import langJson from "../assets/lang.json"; import {getReportsUserInfo ,getActiveReportsInfo} from "../../db"; import { groupSettings } from "../../../types"; +const NodeCache = require( "node-cache" ); +const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); +var myBot; + +myCache.on("expired",function(key,value){ + myBot.deleteMessage(value, key); + }); /* - * /getaccount + * /getreports */ const regexp = /\/getreports/ const callback = async (db: any, settings: groupSettings, bot: any, botid: number, msg: any) => { + myBot = bot try{ if (msg.chat.type !== "private"){ const opts = msg.chat.is_forum? { @@ -37,7 +45,8 @@ const callback = async (db: any, settings: groupSettings, bot: any, botid: numbe ] } } - bot.sendMessage(msg.chat.id, `DM me for report info : )`, opts); + const resp = await bot.sendMessage(msg.chat.id, `DM me for report info : )`, opts); + myCache.set(resp.message_id, msg.chat.id) return; } diff --git a/lib/telegram/commands/getRules.ts b/lib/telegram/commands/getRules.ts index b6671aa..89a155b 100644 --- a/lib/telegram/commands/getRules.ts +++ b/lib/telegram/commands/getRules.ts @@ -2,6 +2,13 @@ import * as TelegramBot from "node-telegram-bot-api"; import {getRule} from "../../db"; import langJson from "../assets/lang.json"; import { groupSettings } from "../../../types"; +const NodeCache = require( "node-cache" ); +const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); +var myBot; + +myCache.on("expired",function(key,value){ + myBot.deleteMessage(value, key); + }); /* * /rules @@ -9,7 +16,10 @@ import { groupSettings } from "../../../types"; const regexp = /\/rules/ const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { - bot.sendMessage(msg.chat.id, `${langJson[settings.lang].rules}(${settings.rules}).`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}); + myBot = bot + getRule(db,'telegram', msg.chat.id,Math.floor(Date.now()/1000)) + const msgresponse = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].rules}(${settings.rules}).`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id, disable_web_page_preview: false}:{parse_mode: "Markdown", disable_web_page_preview: false}); + myCache.set(msgresponse.message_id, msg.chat.id) } export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/help.ts b/lib/telegram/commands/help.ts index 53df8d1..8d4910b 100644 --- a/lib/telegram/commands/help.ts +++ b/lib/telegram/commands/help.ts @@ -13,7 +13,7 @@ const helpgnosis = (db: any, settings: groupSettings, bot: any, botId: number, m Susie uses [xDAI](https://docs.gnosischain.com/about/tokens/xdai), a stable coin, on [Gnosis Chain](https://www.gnosis.io/). Don't know what that means? It means Susie uses a cheap and fast decentralized tool to coordinate moderation fairly and transparently. -What's crypto? I heard about that on the news, I don't want anything to do with crypto. No problem, you can ask for help in the @KlerosModerateGuildOfJustice for help from freelance moderators. +What's crypto? I heard about that on the news, I don't want anything to do with crypto. No problem, you can ask for help from freelance moderators in @KlerosModerateGuildOfJustice. Don't have any xDAI on Gnosis Chain? No problem, there's a (cheap, fast) [bridge](https://bridge.connext.network/?receivingChainId=100&receivingAssetId=0x0000000000000000000000000000000000000000) for that. @@ -42,10 +42,11 @@ How to enable notification channels: 4. Use that channel ID to set notifications with /setchannel in the original group *User commands*: -- /getchannel: Returns current notification channel +- /notifications: Returns current notification channel *Admin commands*: -- /setchannel : Sets the rules to the the url` +- /setchannel : Sets the notification channel to the specified channel id` ,{parse_mode: 'Markdown', disable_web_page_preview: true}) + bot.sendVideo(msg.chat.id, `https://ipfs.kleros.io/ipfs/QmaWKFxR8TNzWW1xDuzXe4XFE5wCFJVuFP6AKCQ3LRAQqB/Screen%20Recording%202022-12-13%20at%209.19.17%20PM(1).mp4`); } catch(e){ console.log(e) } @@ -133,10 +134,10 @@ const respond = (settings: groupSettings, bot: any, helpType: string, callbackQu text: '⚖️ Court', callback_data: `3|court` }, { - text: '🧑‍⚖️ Find a Lawyer', + text: '🧑‍⚖️ Lawyer', callback_data: `3|lawyer` }, { - text: '✨ Open Source', + text: '✨ Open', callback_data: `3|open` } ],[ @@ -147,7 +148,7 @@ const respond = (settings: groupSettings, bot: any, helpType: string, callbackQu text: '🌐 Federation', callback_data: `3|federation` }, { - text: '⛓️ Gnosis Chain', + text: '⛓️ Gnosis', callback_data: `3|web2.5` } ] @@ -164,7 +165,7 @@ Welcome your members with a greeting informing them of the group rules - /welcome : Toggles on/off welcomes messages. - /captcha : Toggles on/off rules captcha. -When a new person joins, or after 5 minutes, the previous welcome messages will get deleted, but the captchas will remain for up to 5 minutes. +When a new person joins, or after 5 minutes, the previous welcome messages will get deleted\n\nCaptchas remain for up to 5 minutes. If a user forgets to respond within 5 minutes, they should rejoin the group to prompt a new captcha. `,optsResponse) break; } @@ -201,7 +202,7 @@ Topics allow large (>200 member) groups to focus discussion in dedicated **topic To prevent important messages from deletion, pre-emptively, messages can be saved as evidence. *User commands*: -- /addevidence : Reply to a message to add it as evidence` +- /addevidence \n\nReply to a message to add it as evidence` ,optsResponse) break; } @@ -230,7 +231,7 @@ Answers to reports can be disputed, creating a case in the Kleros court. Refer t case 'rules': { bot.editMessageText(`⚖️ *Rules* ⚖️ -The [Kleros Moderate Community Guidelines](https://ipfs.kleros.io/ipfs/QmYYcNfEYLtxPM8fof4wf9Tqj7gBGMDMmNnBqZKR1zSczX/Kleros%20Moderate%20Community%20Guidelines%20v1.pdf) apply as the default rules. Crafting precise policies can be challenging, if you are certain in setting a new policy, you can set new rules with /setrules +The Kleros Moderate Community Guidelines apply as the [default rules]((https://ipfs.kleros.io/ipfs/QmYYcNfEYLtxPM8fof4wf9Tqj7gBGMDMmNnBqZKR1zSczX/Kleros%20Moderate%20Community%20Guidelines%20v1.pdf)). Crafting precise policies can be challenging, if you are certain in setting a new policy, you can set new rules with /setrules *User commands*: - /rules: Returns current rules @@ -253,9 +254,9 @@ How to enable notification channels: 4. Use that channel ID to set notifications with /setchannel in the original group *User commands*: -- /getchannel: Returns current notification channel +- /notifications: Returns current notification channel *Admin commands*: -- /setchannel : Sets the rules to the the url` +- /setchannel : Sets the notification channel to the specified channel id` ,optsResponse) break; } @@ -281,7 +282,7 @@ Susie uses [xDAI](https://docs.gnosischain.com/about/tokens/xdai), a stable coin Don't have any xDAI on Gnosis Chain? No problem, there's a (cheap, fast) [bridge](https://bridge.connext.network/?receivingChainId=100&receivingAssetId=0x0000000000000000000000000000000000000000) for that. -What's crypto? I heard about that on the news, I don't want anything to do with crypto. No problem, you can ask for help in the @KlerosModerateGuildOfJustice for help from freelance moderators. +What's crypto? I heard about that on the news, I don't want anything to do with crypto. No problem, you can ask for help from freelance moderators in @KlerosModerateGuildOfJustice. Don't have any cryptocurrency? No problem, there's a convinient [fiat on-ramp](https://www.mtpelerin.com/buy-xdai) (credit card or bank transfer) to buy DAI on Gnosis Chain. @@ -317,12 +318,10 @@ If you would like to offer your services as a lawyer or solicit services, please bot.editMessageText(`✨ *Open Source* ✨ Susie is [open source](https://github.com/kleros/kleros-moderate). Feel free to make an issue, feature request, bug report, comments, suggests, PRs, forks, etc : ) - -Susie is hosted. You can self-host the Susie, a raspberry pi or an old laptop are sufficient to keep your own instance of Susie online. To learn more about self-hosting, see this [guide](https://github.com/kleros/kleros-moderate/self-hosting.md) *soon*. - ` ,optsResponse) break; + //Susie is hosted. You can self-host Susie. A raspberry pi or an old laptop are sufficient to keep your own instance of Susie online. To learn more about self-hosting, guide *coming soon*. } default: { break; @@ -340,11 +339,11 @@ I have lots of handy features, such as crowd-sourced user reporting. Helpful commands: - /start: Starts me. You've probably already used this. - /help: Sends this message and I'll tell you more about myself. - -Important: I moderate groups by crowd-sourcing community input with Gnosis Chain. Make sure you or some community members get DAI on Gnosis Chain to participate actively. Select a feature to learn more. My [documentation](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator) is also helpful, or ask a question in @SusieSupport.`; +//Important: I moderate groups by crowd-sourcing community input with Gnosis Chain. Make sure you or some community members get DAI on Gnosis Chain to participate actively. + const opts = { parse_mode: 'Markdown', disable_web_page_preview: true, @@ -379,10 +378,10 @@ const opts = { text: '⚖️ Court', callback_data: `3|court` }, { - text: '🧑‍⚖️ Find a Lawyer', + text: '🧑‍⚖️ Lawyer', callback_data: `3|lawyer` }, { - text: '✨ Open Source', + text: '✨ Open', callback_data: `3|open` } ], @@ -394,7 +393,7 @@ const opts = { text: '🌐 Federation', callback_data: `3|federation` }, { - text: '⛓️ Gnosis Chain', + text: '⛓️ Gnosis', callback_data: `3|web2.5` } ] diff --git a/lib/telegram/commands/joinfed.ts b/lib/telegram/commands/joinfed.ts index 0ccd602..1c1642d 100644 --- a/lib/telegram/commands/joinfed.ts +++ b/lib/telegram/commands/joinfed.ts @@ -15,15 +15,15 @@ const callback = async (db: any, settings: groupSettings, bot: any, botId: strin message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); } else{ - const name = getFederationName(db, 'telegram',match[1].substring(0,65)) + const name = getFederationName(db, 'telegram',String(Number(match[1]))) if (!name) bot.sendMessage(settings.channelID, `Federation not found. The federation id of any group can be found by sending \`/fedinfo\` in a group.`,msg.chat.is_forum? { message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); - if (msg.from.id === match[1]) - joinFederation(db, 'telegram', String(msg.chat.id), match[1].substring(0,65)) + else if (msg.from.id === match[1]) + joinFederation(db, 'telegram', String(msg.chat.id), match[1]) else - followFederation(db, 'telegram', String(msg.chat.id), match[1].substring(0,65)) + followFederation(db, 'telegram', String(msg.chat.id), match[1]) } } catch(e){ console.log(e) diff --git a/lib/telegram/commands/newfed.ts b/lib/telegram/commands/newfed.ts index 43b53e5..7990056 100644 --- a/lib/telegram/commands/newfed.ts +++ b/lib/telegram/commands/newfed.ts @@ -2,6 +2,13 @@ import * as TelegramBot from "node-telegram-bot-api"; import { groupSettings } from "../../../types"; import {setFederation,getFederationName} from "../../db"; import langJson from "../assets/lang.json"; +const NodeCache = require( "node-cache" ); +const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); +var myBot; + +myCache.on("expired",function(key,value){ + myBot.deleteMessage(value, key); + }); /* * /joinfed @@ -10,6 +17,7 @@ const regexp = /\/newfed\s?(.+)?/ const callback = async (db: any, settings: groupSettings, bot: any, botId: string, msg: any, match: string[]) => { try{ + myBot = bot if (msg.chat.type !== "private"){ const opts = msg.chat.is_forum? { message_thread_id: msg.message_thread_id, @@ -18,7 +26,7 @@ const callback = async (db: any, settings: groupSettings, bot: any, botId: strin inline_keyboard: [ [ { - text: 'Get Help (DM)', + text: 'Create your federation', url: `https://t.me/${process.env.BOT_USERNAME}?start=newfed` } ] @@ -30,14 +38,15 @@ const callback = async (db: any, settings: groupSettings, bot: any, botId: strin inline_keyboard: [ [ { - text: 'Get Help (DM)', + text: 'Create your federation', url: `https://t.me/${process.env.BOT_USERNAME}?start=newfed` } ] ] } } - bot.sendMessage(msg.chat.id, `DM me for to create your federation : )`, opts); + const resp = await bot.sendMessage(msg.chat.id, `DM me for help with your federation : )`, opts); + myCache.set(resp.message_id, msg.chat.id) return; } const name = getFederationName(db, 'telegram',msg.from.id); diff --git a/lib/telegram/commands/report.ts b/lib/telegram/commands/report.ts index 617e397..d7db3cf 100644 --- a/lib/telegram/commands/report.ts +++ b/lib/telegram/commands/report.ts @@ -12,27 +12,52 @@ const regexp = /\/report\s?(.+)?/ // cacheIndex => groupID,reported message id => [pending report message id] const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 900, checkperiod: 1200 } ); - +const myCacheGarbageCollection = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); +const myCacheGarbageCollectionSlow = new NodeCache( { stdTTL: 900, checkperiod: 1200 } ); +var myBot; + +myCacheGarbageCollection.on("expired",function(key,value){ + myBot.deleteMessage(value, key); + }); +myCacheGarbageCollectionSlow.on("expired",function(key,value){ + myBot.deleteMessage(value, key); + }); const callback = async (db:any, settings: groupSettings, bot: any, botId: number, msg: any, match: string[]) => { try{ + myBot = bot if (!msg.reply_to_message) { - bot.sendMessage(msg.chat.id, `/report ${langJson[settings.lang].errorReply}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + const resp = await bot.sendMessage(msg.chat.id, `/report ${langJson[settings.lang].errorReply}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return; } if (msg.reply_to_message.date < Date.now()/1000-86400*7){ - bot.sendMessage(msg.chat.id, `Live and let live. This message is more than one week old. The future is asynchronous, but we believe moderation should not be punitive. Next time try to make the report sooner.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + const resp = await bot.sendMessage(msg.chat.id, `Live and let live. This message is more than one week old. The future is asynchronous, but we believe moderation should not be punitive. Next time try to make the report sooner.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + myCacheGarbageCollection.set(resp.message_id, msg.chat.id) + return; } // WHO WATCHES THE WATCHMEN?? // can't ban bots if (msg.reply_to_message.from.is_bot){ + let resp; if(msg.reply_to_message.from.username === "GroupAnonymousBot") - bot.sendMessage(msg.chat.id, `User is anonymous. Ask admins to disable anonymouse admins to moderate admin behavior.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + resp = await bot.sendMessage(msg.chat.id, `User is anonymous. Ask admins to disable anonymouse admins to moderate admin behavior.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); else - bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.errorModBot}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + resp = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.errorModBot}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + + myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return } + let report: TelegramBot.ChatMember + if(!settings.admin_reportable){ + report = await bot.getChatMember(msg.chat.id,msg.reply_to_message.from.id) + if(report.status === "administrator" || report.status === "creator"){ + const resp = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.errorAdmin}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + myCacheGarbageCollection.set(resp.message_id, msg.chat.id) + return + } + } const fromUsername = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name || `no-username-set`); const reportedUserID = String(msg.reply_to_message.from.id); @@ -41,12 +66,14 @@ const callback = async (db:any, settings: groupSettings, bot: any, botId: number const cachedReportRequestMessage = myCache.get([msg.chat.id, msg.reply_to_message.message_id].toString()) if (cachedReportRequestMessage){ // message already reported const msgLinkReport = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + cachedReportRequestMessage; - bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.reported}(${msgLinkReport})`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); + const resp = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.reported}(${msgLinkReport})`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); + myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return; } const reportedQuestionId = getQuestionId(db, 'telegram', String(msg.chat.id), reportedUserID, String(msg.reply_to_message.message_id)); if (reportedQuestionId){ - bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.reported}(https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${reportedQuestionId})`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); + const resp = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.reported}(https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${reportedQuestionId})`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true}); + myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return; } @@ -55,7 +82,8 @@ const callback = async (db:any, settings: groupSettings, bot: any, botId: number const rules = getRule(db, 'telegram', String(msg.chat.id), msg.reply_to_message.date); if (!rules){ - bot.sendMessage(msg.chat.id, langJson[settings.lang].report.norules, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + const resp = await bot.sendMessage(msg.chat.id, langJson[settings.lang].report.norules, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return; } @@ -65,10 +93,13 @@ const callback = async (db:any, settings: groupSettings, bot: any, botId: number // TODO report const reportAllowance = getAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id)); - if (!reportAllowance){ + if(!settings.admin_reportable && (report.status === "administrator" || report.status === "creator")){ + + } else if (!reportAllowance){ setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), 2, 15, currentTimeMs); } else if (currentTimeMs < reportAllowance.timestamp_refresh + 28800 && reportAllowance.report_allowance == 0 ){ - bot.sendMessage(msg.chat.id, langJson[settings.lang].report.noallowance, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + const resp = await bot.sendMessage(msg.chat.id, langJson[settings.lang].report.noallowance, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return; } else{ const newReportAllowance = reportAllowance.report_allowance + Math.floor((currentTimeMs - reportAllowance.timestamp_refresh)/28800) - 1; @@ -109,7 +140,8 @@ const callback = async (db:any, settings: groupSettings, bot: any, botId: number }; const msgLink = `https://t.me/c/${String(msg.chat.id).substring(4)}/${msg.chat.is_forum? `${msg.message_thread_id}/`:''}${msg.reply_to_message.message_id}`; const reportRequestMsg: TelegramBot.Message = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].socialConsensus.consensus2} [${fromUsername}](tg://user?id=${reportedUserID}) ${langJson[settings.lang].socialConsensus.consensus3}(${rules}) ${langJson[settings.lang].socialConsensus.consensus4}(${msgLink}) ([${langJson[settings.lang].socialConsensus.consensus5}](${msgBackup}))?`, msg.chat.is_forum? optsThread: opts); - myCache.set([msg.chat.id, msg.reply_to_message.message_id].toString(),`${msg.chat.is_forum? `${msg.message_thread_id}/`:''}${msg.reply_to_message.message_id}`) ; + myCache.set([msg.chat.id, msg.reply_to_message.message_id].toString(),`${msg.chat.is_forum? `${msg.message_thread_id}/${reportRequestMsg.message_id}`:''}${reportRequestMsg.message_id}`) ; + myCacheGarbageCollectionSlow.set(reportRequestMsg.message_id, msg.chat.id) return; } catch(e){ console.log(e) diff --git a/lib/telegram/commands/setChannel.ts b/lib/telegram/commands/setChannel.ts index 762802b..2bc0c69 100644 --- a/lib/telegram/commands/setChannel.ts +++ b/lib/telegram/commands/setChannel.ts @@ -10,11 +10,13 @@ import langJson from "../assets/lang.json"; const regexp = /\/setchannel/ const regexpFull = /\/setchannel (.+)/ -const callback = async (db: any, settings: groupSettings, bot: TelegramBot, botId: string, msg: TelegramBot.Message, match: string[], batchedSend: any) => { +const callback = async (db: any, settings: groupSettings, bot: TelegramBot, botId: string, msg: any, match: string[], batchedSend: any) => { try { + if (msg.chat.is_fourm) + return const newmatch = msg.text.match(regexpFull); if (!newmatch || newmatch.length < 2){ - bot.sendMessage(msg.chat.id, `/setchannel must be followed by a channel id. [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpnotifications) me if you need more help : )`, {parse_mode: "Markdown"}); + bot.sendMessage(msg.chat.id, `/setchannel must be followed by a channel id. [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpnotifications) me if you need more help : )`, {parse_mode: "Markdown", disable_web_page_preview: true}); return; } try{ @@ -48,7 +50,7 @@ const callback = async (db: any, settings: groupSettings, bot: TelegramBot, botI const invite_url_channel = await bot.exportChatInviteLink(newmatch[1]); setInviteURLChannel(db, 'telegram', String(msg.chat.id), invite_url_channel); setChannelID(db, 'telegram', String(msg.chat.id), newmatch[1]); - bot.sendMessage(msg.chat.id, `Moderation announcement [channel](${invite_url_channel}).`, {parse_mode: "Markdown"}); + bot.sendMessage(msg.chat.id, `Moderation notifications will now be sent to this [channel](${invite_url_channel}).`, {parse_mode: "Markdown"}); bot.sendMessage(newmatch[1], `This channel will now relay moderation notifications for ${msg.chat.title}`, {parse_mode: "Markdown"}); } catch (error) { console.log(error); diff --git a/lib/telegram/commands/setLanguage.ts b/lib/telegram/commands/setLanguage.ts index 3efc654..6975f26 100644 --- a/lib/telegram/commands/setLanguage.ts +++ b/lib/telegram/commands/setLanguage.ts @@ -53,9 +53,11 @@ const setLanguageConfirm = async (db: any, bot: any, settings: groupSettings, la setLang(db, 'telegram', String(msg.chat.id),langCode); setRules(db, 'telegram', String(msg.chat.id), langJson[langCode].defaultRules, Math.floor(Date.now()/1000)); bot.sendMessage(msg.chat.id, langJson[langCode].confirmationLanguage, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); - const msgDefaultRules = await bot.sendMessage(msg.chat.id, `${langJson[langCode].defaultRulesMsg1}(${langJson[langCode].defaultRules}). ${langJson[langCode].defaultRulesMsg2}.`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: settings.thread_id_rules}: {}) - const msgRules = await bot.forwardMessage(msg.chat.id, msg.chat.id, msgDefaultRules.message_id, {message_thread_id: settings.thread_id_rules}); - bot.pinChatMessage(msg.chat.id, msgRules.message_id, {message_thread_id: settings.thread_id_rules}) + if (msg.chat.is_forum){ + const msgDefaultRules = await bot.sendMessage(msg.chat.id, `${langJson[langCode].defaultRulesMsg1}(${langJson[langCode].defaultRules}). ${langJson[langCode].defaultRulesMsg2}.`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: settings.thread_id_rules}: {}) + const msgRules = await bot.forwardMessage(msg.chat.id, msg.chat.id, msgDefaultRules.message_id, {message_thread_id: settings.thread_id_rules}); + bot.pinChatMessage(msg.chat.id, msgRules.message_id, {message_thread_id: settings.thread_id_rules}) + } } catch(e){ console.log('setLanguageConfirm error '+e); } diff --git a/lib/telegram/commands/start.ts b/lib/telegram/commands/start.ts index 64b8396..86335ea 100644 --- a/lib/telegram/commands/start.ts +++ b/lib/telegram/commands/start.ts @@ -25,9 +25,9 @@ const callback = async (db: any, settings: groupSettings, bot: any, botID: strin ] } } - bot.sendMessage(msg.chat.id, `Hi! My name is Susie. + bot.sendMessage(msg.chat.id, `Hi! My name is Susie, nice to meet you : ) -I am a [Kleros Moderate](https://kleros.io/moderate) community manager at your service. Hit /help to find out more about how to use me to my full potential. +I am a [Kleros Moderate](https://kleros.io/moderate) community manager at your service. Use the command /help to find out more about how to use me to my full potential. Join my news channel @KlerosModerateNews to get information on all the latest updates.`, opts) return; @@ -35,17 +35,20 @@ Join my news channel @KlerosModerateNews to get information on all the latest up const botUser = await bot.getChatMember(msg.chat.id, botID) if(botUser.status !== "administrator" || !botUser.can_restrict_members){ - bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', msg.chat.is_forum? {message_thread_id: msg.message_thread_id, caption: "Please give Susie full admin rights.\n\nThen try to /start community moderation again."} : {caption: "Please give Susie full admin rights.\n\nThen try to /start community moderation again."}); + const video = msg.chat.is_forum? 'QmSdP3SDoHCdW739xLDBKM3gnLeeZug77RgwgxBJSchvYV/guide_topics.mp4' : 'QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4' + bot.sendVideo(msg.chat.id, `https://ipfs.kleros.io/ipfs/${video}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, caption: "Please give Susie full admin rights.\n\nThen try to /start community moderation again."} : {caption: "Please give Susie full admin rights.\n\nThen try to /start community moderation again."}); return; } if (msg.chat.is_forum){ if(!botUser.can_manage_topics){ - bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {message_thread_id: msg.message_thread_id, caption: "Susie needs permissions to manage topics to effectively moderate your community.\n\nThen try to /start community moderation again."}); + + bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmSdP3SDoHCdW739xLDBKM3gnLeeZug77RgwgxBJSchvYV/guide_topics.mp4', {message_thread_id: msg.message_thread_id, caption: "Susie needs permissions to manage topics to effectively moderate your community.\n\nThen try to /start community moderation again."}); return; } const thread_ids = getThreadIDNotifications(db, 'telegram', String(msg.chat.id)); if (thread_ids){ bot.sendMessage(msg.chat.id, "Already started.", {message_thread_id: msg.message_thread_id}); + return } console.log(msg); await topicMode(db,bot,settings,msg.chat); @@ -55,12 +58,12 @@ Join my news channel @KlerosModerateNews to get information on all the latest up - Use /setrules to change the default [rules](${langJson[settings.lang].defaultRules}). - User reports are made by replying to a message with /report -- Penalties progress from 1 day to 1 week, and 1 year bans for each violation.`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}: {parse_mode: "Markdown"}) +- Penalties progress from 1 day to 1 week, and 1 year bans for each violation.`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id, disable_web_page_preview: true}: {parse_mode: "Markdown", disable_web_page_preview: true}) return; } catch (e){ try{ if (msg.chat.is_forum){ - bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {message_thread_id: msg.message_thread_id, caption: "Must have can manage topics"}); + bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmSdP3SDoHCdW739xLDBKM3gnLeeZug77RgwgxBJSchvYV/guide_topics.mp4', {message_thread_id: msg.message_thread_id, caption: "Must have can manage topics"}); } else{ bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {caption: langJson[settings.lang].errorAdminRights+"Topics must be enabled"}); } diff --git a/lib/telegram/commands/toggleAdminReportable.ts b/lib/telegram/commands/toggleAdminReportable.ts new file mode 100644 index 0000000..396ed23 --- /dev/null +++ b/lib/telegram/commands/toggleAdminReportable.ts @@ -0,0 +1,20 @@ +import * as TelegramBot from "node-telegram-bot-api"; +import {setAdminReportableMode} from "../../db"; +import langJson from "../assets/lang.json"; +import {groupSettings} from "../../../types"; + +/* + * /welcome + */ +const regexp = /\/adminreportable/ + +const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { + try{ + setAdminReportableMode(db, 'telegram', String(msg.chat.id),settings.admin_reportable? 0: 1) + bot.sendMessage(msg.chat.id, settings.admin_reportable? "Admins are immune from reports." : "Admins are now held accountable like regular users.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + } catch(e){ + console.log(e) + } +} + +export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/index.ts b/lib/telegram/index.ts index 24a4382..c27c0a5 100644 --- a/lib/telegram/index.ts +++ b/lib/telegram/index.ts @@ -3,10 +3,12 @@ import * as TelegramBot from "node-telegram-bot-api"; import * as getAccount from "../../lib/telegram/commands/getAccount"; import * as setRulesCommand from "../../lib/telegram/commands/setRules"; import * as getRules from "../../lib/telegram/commands/getRules"; +import * as getLeaderboard from "../../lib/telegram/commands/getLeaderboard"; import * as addEvidenceHelp from "../../lib/telegram/commands/addEvidenceHelp"; import * as report from "../../lib/telegram/commands/report"; import * as welcome from "../../lib/telegram/commands/welcome"; import * as toggleWelcome from "../../lib/telegram/commands/toggleWelcome"; +import * as toggleAdminReportable from "../../lib/telegram/commands/toggleAdminReportable"; import * as greeting from "../../lib/telegram/commands/greeting"; import * as toggleCaptcha from "../../lib/telegram/commands/toggleCaptcha"; import * as help from "../../lib/telegram/commands/help"; @@ -55,6 +57,12 @@ const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 900, checkperiod: 1200 } ); // Throttling +const myCacheGarbageCollection = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); + +myCacheGarbageCollection.on("expired",function(key,value){ + bot.deleteMessage(value, key); + }); + const delay = (delayInms) => { return new Promise(resolve => setTimeout(resolve, delayInms)); } @@ -81,7 +89,8 @@ bot.on("my_chat_member", async function(myChatMember: any) { return else try{ - bot.sendVideo(myChatMember.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {caption: "Hi! I'm Susie, a moderation and group management bot. Please promote me to an admin then try to /start me to unlock my full potential."}); + const video = myChatMember.chat.is_forum? 'QmSdP3SDoHCdW739xLDBKM3gnLeeZug77RgwgxBJSchvYV/guide_topics.mp4' : 'QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4' + bot.sendVideo(myChatMember.chat.id, `https://ipfs.kleros.io/ipfs/${video}`, {caption: "Hi! I'm Susie, a moderation and group management bot. Please promote me to an admin then try to /start me to unlock my full potential."}); } catch(e){ console.log(e) } @@ -170,6 +179,7 @@ const commands: {regexp: RegExp, callback: any}[] = [ help, newFed, getChannel, + toggleAdminReportable, leaveFed, joinFed, setChannel, @@ -178,7 +188,7 @@ const commands: {regexp: RegExp, callback: any}[] = [ setLanguage, ]; -const adminOnlyCommands = [joinFed, leaveFed, setLanguage, setChannel, toggleWelcome, start, setRulesCommand ] +const adminOnlyCommands = [joinFed, leaveFed, newFed, toggleCaptcha, setLanguage, setChannel, toggleWelcome, toggleAdminReportable, start, setRulesCommand ] commands.forEach((command) => { bot.onText( @@ -213,7 +223,8 @@ commands.forEach((command) => { if (command === start){ if (hasStarted(msg.chat.id)){ try{ - bot.sendMessage(msg.chat.id, "Susie is already moderating this community.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id} : {}) + const resp = await bot.sendMessage(msg.chat.id, "Susie is already moderating this community.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id} : {}) + myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return } catch(e){ console.log(e) @@ -243,7 +254,8 @@ commands.forEach((command) => { } if (!(status === 'creator' || status === 'administrator')) { try{ - bot.sendMessage(msg.chat.id, langJson[groupSettings.lang].errorAdminOnly, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + const resp = await bot.sendMessage(msg.chat.id, langJson[groupSettings.lang].errorAdminOnly, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + myCacheGarbageCollection.set(resp.message_id, msg.chat.id) } catch(e){ console.log(e) } @@ -253,7 +265,7 @@ commands.forEach((command) => { // todo success bool return val, to not always delete settings command.callback(db, groupSettings, bot, botId, msg, match,batchedSend); - if (command === setLanguage || command === setRulesCommand || command === setChannel || command === toggleWelcome || command === toggleCaptcha) + if (command === setLanguage || command === setRulesCommand || command === setChannel || command === toggleWelcome || command === toggleCaptcha || command === toggleAdminReportable) myCache.del(msg.chat.id) if (command === start) myCache.del("started"+msg.chat.id) diff --git a/subgraph/schema.graphql b/subgraph/schema.graphql index eb7fce3..cca1f3e 100644 --- a/subgraph/schema.graphql +++ b/subgraph/schema.graphql @@ -1,3 +1,23 @@ + +enum Status { + """ + >2/3 answered yes, >10 reports + """ + GoodSamaritan + """ + >1/3 answered yes, >3 reports + """ + NeighborhoodWatch + """ + Neutral State + """ + CommunityMember + """ + >2/3 answered !yes, >10 reports + """ + BoyWhoCriedWolf +} + type ModerationDispute @entity{ id: ID! timestampLastUpdated: BigInt! @@ -40,17 +60,19 @@ type UserHistory @entity{ id: ID! user: User! group: Group! + status: Status! + timestampStatusUpdated: BigInt! timestampLastUpdated: BigInt! - timestampParole: BigInt! - countBrokeRulesOptimisticAndArbitrated: Int! + countBrokeRulesOptimistic: Int! countBrokeRulesArbitrated: Int! countReportsMade: Int! - countReportsMadeAndResponded: Int! + countReportsMadeAndRespondedYes: Int! + countReportsMadeAndDisputedYes: Int! timestampLastReport: BigInt! moderation: [ModerationInfo!]! @derivedFrom(field: "UserHistory") } -type User @entity(immutable: true){ +type User @entity{ id: ID! username: String userID: String! diff --git a/subgraph/src/Realitio_v2_1_ArbitratorWithAppeals.ts b/subgraph/src/Realitio_v2_1_ArbitratorWithAppeals.ts index b66b79b..f5edb85 100644 --- a/subgraph/src/Realitio_v2_1_ArbitratorWithAppeals.ts +++ b/subgraph/src/Realitio_v2_1_ArbitratorWithAppeals.ts @@ -5,7 +5,7 @@ import { Evidence as EvidenceEvent } from "../generated/Realitio_v2_1_ArbitratorWithAppeals/Realitio_v2_1_ArbitratorWithAppeals" import { - ModerationDispute, ModerationInfo, RealityCheck, UserHistory, + ModerationDispute, ModerationInfo, RealityCheck, UserHistory, Group } from "../generated/schema" import { log, Bytes, BigInt } from "@graphprotocol/graph-ts" @@ -52,17 +52,43 @@ import { return; } - if (event.params._ruling.equals(BigInt.fromU32(1))){ - userHistory.countBrokeRulesOptimisticAndArbitrated++ + let group = Group.load(userHistory.group) + if (!group){ + log.error('group not found. {}',[userHistory.group]) + return + } + + let reportedByUserHistory = UserHistory.load(modinfo.reportedBy+group.groupID) + if (!reportedByUserHistory){ + log.error('reportedByUserHistory not found. {}',[modinfo.reportedBy+group.groupID]) + return + } + + if (event.params._ruling.equals(BigInt.fromU32(2))){ // kleros 2 is yes userHistory.countBrokeRulesArbitrated++ userHistory.timestampLastUpdated = event.block.timestamp - if(userHistory.countBrokeRulesOptimisticAndArbitrated === 1) - userHistory.timestampParole = event.block.timestamp.plus(BigInt.fromU32(86400)) - if(userHistory.countBrokeRulesOptimisticAndArbitrated === 2) - userHistory.timestampParole = event.block.timestamp.ge(userHistory.timestampParole) ? event.block.timestamp.plus(BigInt.fromU32(604800)) : userHistory.timestampParole.plus(BigInt.fromU32(604800)) - } + + reportedByUserHistory.countReportsMadeAndDisputedYes = 1 + const oldStatus = reportedByUserHistory.status + if(reportedByUserHistory.countReportsMade >= 10 && 3*reportedByUserHistory.countReportsMadeAndRespondedYes > 2*reportedByUserHistory.countReportsMade){ + reportedByUserHistory.status = "GoodSamaritan" + } else if(reportedByUserHistory.countReportsMade >= 3 && 3*reportedByUserHistory.countReportsMadeAndRespondedYes > reportedByUserHistory.countReportsMade){ + reportedByUserHistory.status = "NeighborhoodWatch" + } else if(reportedByUserHistory.countReportsMade >= 10 && 3*reportedByUserHistory.countReportsMadeAndRespondedYes < reportedByUserHistory.countReportsMade){ + reportedByUserHistory.status = "BoyWhoCriedWolf" + } else { + reportedByUserHistory.status = "CommunityMember" + } + + + if (oldStatus != reportedByUserHistory.status){ + reportedByUserHistory.timestampStatusUpdated = event.block.timestamp + } + reportedByUserHistory.save() + + } userHistory.save() - } +} export function handleRulingFunded(event: RulingFundedEvent): void { let moderationInfo = ModerationInfo.load(event.params._localDisputeID.toHexString()); diff --git a/subgraph/src/reality-ethv-30.ts b/subgraph/src/reality-ethv-30.ts index d60e6ea..2d7a311 100644 --- a/subgraph/src/reality-ethv-30.ts +++ b/subgraph/src/reality-ethv-30.ts @@ -18,15 +18,41 @@ export function handleLogNotifyOfArbitrationRequest(event: LogNotifyOfArbitratio log.error('user history not found. {}',[moderationInfo.UserHistory]) return } - if(RealityETHV30.bind(event.address).getBestAnswer(event.params.question_id) === new Bytes(1)){ - userHistory.countBrokeRulesOptimisticAndArbitrated-- - userHistory.timestampLastUpdated = event.block.timestamp - if(userHistory.countBrokeRulesOptimisticAndArbitrated === 0) - userHistory.timestampParole.minus(BigInt.fromU32(86400)) - if(userHistory.countBrokeRulesOptimisticAndArbitrated === 1) - userHistory.timestampParole.minus(BigInt.fromU32(604800)) + let group = Group.load(userHistory.group) + if (!group){ + log.error('group not found. {}',[userHistory.group]) + return + } + + let reportedByUserHistory = UserHistory.load(moderationInfo.reportedBy+group.groupID) + if (!reportedByUserHistory){ + log.error('reportedByUserHistory not found. {}',[moderationInfo.reportedBy+group.groupID]) + return + } + const yes = Bytes.fromHexString('0x0000000000000000000000000000000000000000000000000000000000000001') + + if(RealityETHV30.bind(event.address).getBestAnswer(event.params.question_id).equals(yes)){ + reportedByUserHistory.countReportsMadeAndRespondedYes-- + userHistory.countBrokeRulesOptimistic-- + userHistory.timestampLastUpdated = event.block.timestamp userHistory.save() + const oldStatus = reportedByUserHistory.status + if(reportedByUserHistory.countReportsMade >= 10 && 3*reportedByUserHistory.countReportsMadeAndRespondedYes > 2*reportedByUserHistory.countReportsMade){ + reportedByUserHistory.status = "GoodSamaritan" + } else if(reportedByUserHistory.countReportsMade >= 3 && 3*reportedByUserHistory.countReportsMadeAndRespondedYes > reportedByUserHistory.countReportsMade){ + reportedByUserHistory.status = "NeighborhoodWatch" + } else if(reportedByUserHistory.countReportsMade >= 10 && 3*reportedByUserHistory.countReportsMadeAndRespondedYes < reportedByUserHistory.countReportsMade){ + reportedByUserHistory.status = "BoyWhoCriedWolf" + } else { + reportedByUserHistory.status = "CommunityMember" + } + + if (oldStatus != reportedByUserHistory.status){ + reportedByUserHistory.timestampStatusUpdated = event.block.timestamp + } + + reportedByUserHistory.save() } } @@ -53,36 +79,25 @@ export function handleLogNewAnswer(event: LogNewAnswer): void { return; } - let reportedByUserHistory = UserHistory.load(moderationInfo.reportedBy) + let reportedByUserHistory = UserHistory.load(moderationInfo.reportedBy+group.groupID) if (!reportedByUserHistory){ log.error('reportedByUserHistory missing {}',[moderationInfo.reportedBy]); return; } - const currentAnswer = realityCheck.currentAnswer const yes = Bytes.fromHexString('0x0000000000000000000000000000000000000000000000000000000000000001') if(currentAnswer && currentAnswer.equals(yes)){ if (event.params.answer.notEqual(yes)){ - reportedByUserHistory.countReportsMadeAndResponded-- - realityCheck.timeServed = event.block.timestamp.minus(realityCheck.deadline.minus(moderationInfo.timeout)); - userHistory.countBrokeRulesOptimisticAndArbitrated-- + reportedByUserHistory.countReportsMadeAndRespondedYes-- + userHistory.countBrokeRulesOptimistic-- userHistory.timestampLastUpdated = event.block.timestamp - if(userHistory.countBrokeRulesOptimisticAndArbitrated === 0) - userHistory.timestampParole.minus(BigInt.fromU32(86400)) - if(userHistory.countBrokeRulesOptimisticAndArbitrated === 1) - userHistory.timestampParole.minus(BigInt.fromU32(604800)) } } else if (event.params.answer.equals(yes)){ - reportedByUserHistory.countReportsMadeAndResponded++ - realityCheck.timeServed = BigInt.fromU32(0) - userHistory.countBrokeRulesOptimisticAndArbitrated++ + reportedByUserHistory.countReportsMadeAndRespondedYes++ + userHistory.countBrokeRulesOptimistic++ userHistory.timestampLastUpdated = event.block.timestamp - if(userHistory.countBrokeRulesOptimisticAndArbitrated === 1) - userHistory.timestampParole = event.block.timestamp.plus(BigInt.fromU32(86400)) - if(userHistory.countBrokeRulesOptimisticAndArbitrated === 2) - userHistory.timestampParole = event.block.timestamp.ge(userHistory.timestampParole) ? event.block.timestamp.plus(BigInt.fromU32(604800)) : userHistory.timestampParole.plus(BigInt.fromU32(604800)) } realityCheck.currentAnswer = event.params.answer @@ -92,9 +107,29 @@ export function handleLogNewAnswer(event: LogNewAnswer): void { realityCheck.save() userHistory.save() + const oldStatus = reportedByUserHistory.status + if(reportedByUserHistory.countReportsMade >= 10 && 3*reportedByUserHistory.countReportsMadeAndRespondedYes > 2*reportedByUserHistory.countReportsMade){ + reportedByUserHistory.status = "GoodSamaritan" + } else if(reportedByUserHistory.countReportsMade >= 3 && 3*reportedByUserHistory.countReportsMadeAndRespondedYes > reportedByUserHistory.countReportsMade){ + reportedByUserHistory.status = "NeighborhoodWatch" + } else if(reportedByUserHistory.countReportsMade >= 10 && 3*reportedByUserHistory.countReportsMadeAndRespondedYes < reportedByUserHistory.countReportsMade){ + reportedByUserHistory.status = "BoyWhoCriedWolf" + } else { + reportedByUserHistory.status = "CommunityMember" + } +/* + if (reportedByUserHistory.countReportsMadeAndRespondedYes > 3){ + log.warning('reportedByUserHistory.status {}, {}, {}', [oldStatus]) + reportedByUserHistory.timestampStatusUpdated = event.block.timestamp + }*/ + + if (oldStatus != reportedByUserHistory.status){ + reportedByUserHistory.timestampStatusUpdated = event.block.timestamp + } + reportedByUserHistory.save() - if(reportedByUserHistory.countReportsMadeAndResponded > 0){ + if(reportedByUserHistory.countReportsMadeAndRespondedYes > 0){ let janny = Janny.load(userHistory.group) if(!janny){ janny = new Janny(userHistory.group) @@ -105,13 +140,17 @@ export function handleLogNewAnswer(event: LogNewAnswer): void { let sheriffOld = janny.sheriff let deputySheriffOld = janny.deputySheriff + if((sheriffOld == reportedByUserHistory.id)||(deputySheriffOld == reportedByUserHistory.id)){ + return + } + if (!sheriffOld){//event.transaction.from.toHexString() + params[2] + params[1]+params[5]) - janny.sheriff = moderationInfo.reportedBy + janny.sheriff = reportedByUserHistory.id janny.blocknumberLastUpdatedSheriff = event.block.number janny.timestampLastUpdatedSheriff = event.block.timestamp janny.save() } else if (!deputySheriffOld){ - janny.deputySheriff = moderationInfo.reportedBy + janny.deputySheriff = reportedByUserHistory.id janny.timestampLastUpdatedDeputySheriff = event.block.timestamp janny.blocknumberLastUpdatedDeputySheriff = event.block.number janny.save() @@ -122,7 +161,8 @@ export function handleLogNewAnswer(event: LogNewAnswer): void { log.error('sheriff missing {}',[non_null_sheriff]); return; } - if(sheriff.countReportsMadeAndResponded < reportedByUserHistory.countReportsMadeAndResponded){ + + if(sheriff.countReportsMadeAndRespondedYes < reportedByUserHistory.countReportsMadeAndRespondedYes){ janny.sheriff = reportedByUserHistory.id janny.blocknumberLastUpdatedSheriff = event.block.number janny.timestampLastUpdatedSheriff = event.block.timestamp @@ -134,7 +174,7 @@ export function handleLogNewAnswer(event: LogNewAnswer): void { log.error('deputy sheriff missing {}',[non_null_deputySheriff]); return; } - if(deputySheriff.countReportsMadeAndResponded < reportedByUserHistory.countReportsMadeAndResponded){ + if(deputySheriff.countReportsMadeAndRespondedYes < reportedByUserHistory.countReportsMadeAndRespondedYes){ janny.deputySheriff = reportedByUserHistory.id janny.blocknumberLastUpdatedDeputySheriff = event.block.number janny.timestampLastUpdatedDeputySheriff = event.block.timestamp @@ -155,7 +195,7 @@ export function handleLogNewQuestion(event: LogNewQuestion): void { return; let group = Group.load(event.transaction.from.toHexString() + params[2] + params[5]); - if (group === null) { + if (!group) { group = new Group(event.transaction.from.toHexString() + params[2] + params[5]); group.groupID = params[5]; group.platform = params[2]; @@ -171,29 +211,33 @@ export function handleLogNewQuestion(event: LogNewQuestion): void { user.userID = params[1]; user.username = params[0]; user.save(); + } else { + user.username = params[0]; + user.save(); } let moderationInfo = new ModerationInfo(event.params.question_id.toHexString()); moderationInfo.moderationType = event.params.template_id; - moderationInfo.reportedBy = event.transaction.from.toHexString()+params[2] + params[9] +params[5] - if (!UserHistory.load(moderationInfo.reportedBy)){ - let reportedByUser = new UserHistory(event.transaction.from.toHexString() + params[2] + params[9]+params[5]) - reportedByUser.countBrokeRulesArbitrated = 0 - reportedByUser.countBrokeRulesOptimisticAndArbitrated = 0 - reportedByUser.countReportsMade = 0 - reportedByUser.countReportsMadeAndResponded = 0 - reportedByUser.timestampLastReport = BigInt.fromU32(0) - reportedByUser.timestampLastUpdated = BigInt.fromU32(0) - reportedByUser.timestampParole = BigInt.fromU32(0) - reportedByUser.user = event.transaction.from.toHexString() + params[2] + params[9] - reportedByUser.group = group.id - reportedByUser.save() - if(!User.load(reportedByUser.user)){ - let userReportedBy = new User(reportedByUser.user) - userReportedBy.userID = params[9] - userReportedBy.username = params[0] - userReportedBy.save() - } + moderationInfo.reportedBy = event.transaction.from.toHexString()+params[2] + params[9] + let userReportedBy = User.load(moderationInfo.reportedBy); + if (!userReportedBy) { + userReportedBy = new User(moderationInfo.reportedBy); + userReportedBy.userID = params[9]; + userReportedBy.save(); + } + let reportedByUserHistory = UserHistory.load(moderationInfo.reportedBy+params[5]) + if (!reportedByUserHistory){ + reportedByUserHistory = new UserHistory(moderationInfo.reportedBy+params[5]) + reportedByUserHistory.status = "CommunityMember" + reportedByUserHistory.user = moderationInfo.reportedBy + reportedByUserHistory.group = group.id + reportedByUserHistory.countReportsMade = 0 + reportedByUserHistory.countBrokeRulesOptimistic = 0 + reportedByUserHistory.countBrokeRulesArbitrated = 0 + reportedByUserHistory.timestampLastUpdated = BigInt.fromU32(0) + reportedByUserHistory.countReportsMadeAndRespondedYes = 0 + reportedByUserHistory.timestampStatusUpdated = BigInt.fromU32(0) + reportedByUserHistory.countReportsMadeAndDisputedYes = 0 } moderationInfo.deadline = event.params.opening_ts.plus(event.params.timeout); moderationInfo.timeout = event.params.timeout; @@ -206,13 +250,15 @@ export function handleLogNewQuestion(event: LogNewQuestion): void { let reportedUser = UserHistory.load(event.transaction.from.toHexString() + params[2] + params[1]+params[5]) if (!reportedUser){ reportedUser = new UserHistory(event.transaction.from.toHexString() + params[2] + params[1]+params[5]) + reportedUser.status = "CommunityMember" reportedUser.countBrokeRulesArbitrated = 0 - reportedUser.countBrokeRulesOptimisticAndArbitrated = 0 + reportedUser.countBrokeRulesOptimistic = 0 reportedUser.countReportsMade = 0 - reportedUser.countReportsMadeAndResponded = 0 + reportedUser.countReportsMadeAndRespondedYes = 0 + reportedUser.countReportsMadeAndDisputedYes = 0 + reportedUser.timestampStatusUpdated = BigInt.fromU32(0) reportedUser.timestampLastReport = BigInt.fromU32(0) reportedUser.timestampLastUpdated = BigInt.fromU32(0) - reportedUser.timestampParole = BigInt.fromU32(0) reportedUser.user = event.transaction.from.toHexString() + params[2] + params[1] reportedUser.group = group.id reportedUser.save() @@ -222,18 +268,7 @@ export function handleLogNewQuestion(event: LogNewQuestion): void { moderationInfo.save(); - let reportedByUserHistory = UserHistory.load(moderationInfo.reportedBy+params[5]) - if (!reportedByUserHistory){ - reportedByUserHistory = new UserHistory(moderationInfo.reportedBy+params[5]) - reportedByUserHistory.user = moderationInfo.reportedBy - reportedByUserHistory.group = group.id - reportedByUserHistory.countReportsMade = 0 - reportedByUserHistory.countBrokeRulesOptimisticAndArbitrated = 0 - reportedByUserHistory.countBrokeRulesArbitrated = 0 - reportedByUserHistory.timestampParole = BigInt.fromU32(0) - reportedByUserHistory.timestampLastUpdated = BigInt.fromU32(0) - reportedByUserHistory.countReportsMadeAndResponded = 0 - } + reportedByUserHistory.countReportsMade++ reportedByUserHistory.timestampLastReport = event.block.timestamp reportedByUserHistory.save() diff --git a/subgraph/subgraph.yaml b/subgraph/subgraph.yaml index 5583225..a5bc922 100644 --- a/subgraph/subgraph.yaml +++ b/subgraph/subgraph.yaml @@ -34,9 +34,9 @@ dataSources: name: Realitio_v2_1_ArbitratorWithAppeals network: goerli #xdai source: - address: "0xAa5681047a16F163391377Fd9f78e84355Cc9696" #goerli "0xAa5681047a16F163391377Fd9f78e84355Cc9696" #xdai 0x2a2bAB2C2D4eB5007b0389720b287D4D19dc4001# xdai me "0x36a4e90568ce270aB671F55547C5EAe428B6c03A" + address: "0xAa5681047a16F163391377Fd9f78e84355Cc9696" #goerli "0xAa5681047a16F163391377Fd9f78e84355Cc9696" #xdai 0x17BBc6405e3Cbc452A993E5C23e460980BBeC83F abi: Realitio_v2_1_ArbitratorWithAppeals - startBlock: 8034496 #7913496 #goerli, xdai 23143918 + startBlock: 8034496 #8034496 #goerli, xdai 23143918 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -60,9 +60,9 @@ dataSources: name: KlerosLiquid network: goerli #xdai source: - address: "0x1128eD55ab2d796fa92D2F8E1f336d745354a77A" # goerli 0x209469C921db9d5Bd77084370e80B63d5cdD63C1 + address: "0x1128eD55ab2d796fa92D2F8E1f336d745354a77A" # "0x1128eD55ab2d796fa92D2F8E1f336d745354a77A" # goerli # gnosis 0x9C1dA9A04925bDfDedf0f6421bC7EEa8305F9002 abi: KlerosLiquid - startBlock: 7913496 #7913496 #goerli, xdai 23143918 + startBlock: 8034496 #goerli, 8034496 xdai 23143918 mapping: kind: ethereum/events apiVersion: 0.0.6 From f928d670df919ce10b9ca652eb56ab304fb488f4 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Thu, 15 Dec 2022 22:09:45 -0700 Subject: [PATCH 011/111] fix(cron): bug fixes --- lib/cron.ts | 26 +++++++++---------- lib/telegram/commands/joinfed.ts | 24 +++++++++++++---- lib/telegram/commands/newfed.ts | 2 +- lib/telegram/commands/setChannel.ts | 24 ++++++++++++----- subgraph/schema.graphql | 2 +- .../Realitio_v2_1_ArbitratorWithAppeals.ts | 10 ++++--- subgraph/src/reality-ethv-30.ts | 7 +++++ 7 files changed, 64 insertions(+), 31 deletions(-) diff --git a/lib/cron.ts b/lib/cron.ts index c467a70..320cf63 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -40,9 +40,8 @@ const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCo console.log(history.last_timestamp) console.log(history.last_block) // hardcode values for tests - history.last_timestamp = 1670992400 - history.last_block = 8131483 - const graphSyncingPeriod = 300; + //history.last_timestamp = 1671166007 + //history.last_block = 8143190 const timestampNew = currentTime const timestampLastUpdated = history.last_timestamp const reports = {}; @@ -58,7 +57,7 @@ const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCo // jannies sheriff // jannies deputysheriff const lastPageUpdated = 0; - const queryModeration = getQuery(lastPageUpdated, timestampLastUpdated, botaddress, timestampNew, graphSyncingPeriod) + const queryModeration = getQuery(lastPageUpdated, timestampLastUpdated, botaddress, timestampNew) //console.log(queryModeration); //console.log('graphtime'); @@ -147,7 +146,7 @@ const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCo bot.sendMessage(settings.channelID, `The [report](${realityURL}) is finalized.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); // finalize - handleTelegramUpdate(db, bot, settings, data.moderationInfo, timestampNew, data.finalRuling === "0x0000000000000000000000000000000000000000000000000000000000000001", true, false); + handleTelegramUpdate(db, bot, settings, data.moderationInfo, timestampNew, data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001", true, false); } catch(e){ console.log(e) } @@ -307,23 +306,22 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, } const ban_level_current = calculateHistory.length - console.log(ban_level_current) - console.log(ban_level_history) - console.log(calculateHistory) if (restrict){ // TODO federation subscriptions const groups = settings.federation_id? getGroupsInAndFollowingFederation(db,'telegram',settings.federation_id) : [moderationInfo.UserHistory.group.groupID] - console - if (ban_level_current > ban_level_history){ + if (ban_level_current >= ban_level_history){ const parole = calcPenalty(ban_level_current,timestampNew) if(finalize){ // if message reported timestamp is before the most recent finalized ban / penality, users deserve a second chance, no action taken // philosophy is only escalate the penalties after the user is warned with a temporary ban. // this report changed penalties, recalculate all - for (const group of groups) - bot.banChatMember(group, moderationInfo.UserHistory.user.userID, parole); + //console.log(moderationInfo.UserHistory.group.groupID) + for (const group of groups){ + //console.log(group) + bot.banChatMember(group, moderationInfo.UserHistory.user.userID, {until_date: parole}); + } } else if(!finalize){ const options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false, until_date: parole}; for (const group of groups){ @@ -353,7 +351,7 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, } } -const getQuery = (lastPageUpdated: number, timestampLastUpdated: number, botaddress: string, timestampNew: number, graphSyncingPeriod: number): string => { +const getQuery = (lastPageUpdated: number, timestampLastUpdated: number, botaddress: string, timestampNew: number): string => { const moderationInfoContent = ` id message messageBackup @@ -401,7 +399,7 @@ return `{ realityQuestionUnansweredFinalized: moderationInfos(first: 1000, skip: ${lastPageUpdated*1000}, where: {deadline_gt: ${timestampLastUpdated}, deadline_lt: ${timestampNew}, reality: null, askedBy: "${botaddress}"}) { ${moderationInfoContent} } - realityQuestionAnsweredFinalized: realityChecks(first: 1000, skip: ${lastPageUpdated*1000}, where: {deadline_gt: ${timestampLastUpdated}, dispute: null, deadline_lt: ${timestampNew + graphSyncingPeriod}, moderationInfo_: {askedBy: "${botaddress}"}}) { + realityQuestionAnsweredFinalized: realityChecks(first: 1000, skip: ${lastPageUpdated*1000}, where: {deadline_gt: ${timestampLastUpdated}, dispute: null, deadline_lt: ${timestampNew}, moderationInfo_: {askedBy: "${botaddress}"}}) { id timestampLastUpdated currentAnswer diff --git a/lib/telegram/commands/joinfed.ts b/lib/telegram/commands/joinfed.ts index 1c1642d..1ca6e4e 100644 --- a/lib/telegram/commands/joinfed.ts +++ b/lib/telegram/commands/joinfed.ts @@ -2,6 +2,13 @@ import * as TelegramBot from "node-telegram-bot-api"; import { groupSettings } from "../../../types"; import {joinFederation,followFederation,getFederationName} from "../../db"; import langJson from "../assets/lang.json"; +const NodeCache = require( "node-cache" ); +const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); +var myBot; + +myCache.on("expired",function(key,value){ + myBot.deleteMessage(value, key); + }); /* * /joinfed @@ -11,19 +18,26 @@ const regexp = /\/joinfed\s?(.+)?/ const callback = async (db: any, settings: groupSettings, bot: any, botId: string, msg: any, match: string[]) => { try{ if (!match[1]){ - bot.sendMessage(settings.channelID, `Please specify a federation eg. \`/joinfed \`.`,msg.chat.is_forum? { + const resp = bot.sendMessage(settings.channelID, `Please specify a federation eg. \`/joinfed \`.`,msg.chat.is_forum? { message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); + myCache.set(resp.message_id, msg.chat.id) } else{ const name = getFederationName(db, 'telegram',String(Number(match[1]))) - if (!name) - bot.sendMessage(settings.channelID, `Federation not found. The federation id of any group can be found by sending \`/fedinfo\` in a group.`,msg.chat.is_forum? { + if (!name){ + const resp = bot.sendMessage(settings.channelID, `Federation not found. The federation id of any group can be found by sending \`/fedinfo\` in a group.`,msg.chat.is_forum? { message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); - else if (msg.from.id === match[1]) + myCache.set(resp.message_id, msg.chat.id) + } + else if (msg.from.id === match[1]){ + bot.sendMessage(settings.channelID, `Your group is now a member of the *${name}* Federation. Reputation extends through all member communities.`,msg.chat.is_forum? {message_thread_id: msg.message_thread_id,parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); joinFederation(db, 'telegram', String(msg.chat.id), match[1]) - else + } + else{ + bot.sendMessage(settings.channelID, `Your group is now a following of the *${name}* Federation. The reputation of users in groups of the federation extend to this group.`,msg.chat.is_forum? {message_thread_id: msg.message_thread_id,parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); followFederation(db, 'telegram', String(msg.chat.id), match[1]) + } } } catch(e){ console.log(e) diff --git a/lib/telegram/commands/newfed.ts b/lib/telegram/commands/newfed.ts index 7990056..ea1ff97 100644 --- a/lib/telegram/commands/newfed.ts +++ b/lib/telegram/commands/newfed.ts @@ -64,7 +64,7 @@ const callback = async (db: any, settings: groupSettings, bot: any, botId: strin return } else{ const name = match[1].substring(0,65) - setFederation(db, 'telegram',name, msg.from.id) + setFederation(db, 'telegram',name, String(msg.from.id)) bot.sendMessage(settings.channelID, `Your new federation is called *${match[1].substring(0,65)}* with id ${msg.from.id}. You can add groups to your federation by sending \`/joinfed ${msg.from.id}\` in each group.`,msg.chat.is_forum? { message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); diff --git a/lib/telegram/commands/setChannel.ts b/lib/telegram/commands/setChannel.ts index 2bc0c69..fd1e353 100644 --- a/lib/telegram/commands/setChannel.ts +++ b/lib/telegram/commands/setChannel.ts @@ -3,7 +3,13 @@ import {groupSettings} from "../../../types"; import {setChannelID, setInviteURLChannel} from "../../db"; import {validateUrl} from "./setRules"; import langJson from "../assets/lang.json"; +const NodeCache = require( "node-cache" ); +const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); +var myBot; +myCache.on("expired",function(key,value){ + myBot.deleteMessage(value, key); + }); /* * /setchannel [public channel name] */ @@ -16,18 +22,21 @@ const callback = async (db: any, settings: groupSettings, bot: TelegramBot, botI return const newmatch = msg.text.match(regexpFull); if (!newmatch || newmatch.length < 2){ - bot.sendMessage(msg.chat.id, `/setchannel must be followed by a channel id. [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpnotifications) me if you need more help : )`, {parse_mode: "Markdown", disable_web_page_preview: true}); + const resp = await bot.sendMessage(msg.chat.id, `/setchannel must be followed by a channel id. [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpnotifications) me if you need more help : )`, {parse_mode: "Markdown", disable_web_page_preview: true}); + myCache.set(resp.message_id, msg.chat.id) return; } try{ const channel = await bot.getChat(newmatch[1]); if(channel.type !== "channel"){ - await bot.sendMessage(msg.chat.id, '/setchannel must be followed by a valid channel.'); + const resp = await bot.sendMessage(msg.chat.id, '/setchannel must be followed by a valid channel.'); + myCache.set(resp.message_id, msg.chat.id) return; } } catch(e){ try{ - bot.sendMessage(msg.chat.id, `${newmatch[1]} is not a valid channel.`); + const resp = await bot.sendMessage(msg.chat.id, `${newmatch[1]} is not a valid channel.`); + myCache.set(resp.message_id, msg.chat.id) } catch(e){ console.log(e) } @@ -35,16 +44,19 @@ const callback = async (db: any, settings: groupSettings, bot: TelegramBot, botI } const channelUser = await bot.getChatMember(newmatch[1], String(msg.from.id)); if(channelUser.status !== "administrator" && channelUser.status !== "creator"){ - await bot.sendMessage(msg.chat.id, 'You are not an authorized admin of the channel.'); + const resp = await bot.sendMessage(msg.chat.id, 'You are not an authorized admin of the channel.'); + myCache.set(resp.message_id, msg.chat.id) return; } const channelUserSusie = await bot.getChatMember(newmatch[1], botId); if (channelUserSusie.status !== "administrator"){ - bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {caption: langJson[settings.lang].errorAdminRights}); + const resp = await bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {caption: langJson[settings.lang].errorAdminRights}); + myCache.set(resp.message_id, msg.chat.id) return; } if(!channelUserSusie.can_invite_users){ - bot.sendMessage(msg.chat.id, 'Susie must be able to invite users to the channel.'); + const resp = await bot.sendMessage(msg.chat.id, 'Susie must be able to invite users to the channel.'); + myCache.set(resp.message_id, msg.chat.id) return; } const invite_url_channel = await bot.exportChatInviteLink(newmatch[1]); diff --git a/subgraph/schema.graphql b/subgraph/schema.graphql index cca1f3e..2a6797a 100644 --- a/subgraph/schema.graphql +++ b/subgraph/schema.graphql @@ -38,7 +38,7 @@ type ModerationInfo @entity(immutable: true){ messageBackup: String! reportedBy: UserHistory! askedBy: Bytes! - deadline: BigInt + deadline: BigInt! timeout: BigInt! UserHistory: UserHistory! dispute: ModerationDispute @derivedFrom(field: "moderationInfo") diff --git a/subgraph/src/Realitio_v2_1_ArbitratorWithAppeals.ts b/subgraph/src/Realitio_v2_1_ArbitratorWithAppeals.ts index f5edb85..bca570b 100644 --- a/subgraph/src/Realitio_v2_1_ArbitratorWithAppeals.ts +++ b/subgraph/src/Realitio_v2_1_ArbitratorWithAppeals.ts @@ -12,15 +12,17 @@ import { export function handleDisputeIDToQuestionID( event: DisputeIDToQuestionIDEvent ): void { - let moderationDispute = new ModerationDispute(event.params._disputeID.toHexString()); - moderationDispute.moderationInfo = event.params._questionID.toHexString() - moderationDispute.timestampLastUpdated = event.block.timestamp - moderationDispute.save(); let realityCheck = RealityCheck.load(event.params._questionID.toHexString()) if (!realityCheck){ log.error('no reality check found for dispute. {}', [event.params._questionID.toHexString()]) return } + + let moderationDispute = new ModerationDispute(event.params._disputeID.toHexString()); + moderationDispute.moderationInfo = event.params._questionID.toHexString() + moderationDispute.timestampLastUpdated = event.block.timestamp + moderationDispute.save(); + realityCheck.dispute = event.params._disputeID.toHexString() realityCheck.save() } diff --git a/subgraph/src/reality-ethv-30.ts b/subgraph/src/reality-ethv-30.ts index 2d7a311..20dd434 100644 --- a/subgraph/src/reality-ethv-30.ts +++ b/subgraph/src/reality-ethv-30.ts @@ -13,6 +13,10 @@ export function handleLogNotifyOfArbitrationRequest(event: LogNotifyOfArbitratio log.error('moderation info not found. {}',[event.params.question_id.toHexString()]) return } + + if(moderationInfo.deadline < event.block.timestamp) + return; + let userHistory = UserHistory.load(moderationInfo.UserHistory) if (!userHistory){ log.error('user history not found. {}',[moderationInfo.UserHistory]) @@ -64,6 +68,9 @@ export function handleLogNewAnswer(event: LogNewAnswer): void { return } + if(moderationInfo.deadline < event.block.timestamp) + return; + let realityCheck = RealityCheck.load(event.params.question_id.toHexString()) if (!realityCheck) realityCheck = new RealityCheck(event.params.question_id.toHexString()) From 00b48341aaa24aa84153965e1bb6c01f3da8c1e6 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Tue, 20 Dec 2022 23:45:40 -0700 Subject: [PATCH 012/111] feat: big update --- README.md | 6 +- ecosystem.config.js | 19 +- lib/create-db.ts | 2 + lib/cron.ts | 102 +++++---- lib/db.ts | 195 ++++++++++++++---- lib/telegram/assets/lang.json | 25 +-- lib/telegram/commands/addEvidence.ts | 65 +++--- lib/telegram/commands/addEvidenceHelp.ts | 6 +- lib/telegram/commands/captcha.ts | 14 +- lib/telegram/commands/fedinfo.ts | 79 +++---- lib/telegram/commands/getAccount.ts | 4 +- lib/telegram/commands/getChannel.ts | 27 ++- lib/telegram/commands/getReports.ts | 90 +++++--- lib/telegram/commands/getRules.ts | 14 +- lib/telegram/commands/greeting.ts | 18 +- lib/telegram/commands/help.ts | 120 +++++------ lib/telegram/commands/joinfed.ts | 27 ++- lib/telegram/commands/leavefed.ts | 4 +- lib/telegram/commands/newfed.ts | 27 ++- lib/telegram/commands/report.ts | 64 ++++-- lib/telegram/commands/setChannel.ts | 46 +++-- lib/telegram/commands/setChannelFed.ts | 93 +++++++++ lib/telegram/commands/setLanguage.ts | 22 +- lib/telegram/commands/setRules.ts | 18 +- lib/telegram/commands/socialConsensus.ts | 13 +- lib/telegram/commands/start.ts | 96 +++++++-- .../commands/toggleAdminReportable.ts | 4 +- lib/telegram/commands/toggleCaptcha.ts | 6 +- lib/telegram/commands/toggleWelcome.ts | 16 +- lib/telegram/commands/welcome.ts | 4 +- lib/telegram/index.ts | 174 +++++++++++----- 31 files changed, 922 insertions(+), 478 deletions(-) create mode 100644 lib/telegram/commands/setChannelFed.ts diff --git a/README.md b/README.md index ecd7c63..cc4c876 100644 --- a/README.md +++ b/README.md @@ -37,14 +37,12 @@ yarn pm2:delete-all Command | Description | Group Admin | Normal user --- | --- | --- | --- -/newaccount | Creates a new bot account | ✅ | ❌ -/setaccount [address]| Sets the bot address of the current chat | ✅ | ❌ /getaccount | Returns the bot address of the current chat | ✅ | ✅ /setrules | `[by reply/username/id]` Set chat rules from the quoted message | ✅ | ❌ /setrules [url] | Set chat rules from the specified url | ✅ | ❌ -/getrules | Get chat rules | ✅ | ✅ +/rules | Get chat rules | ✅ | ✅ /report | `[by reply/username/id]` Reports a user | ✅ | ❌ -/addevidence [questionId] | `[by reply/username/id]` Adds the quoted message as evidence to the arbitrator of `questionId` | ✅ | ✅ +/evidence [questionId] | `[by reply/username/id]` Adds the quoted message as evidence to the arbitrator of `questionId` | ✅ | ✅ ### Attribution diff --git a/ecosystem.config.js b/ecosystem.config.js index b701e14..b0e3624 100644 --- a/ecosystem.config.js +++ b/ecosystem.config.js @@ -5,25 +5,12 @@ module.exports = { args: 'start-telegram-bot', interpreter: '/bin/bash', log_date_format : 'YYYY-MM-DD HH:mm Z', - watch: true, + watch: false, ignore_watch: ['\.git', 'node_modules', 'database\.db', 'database\.db-journal'], env: { NODE_ENV: 'development' } - }, { - name: 'realitio-reporting', - script: 'yarn', - args: '--cwd ../realitio-reporting-bot/ start', - interpreter: '/bin/bash', - log_date_format : 'YYYY-MM-DD HH:mm Z', - autorestart: false, - watch: false, - ignore_watch: ['\.git', 'node_modules', 'database\.db', 'database\.db-journal'], - cron_restart: '* */1 * * *', - env: { - NODE_ENV: 'development' - } - }, + }, { name: 'moderator_cron', script: 'yarn', @@ -31,7 +18,7 @@ module.exports = { interpreter: '/bin/bash', log_date_format : 'YYYY-MM-DD HH:mm Z', autorestart: false, - watch: true, + watch: false, ignore_watch: ['\.git', 'node_modules', 'database\.db', 'database\.db-journal'], cron_restart: '* * * * *', env: { diff --git a/lib/create-db.ts b/lib/create-db.ts index c03d8d6..aec6e61 100644 --- a/lib/create-db.ts +++ b/lib/create-db.ts @@ -15,6 +15,7 @@ const Database = require('better-sqlite3'); `CREATE TABLE groups ( platform TEXT, group_id TEXT, + title TEXT, channel_id TEXT, thread_id_rules TEXT, thread_id_notifications TEXT, @@ -48,6 +49,7 @@ const Database = require('better-sqlite3'); report_allowance INTEGER, evidence_allowance INTEGER, timestamp_refresh INTEGER, + limit_level INTEGER, PRIMARY KEY (platform, group_id, user_id))` ); diff --git a/lib/cron.ts b/lib/cron.ts index 320cf63..fd33c1a 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -1,5 +1,5 @@ require('dotenv').config() -import {openDb, getGroupSettings, getRule, getCron, getTimestampFinalized, getFederatedFollowingBanHistory, getLocalBanHistory, getFederatedBanHistory, setCron, getGroupsInAndFollowingFederation, getReportMessageTimestampAndActive, setReport} from "./db"; +import {openDb, getGroupSettings, getRule, getCron, getFederationChannel, getFederatedFollowingBanHistory, getLocalBanHistory, getFederatedBanHistory, setCron, getGroupsInAndFollowingFederation, getReportMessageTimestampAndActive, setReport} from "./db"; import request from "graphql-request"; import {BigNumber} from "ethers"; import TelegramBot from "node-telegram-bot-api"; @@ -14,7 +14,7 @@ const realitio_bot = require('./realitioReporting') const myCache = new NodeCache( { stdTTL: 900, checkperiod: 1200 } ); const db = openDb(); const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: false, testEnvironment: true}); -const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCount: true}); +const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCount: true}); // Only need DB for // - channelID // - finalizedReportCount @@ -23,7 +23,7 @@ const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCo // - rules (for new reports) (async ()=> { - const botaddress = await (await new Wallet(process.env.PRIVATE_KEY)).address; + const botaddress = (await new Wallet(process.env.PRIVATE_KEY)).address; var history = getCron(db) const web3 = new Web3(process.env.WEB3_PROVIDER_URL) const privateKey = process.env.PRIVATE_KEY @@ -40,8 +40,8 @@ const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCo console.log(history.last_timestamp) console.log(history.last_block) // hardcode values for tests - //history.last_timestamp = 1671166007 - //history.last_block = 8143190 + //history.last_timestamp = 1671604752 + //history.last_block = 8173468 const timestampNew = currentTime const timestampLastUpdated = history.last_timestamp const reports = {}; @@ -78,7 +78,8 @@ const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCo const message = (data.finalRuling === 2)? 'broke the rules' : 'did not break the rules' //console.log(data.finalRuling) try{ - bot.sendMessage(settings.channelID, `The [dispute](${disputeURL}) over *${data.moderationInfo.UserHistory.user.username}*'s [message](${msgLink}) ([backup](${data.moderationInfo.messageBackup})) resolved. *${data.moderationInfo.UserHistory.user.username}* ${message}`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `The [dispute](${disputeURL}) over *${data.moderationInfo.UserHistory.user.username}*'s [message](${msgLink}) ([backup](${data.moderationInfo.messageBackup})) resolved. *${data.moderationInfo.UserHistory.user.username}* ${message}`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + //bot.sendMessage(process.env.JUSTICE_LEAGUE, `The [dispute](${disputeURL}) over *${data.moderationInfo.UserHistory.user.username}*'s [message](${msgLink}) ([backup](${data.moderationInfo.messageBackup})) resolved. *${data.moderationInfo.UserHistory.user.username}* ${message}`, {parse_mode: 'Markdown'}); handleTelegramUpdate(db, bot,settings, data.moderationInfo,timestampNew, data.finalRuling === 2, true, true); } catch(e){ console.log(e) @@ -96,8 +97,10 @@ const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCo const disputeURL = `https://resolve.kleros.io/cases/${BigNumber.from(data.id).toNumber()}`; // settings[1] language try{ - //TODO - bot.sendMessage(settings.channelID, `The dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'} If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `The dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(process.env.JUSTICE_LEAGUE, `The dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if(settings.federation_id) + queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `The dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); } catch(e){ console.log(e) } @@ -109,7 +112,10 @@ const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCo const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; const disputeURL = `https://resolve.kleros.io/cases/${BigNumber.from(data.id).toNumber()}`; try{ - bot.sendMessage(settings.channelID, `Arbitration is requested for the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})). Consequences of the report are lifted for the duration of the [dispute](${disputeURL}) (on Gnosis Chain).`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `Arbitration is requested for the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})). Consequences of the report are lifted for the duration of the [dispute](${disputeURL}) (on Gnosis Chain).`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(process.env.JUSTICE_LEAGUE, `Arbitration is requested for the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})). Consequences of the report are lifted for the duration of the [dispute](${disputeURL}) (on Gnosis Chain).`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if(settings.federation_id) + queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `Arbitration is requested for the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})). Consequences of the report are lifted for the duration of the [dispute](${disputeURL}) (on Gnosis Chain).`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); handleTelegramUpdate(db, bot,settings, data.moderationInfo,timestampNew, false, false, true); } catch (e){ console.log(e) @@ -118,9 +124,15 @@ const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCo for (const data of moderationActions.disputesAppealFunded) { const settings = validate(data.moderationInfo.UserHistory.group.groupID); + const msgLink = data.moderationInfo.message; + const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; + const disputeURL = `https://resolve.kleros.io/cases/${BigNumber.from(data.id).toNumber()}`; // settings[1] language try{ - bot.sendMessage(settings.channelID, "An appeal has been funded",settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `An appeal has been funded in the dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})). Juror's voted in the previous round that *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. The contribution funded ${data.RulingFunded == data.currentRuling ? 'the previous round winning option': 'a different option that the previous round'}. If you think the funded option is incorrect, you can win some of their deposit by funding the correct side of the [appeal](${disputeURL})`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(process.env.JUSTICE_LEAGUE, `An appeal has been funded in the dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})). Juror's voted in the previous round that *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. The contribution funded ${data.RulingFunded == data.currentRuling ? 'the previous round winning option': 'a different option that the previous round'}. If you think the funded option is incorrect, you can win some of their deposit by funding the correct side of the [appeal](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if(settings.federation_id) + queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `An appeal has been funded in the dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})). Juror's voted in the previous round that *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. The contribution funded ${data.RulingFunded == data.currentRuling ? 'the previous round winning option': 'a different option that the previous round'}. If you think the funded option is incorrect, you can win some of their deposit by funding the correct side of the [appeal](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); } catch(e){ console.log(e) } @@ -144,7 +156,8 @@ const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCo //bot.sendMessage(settings[0], `The reality question ${data.id} is finalized with ${data.currentAnswer}`); const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; - bot.sendMessage(settings.channelID, `The [report](${realityURL}) is finalized.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); + //bot.sendMessage(settings.channelID, `The [report](${realityURL}) is finalized.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); + //bot.sendMessage(process.env.JUSTICE_LEAGUE, `The [report](${realityURL}) is finalized.`, {parse_mode: 'Markdown'}); // finalize handleTelegramUpdate(db, bot, settings, data.moderationInfo, timestampNew, data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001", true, false); } catch(e){ @@ -163,7 +176,11 @@ const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCo //console.log(data) //console.log(data.moderationInfo.UserHistory) //console.log('answered') - bot.sendMessage(settings.channelID, `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) violate the [rules](${data.moderationInfo.rules})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true}); + + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) violate the [rules](${data.moderationInfo.rules})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(process.env.JUSTICE_LEAGUE, `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) violate the [rules](${data.moderationInfo.rules})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if(settings.federation_id) + queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) violate the [rules](${data.moderationInfo.rules})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); handleTelegramUpdate(db, bot,settings, data.moderationInfo,timestampNew, data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001", false, false); } catch(e){ console.log(e) @@ -176,9 +193,10 @@ const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCo const settings = validate(data.group.groupID); // settings[1] language try{ - const sherrif = await bot.getChatMember(data.group.groupID, data.sheriff.user.userID) + const sherrif = await queue.add(async () => {try{const val = await bot.getChatMember(data.group.groupID, data.sheriff.user.userID) + return val}catch{}}); //console.log(sherrif) - queue.add(() => bot.sendMessage(settings.channelID, `There's a new sheriff in town 👑🥇🤠[${sherrif.user.username}](tg://user?id=${sherrif.user.id})🤠🥇👑`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `There's a new sheriff in town 👑🥇🤠[${sherrif.user.username}](tg://user?id=${sherrif.user.id})🤠🥇👑`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); } catch(e){ console.log(e) } @@ -188,8 +206,9 @@ const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCo const settings = validate(data.group.groupID); // settings[1] language try{ - const deputysherrif = await bot.getChatMember(data.group.groupID, data.deputySheriff.user.userID) - bot.sendMessage(settings.channelID, `There's a new deputy sheriff in town 🥈[${deputysherrif.user.username}](tg://user?id=${deputysherrif.user.id})🥈`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); + const deputysherrif = await queue.add(async () => {try{const val = await bot.getChatMember(data.group.groupID, data.deputySheriff.user.userID) + return val}catch{}}) + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `There's a new deputy sheriff in town 🥈[${deputysherrif.user.username}](tg://user?id=${deputysherrif.user.id})🥈`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); } catch(e){ console.log(e) } @@ -199,7 +218,8 @@ const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCo const settings = validate(data.group.groupID); // settings[1] language try{ - const userUpdate = await bot.getChatMember(data.group.groupID, data.user.userID) + const userUpdate = await queue.add(async () => {try{const val = await bot.getChatMember(data.group.groupID, data.user.userID) + return val}catch{}}) let message = "" if (data.status === "GoodSamaritan"){ message = "🎖 ***Good Samaritan Award***🎖\n\nThe Good Samaritan award is this group's highest honor, given to members who performed exemplary deeds of service for their group or their fellow members. Thank you for your service 🙏" @@ -209,7 +229,7 @@ const queue = new PQueue({intervalCap: 25, interval: 1000,carryoverConcurrencyCo "Have you ever heard of the fable of 💩 the boy who cried wolf 💩?\n\nBe careful, too many unanswered reports could hurt your reputation, " } if(data.status !== "CommunityMember") - bot.sendMessage(settings.channelID, `${message} [${userUpdate.user.username}](tg://user?id=${userUpdate.user.id})`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `${message} [${userUpdate.user.username}](tg://user?id=${userUpdate.user.id})`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); } catch(e){ console.log(e) } @@ -261,11 +281,11 @@ const validate = (chatId: string): groupSettings=> { const calcPenalty = (ban_level: number, timestamp_finalized: number): number => { if(ban_level == 1) - return timestamp_finalized + 86400 + return timestamp_finalized + 120 else if (ban_level == 2) return timestamp_finalized + 604800 else - return timestamp_finalized + 220147200 + return timestamp_finalized + 31536000 } const calcPenaltyPhrase = (ban_level: number): string => { @@ -282,22 +302,19 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, const reportInfo = getReportMessageTimestampAndActive(db, moderationInfo.id) if (!reportInfo) return; let calculateHistory = [] - - if (settings.federation_id) - calculateHistory = getFederatedBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,moderationInfo.UserHistory.group.groupID,finalize) - else { - if (settings.federation_id_following) - calculateHistory = getFederatedFollowingBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,moderationInfo.UserHistory.group.groupID,settings.federation_id_following,finalize) - else - calculateHistory = getLocalBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,moderationInfo.UserHistory.group.groupID,finalize) + if (settings.federation_id){ + calculateHistory = getFederatedBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,settings.federation_id,finalize) } + else if (settings.federation_id_following){ + calculateHistory = getFederatedFollowingBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,moderationInfo.UserHistory.group.groupID,settings.federation_id_following,finalize) + } else + calculateHistory = getLocalBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,moderationInfo.UserHistory.group.groupID,finalize) const ban_level_history = calculateHistory.length - setReport(db, moderationInfo.id,restrict,true,finalize,disputed, finalize? 0 : (restrict? timestampNew: 0), finalize? timestampNew: 0) if (settings.federation_id){ - calculateHistory = getFederatedBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,moderationInfo.UserHistory.group.groupID,finalize) + calculateHistory = getFederatedBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,settings.federation_id,finalize) } else { if (settings.federation_id_following){ calculateHistory = getFederatedFollowingBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,moderationInfo.UserHistory.group.groupID,settings.federation_id_following,finalize) @@ -311,7 +328,7 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, // TODO federation subscriptions const groups = settings.federation_id? getGroupsInAndFollowingFederation(db,'telegram',settings.federation_id) : [moderationInfo.UserHistory.group.groupID] - if (ban_level_current >= ban_level_history){ + if (ban_level_current > ban_level_history){ const parole = calcPenalty(ban_level_current,timestampNew) if(finalize){ // if message reported timestamp is before the most recent finalized ban / penality, users deserve a second chance, no action taken @@ -319,20 +336,17 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, // this report changed penalties, recalculate all //console.log(moderationInfo.UserHistory.group.groupID) for (const group of groups){ - //console.log(group) - bot.banChatMember(group, moderationInfo.UserHistory.user.userID, {until_date: parole}); + queue.add(async () => {try{await bot.banChatMember(group.group_id, moderationInfo.UserHistory.user.userID, {until_date: parole})}catch{}}); } } else if(!finalize){ const options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false, until_date: parole}; for (const group of groups){ - console.log(group) - bot.restrictChatMember(group, moderationInfo.UserHistory.user.userID, options); + queue.add(async () => {try{await bot.restrictChatMember(group.group_id, moderationInfo.UserHistory.user.userID, options)}catch{}}); } } - // TODO notify federation - bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}) for the ${calcPenaltyPhrase(ban_level_current)} ban.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}) for the ${calcPenaltyPhrase(ban_level_current)} ban.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); } else{ - bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messsageBackup})) violated the [rules](${moderationInfo.rulesUrl}). The conduct occured before *${moderationInfo.UserHistory.user.username}*'s latest effective ban. The next time ${moderationInfo.UserHistory.user.username} breaks the rules, the consequences are more severe.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messsageBackup})) violated the [rules](${moderationInfo.rulesUrl}). The conduct occured before *${moderationInfo.UserHistory.user.username}*'s latest effective ban. The next time ${moderationInfo.UserHistory.user.username} breaks the rules, the consequences are more severe.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true})}catch{}}); } } else if (ban_level_current < ban_level_history){ let liftbans = true; @@ -340,11 +354,12 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, if (ban_level.timestamp_active > 0) liftbans = false if(liftbans){ - const options = {can_send_messages: true, can_send_media_messages: true, can_send_polls: true, can_send_other_messages: true, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false}; - bot.restrictChatMember(moderationInfo.UserHistory.group.groupID, moderationInfo.UserHistory.user.userID, options); - bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}* has no other active reports. All bans are lifted.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); + const permissions = await queue.add(async () => {try{const val = await bot.getChat(moderationInfo.UserHistory.group.groupID).permissions + return val}catch{}}) + queue.add(async () => {try{await bot.restrictChatMember(moderationInfo.UserHistory.group.groupID, moderationInfo.UserHistory.user.userID, permissions)}catch{}}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}* has no other active reports. All bans are lifted.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); } else - bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}* has other active reports, and is still restricted.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}* has other active reports, and is still restricted.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); } } catch(e){ console.log(e) @@ -444,4 +459,5 @@ return `{ } } }`; -} \ No newline at end of file +} +export {calcPenalty} \ No newline at end of file diff --git a/lib/db.ts b/lib/db.ts index 48030d0..4eafb40 100644 --- a/lib/db.ts +++ b/lib/db.ts @@ -93,7 +93,6 @@ const setInviteURL = (db: any, platform: string, groupId: string, inviteUrl: str const setInviteURLChannel = (db: any, platform: string, groupId: string, inviteUrlChannel: string) => { try{ - console.log('yo'); const stmt = db.prepare( `INSERT INTO groups (platform, group_id, invite_url_channel) VALUES (?, ?, ?) @@ -101,8 +100,20 @@ const setInviteURLChannel = (db: any, platform: string, groupId: string, inviteU invite_url_channel = ?;`); const info = stmt.run(platform, groupId, inviteUrlChannel, inviteUrlChannel); } catch(err) { - console.log("db error: setInviteURLChannel"); - console.log(err); + console.log("db error: setInviteURLChannel, "+err); + } +} + +const setFederationInviteURLChannel = (db: any, platform: string, groupId: string, inviteUrlChannel: string) => { + try{ + const stmt = db.prepare( + `INSERT INTO federations (platform, group_id, invite_url_channel) + VALUES (?, ?, ?) + ON CONFLICT (platform, group_id) DO UPDATE SET + invite_url_channel = ?;`); + const info = stmt.run(platform, groupId, inviteUrlChannel, inviteUrlChannel); + } catch(err) { + console.log("db error: setFederationInviteURLChannel, "+err); } } @@ -120,9 +131,23 @@ const setChannelID = (db: any, platform: string, groupId: string, channel_id: st } } +const setFederationChannelID = (db: any, platform: string, groupId: string, channel_id: string) => { + try{ + const stmt = db.prepare( + `INSERT INTO federations (platform, group_id, notification_channel_id) + VALUES (?, ?, ?) + ON CONFLICT (platform, group_id) DO UPDATE SET + notification_channel_id = ?;`); + const info = stmt.run(platform, groupId, channel_id, channel_id); + } catch(err) { + console.log("db error: set setChannelID"); + console.log(err); + } +} + const getActiveReportsInfo = (db:any, platform: string, groupId: string) => { try{ - const stmt = db.prepare('SELECT * FROM reports WHERE group_id = ? AND platform = ? AND answered IS NOT NULL'); + const stmt = db.prepare('SELECT * FROM reports WHERE group_id = ? AND platform = ? AND answered IS NOT NULL AND NOT finalized = 1'); return stmt.all(groupId, platform); } catch(err){ console.log("db error: getDisputedReports"); @@ -130,14 +155,41 @@ const getActiveReportsInfo = (db:any, platform: string, groupId: string) => { } } +const getFederationChannel = (db: any, platform: string, federation_id: string) => { + try{ + const stmt = db.prepare( + `SELECT notification_channel_id FROM federations WHERE platform=? AND federation_id=?;`); + return stmt.get(platform, federation_id)?.notification_channel_id; + } catch(err) { + console.log("db error: getFederationChannel "+err); + } +} + const getFederationGroups = (db: any, platform: string, federation_id: string) => { try{ const stmt = db.prepare( `SELECT group_id FROM groups WHERE platform=? AND federation_id=?;`); - const info = stmt.run(platform, platform, federation_id); + return stmt.get(platform, platform, federation_id); } catch(err) { - console.log("db error: setLang"); - console.log(err); + console.log("db error: getFederationGroups "+err); + } +} + +const getGroupFederation = (db: any, platform: string, group_id: string): string | undefined => { + try{ + const stmt = db.prepare('SELECT federation_id FROM groups WHERE platform = ? AND group_id = ?'); + return stmt.get(platform, group_id)?.federation_id; + } catch(err){ + console.log("db error: getGroupFederation, "+err); + } +} + +const getGroupFederationFollowing = (db: any, platform: string, group_id: string): string | undefined => { + try{ + const stmt = db.prepare('SELECT federation_id_following FROM groups WHERE platform = ? AND group_id = ?'); + return stmt.get(platform, group_id)?.federation_id_following; + } catch(err){ + console.log("db error: getGroupFederationFollowing, "+err); } } @@ -189,8 +241,7 @@ const setThreadID = (db: any, platform: string, groupId: string, thread_id_rules thread_id_rules = ?, thread_id_notifications = ?;`); const info = stmt.run(platform, groupId, thread_id_rules, thread_id_notifications, thread_id_rules, thread_id_notifications); } catch(err) { - console.log("db error: set setThreadID"); - console.log(err); + console.log("db error: set setThreadID, "+err); } } @@ -217,11 +268,33 @@ const setThreadIDWelcome = (db: any, platform: string, groupId: string, thread_i thread_id_welcome = ?;`); const info = stmt.run(platform, groupId, thread_id_welcome, thread_id_welcome); } catch(err) { - console.log("db error: set setThreadIDWelcome"); - console.log(err); + console.log("db error: set setThreadIDWelcome, "+err); + } +} + +const setTitle = (db: any, platform: string, groupId: string, title: string) => { + try{ + const stmt = db.prepare( + `INSERT INTO groups (platform, group_id, title) + VALUES (?, ?, ?) + ON CONFLICT (platform, group_id) DO UPDATE SET + title = ?;`); + const info = stmt.run(platform, groupId, title, title); + } catch(err) { + console.log("db error: setTitle, "+err); } } +const getTitle = (db: any, platform: string, groupId: string) => { + try{ + const stmt = db.prepare( + `SELECT title + FROM groups WHERE platform=? AND group_id=? `); + const info = stmt.get(platform, groupId); + } catch(err) { + console.log("db error: setTitle, "+err); + } +} const getGroup = (db: any, platform: string, groupId: string) => { try{ @@ -232,8 +305,7 @@ const getGroup = (db: any, platform: string, groupId: string) => { ); return stmt.get(platform, groupId); } catch(err) { - console.log("db error: getGroup"); - console.log(err); + console.log("db error: getGroup, "+err); } } @@ -242,8 +314,7 @@ const getInviteURL = (db: any, platform: string, groupId: string) => { const stmt = db.prepare('SELECT invite_url FROM groups WHERE platform = ? AND group_id = ?'); return stmt.get(platform, groupId)?.invite_url || ''; } catch(err){ - console.log("db error: getInviteURL"); - console.log(err); + console.log("db error: getInviteURL, "+err); } } @@ -252,8 +323,16 @@ const getInviteURLChannel = (db: any, platform: string, groupId: string) => { const stmt = db.prepare('SELECT invite_url_channel FROM groups WHERE platform = ? AND group_id = ?'); return stmt.get(platform, groupId)?.invite_url_channel || ''; } catch(err){ - console.log("db error: getInviteURLChannel"); - console.log(err); + console.log("db error: getInviteURLChannel, "+err); + } +} + +const getFederatedInviteURLChannel = (db: any, platform: string, groupId: string) => { + try{ + const stmt = db.prepare('SELECT invite_url_channel FROM federations WHERE platform = ? AND federation_id = ?'); + return stmt.get(platform, groupId)?.invite_url_channel || ''; + } catch(err){ + console.log("db error: getFederatedInviteURLChannel, "+err); } } @@ -263,8 +342,7 @@ const existsQuestionId = (db: any, question_id: string): boolean => { const stmt = db.prepare('SELECT question_id FROM reports WHERE question_id = ?'); return stmt.get(question_id)?.length > 0; } catch(err){ - console.log("db error: existsQuestionId"); - console.log(err); + console.log("db error: existsQuestionId, "+err); } } @@ -273,8 +351,7 @@ const getFederationName = (db: any, platform: string, federation_id: string): st const stmt = db.prepare('SELECT name FROM federations WHERE platform = ? AND federation_id = ?'); return stmt.get(platform, federation_id)?.name; } catch(err){ - console.log("db error: getFederationName"); - console.log(err); + console.log("db error: getFederationName, "+err); } } @@ -335,11 +412,32 @@ const getThreadIDRules = (db: any, platform: string, groupId: string) => { const getReportsUserInfo = (db:any, platform: string, groupId: string, userId: string) => { try{ - const stmt = db.prepare('SELECT question_id, active,msgBackup, msg_id, evidenceIndex, timestamp_msg, finalized FROM reports WHERE user_id = ? AND group_id = ? AND platform = ?'); + const stmt = db.prepare('SELECT question_id, group_id, active,msgBackup, msg_id, answered, evidenceIndex, timestamp_msg, finalized FROM reports WHERE user_id = ? AND group_id = ? AND platform = ? AND answered IS NOT NULL AND ((active = 1 AND finalized = 1) OR finalized = 0)'); return stmt.all(userId, groupId, platform); } catch(err){ - console.log("db error: getReportsUserInfo"); - console.log(err); + console.log("db error: getReportsUserInfo, "+err); + } +} + +const getReportsUserInfoFederation = (db:any, platform: string, userId: string, federation_id: string, group_id_not: string) => { + try{ + const stmt = db.prepare(`SELECT question_id, group_id, answered, active,msgBackup, msg_id, evidenceIndex, timestamp_msg, finalized FROM reports WHERE user_id = ? AND platform = ? AND answered IS NOT NULL AND ((active = 1 AND finalized = 1) OR finalized = 0) AND NOT group_id = ? AND group_id IN ( + SELECT group_id + FROM groups + WHERE federation_id = ? AND platform = ? + )`); + return stmt.all(userId, platform,group_id_not,federation_id,platform); + } catch(err){ + console.log("db error: getReportsUserInfoFederation, "+err); + } +} + +const getReportsUserInfoActive = (db:any, platform: string, groupId: string, userId: string) => { + try{ + const stmt = db.prepare('SELECT question_id, active,msgBackup, msg_id, evidenceIndex, timestamp_msg, finalized FROM reports WHERE user_id = ? AND group_id = ? AND platform = ? AND NOT finalized = 1'); + return stmt.all(userId, groupId, platform); + } catch(err){ + console.log("db error: getReportsUserInfoActive, "+err); } } @@ -347,8 +445,8 @@ const getQuestionId = (db: any, platform: string, groupId: string, userId: strin try{ const stmt = db.prepare(`SELECT question_id FROM reports WHERE platform = ? AND group_id = ? AND user_id = ? AND msg_id = ?`); return stmt.get(platform, groupId, userId, msgId)?.question_id || ''; - } catch{ - console.log("db error: getQuestionId"); + } catch(err){ + console.log("db error: getQuestionId, "+err); } } @@ -356,8 +454,8 @@ const getCron = (db: any): {last_timestamp: number, last_block: number} => { try{ const stmt = db.prepare(`SELECT last_block, last_timestamp FROM cron WHERE bot_index = 0`); return stmt.get(); - } catch{ - console.log("db error: getCron"); + } catch(err){ + console.log("db error: getCron, "+err); } } @@ -370,8 +468,7 @@ const setCron = (db: any, last_block: number, last_timestamp: number) => { last_block=?, last_timestamp=?;`); const info = stmt.run(last_block, last_timestamp,last_block, last_timestamp); } catch(err) { - console.log("db error: setCron"); - console.log(err); + console.log("db error: setCron, "+err); } } @@ -383,8 +480,7 @@ const getRecordCount = (db: any, platform: string, groupId: string) => { ); return stmt.get(platform, groupId)?.total || 0; } catch(err) { - console.log("db error: getRecordCount"); - console.log(err); + console.log("db error: getRecordCount, "+err); } } @@ -405,8 +501,7 @@ const setReport = (db: any, questionId: string, active: boolean, answered: boole ); const info = stmt.run(Number(active), Number(answered),Number(finalized), Number(disputed), timestamp_active, timestamp_finalized, questionId); } catch(err) { - console.log("db error: setReport"); - console.log(err); + console.log("db error: setReport, "+err); } } @@ -448,7 +543,7 @@ const getGroupsInFederation = (db: any, platform: string, federationId: string) const getGroupsInAndFollowingFederation = (db: any, platform: string, federationId: string) => { try{ const stmt = db.prepare( ` - SELECT group_ids + SELECT group_id FROM groups WHERE platform = ? AND (federation_id = ? OR federation_id_following = ?) `); @@ -479,7 +574,7 @@ const getLocalBanHistory = (db: any, platform: string, userId: string, group_id: const getLocalBanHistoryBase = (db: any, platform: string, userId: string, group_id: string, finalized: boolean) => { try{ const stmt = db.prepare(` - SELECT question_id, timestamp_report, timestamp_active as timestamp + SELECT question_id, timestamp_active, timestamp_finalized, timestamp_report as timestamp FROM reports WHERE platform = ? AND user_id = ? ${finalized? 'AND finalized = 1': ''} AND active = 1 AND group_id = ? ORDER BY timestamp_report ASC`) @@ -492,7 +587,7 @@ const getLocalBanHistoryBase = (db: any, platform: string, userId: string, group const getLocalBanHistoryInduction = (db: any, platform: string, userId: string, group_id: string, timestamp_last: number, finalized: boolean) => { try{ const stmt = db.prepare(` - SELECT question_id, timestamp_report, timestamp_active as timestamp + SELECT question_id, timestamp_active, timestamp_finalized, timestamp_report as timestamp FROM reports WHERE platform = ? AND user_id = ? ${finalized? 'AND finalized = 1': ''} AND active = 1 AND group_id = ? AND timestamp_msg > ? ORDER BY timestamp_report ASC`) @@ -510,6 +605,7 @@ const getFederatedBanHistory = (db: any, platform: string, userId: string, feder // sqlit3 couldn't do recursive agregate queries // report ban depth is capped at 3 or 4 levels (1 day, 1 week, permaban) // just going a few inductive steps, could be more efficient in a full query + const banLevel1 = getFederatedBanHistoryInduction(db,platform,userId,federation_id,base.timestamp, finalized) if(!banLevel1) return [base] @@ -522,10 +618,15 @@ const getFederatedBanHistory = (db: any, platform: string, userId: string, feder const getFederatedBanHistoryBase = (db: any, platform: string, userId: string, federation_id: string, finalized: boolean) => { try{ + /* + SELECT question_id, timestamp_active, timestamp_report as timestamp + FROM reports + WHERE platform = ? AND user_id = ? ${finalized? 'AND finalized = 1': ''} AND active = 1 AND group_id = ? + ORDER BY timestamp_report ASC`)*/ const stmt = db.prepare(` - SELECT question_id, timestamp_report, timestamp_active as timestamp + SELECT question_id, timestamp_active, timestamp_finalized, timestamp_report as timestamp FROM reports - WHERE platform = ? AND user_id = ? AND ${finalized? 'AND finalized = 1': ''} AND active = 1 AND group_id IN ( + WHERE platform = ? AND user_id = ? ${finalized? 'AND finalized = 1': ''} AND active = 1 AND group_id IN ( SELECT group_id FROM groups WHERE federation_id = ? AND platform = ? @@ -540,7 +641,7 @@ const getFederatedBanHistoryBase = (db: any, platform: string, userId: string, f const getFederatedBanHistoryInduction = (db: any, platform: string, userId: string, federation_id: string, timestamp_last: number, finalized: boolean) => { try{ const stmt = db.prepare(` - SELECT question_id, timestamp_report, timestamp_active as timestamp + SELECT question_id, timestamp_active, timestamp_finalized, timestamp_report as timestamp FROM reports WHERE platform = ? AND user_id = ? ${finalized? 'AND finalized = 1': ''} AND active = 1 AND timestamp_msg > ? AND group_id IN ( SELECT group_id @@ -575,7 +676,7 @@ const getFederatedFollowingBanHistory = (db: any, platform: string, userId: stri const getFederatedFollowingBanHistoryBase = (db: any, platform: string, userId: string, group_id: string, federation_id: string, finalized: boolean) => { try{ const stmt = db.prepare(` - SELECT question_id, timestamp_report, timestamp_active as timestamp + SELECT question_id, timestamp_active, timestamp_finalized, timestamp_report as timestamp FROM reports WHERE platform = ? AND user_id = ? ${finalized? 'AND finalized = 1': ''} AND active = 1 AND (group_id = ? OR group_id IN ( SELECT group_id @@ -592,7 +693,7 @@ const getFederatedFollowingBanHistoryBase = (db: any, platform: string, userId: const getFederatedFollowingBanHistoryInduction = (db: any, platform: string, userId: string, group_id: string, federation_id: string, timestamp_last: number, finalized: boolean) => { try{ const stmt = db.prepare(` - SELECT question_id, timestamp_report, timestamp_active as timestamp + SELECT question_id, timestamp_active, timestamp_finalized, timestamp_report as timestamp FROM reports WHERE platform = ? AND user_id = ? ${finalized? 'AND finalized = 1': ''} AND active = 1 AND timestamp_msg > ? AND (group_id = ? OR group_id IN ( SELECT group_id @@ -812,13 +913,16 @@ export { setThreadIDWelcome, setAllowance, getAllowance, + getTitle, setReport, setFederation, getFederatedBanHistoryBase, getFederatedFollowingBanHistoryBase, getLocalBanHistoryBase, + getReportsUserInfoFederation, followFederation, addReport, + setFederationChannelID, getUsersWithQuestionsNotFinalized, getQuestionId, getActiveEvidenceGroupId, @@ -828,13 +932,20 @@ export { setAdminReportableMode, setCaptchaMode, getTimestampFinalized, + setFederationInviteURLChannel, getChannelID, getActiveReportsInfo, leaveFederation, + getGroupFederation, + getFederationChannel, + setTitle, + getGroupFederationFollowing, joinFederation, getFederatedFollowingBanHistory, isInFederation, getLocalBanHistory, + getReportsUserInfoActive, + getFederatedInviteURLChannel, getFederatedBanHistory, getGroupsInAndFollowingFederation, getFederationGroups, diff --git a/lib/telegram/assets/lang.json b/lib/telegram/assets/lang.json index 16f9632..917febe 100644 --- a/lib/telegram/assets/lang.json +++ b/lib/telegram/assets/lang.json @@ -5,24 +5,25 @@ "errorLanguage": "is not a supported language.", "errorReply": "must be used in a reply", "errorTxn": "Does the bot address have enough funds to pay the transaction? An unexpected error has occurred", - "errorAdminOnly": "Only admins can execute this command.", + "errorAdminOnly": "Admin only.", "confirmationLanguage": "Language changed to english.", "getAccount": "Bot address", "errorAdminRights": "Please make sure to enable all of the admin rights for the bot.", "getReports" :{ - "noReports": "No reports for user ", - "broke": "broke the rules.", - "nobreak": "did not break the rules.", + "noReports": "No local reports for user", + "noFedReports": "No federal reports for user", + "broke": "broke the rules", + "nobreak": "did not break the rules", "reportFinal": "final", "reportCurrent": "current", "noActiveReports": "There are no active answered reports.", - "specificUser": "To find all reports for a specific user, reply to their message with '/getreports'.", + "specificUser": "To find all reports for a specific user, reply to their message with `/reportinfo`.", "reportMessage": "Active Answered Reports", "reportMessage1": "reported for message sent", "reportMessage2": "backup", "reportMessage3": "Report", "reportMessage4": "current answer", - "ReportsFor": "Reports for" + "ReportsFor": "Local reports for" }, "report" : { "errorAdmin": "An admin can't be reported.", @@ -66,20 +67,20 @@ "Question": "Question", "Option": "Option", "Evidence": "Evidence", - "MessageSent": "Message Set", + "MessageSent": "Message Sent", "Desc1": "Check the bot account of the chat with /getaccount to make sure this evidence submission is not falsified. This is an automated message by the Kleros Moderator Bot with address", "Desc2": "The attached file is a backup record of a message sent in the chat," }, "rules" : "User conduct is moderated according to these [rules]", "noRules" : "No rules found for this chat.", - "errorRules" : "Invalid url passed to /setrules", + "errorRules" : "/setrules with a reply to a msg or ", "rulesUpdated" : "Rules updated.", "answer": "answer", "welcome": "Hi, I'm Susie, a ", "greeting1": "Welcome, this group is moderated with ", "greeting2": "Please make sure to follow the [community rules]", "greeting3": "Users who break the rules can be reported by replying to a message with the command /report.", - "defaultRules": "https://ipfs.kleros.io/ipfs/QmYYcNfEYLtxPM8fof4wf9Tqj7gBGMDMmNnBqZKR1zSczX/Kleros%20Moderate%20Community%20Guidelines%20v1.pdf", + "defaultRules": "https://ipfs.kleros.io/ipfs/QmRxgfYYLRdrCnd492GRinJLT2PvyPkvDhpA5eawEXs3bP/Kleros%20Moderate%20Community%20Guidelines%20v1.0.pdf", "defaultRulesMsg1": "The Kleros Moderate Community Guidelines apply as the default [rules]", "defaultRulesMsg1alt": "The Kleros Moderate Community Guidelines apply as the default rules", "defaultRulesMsg2": "Crafting precise policies can be challenging, if you are certain in setting a new policy, you can set new rules with /setrules \\[url] or /setrules \\[reply to message]" @@ -101,13 +102,13 @@ "reportFinal": "final", "reportCurrent": "current", "noActiveReports": "There are no active answered reports.", - "specificUser": "To find all reports for a specific user, reply to their message with '/getreports'.", + "specificUser": "To find all reports for a specific user, reply to their message with `/getreports`.", "reportMessage": "Active Answered Reports", "reportMessage1": "reported for message sent", "reportMessage2": "backup", "reportMessage3": "Report", "reportMessage4": "current answer", - "ReportsFor": "Reports for" + "ReportsFor": "Local reports for" }, "report" : { "errorAdmin": "An admin can't be reported.", @@ -151,7 +152,7 @@ "Option": "Option", "Evidence": "Evidence", "MessageSent": "Message Set", - "Desc1": "Check the bot account of the chat with /getaccount to make sure this evidence submission is not falsified. This is an automated message by the Kleros Moderator Bot with address", + "Desc1": "Check the bot account of the chat with /getaccount to make it matches the submission address of this automated piece of evidence, to ensure its authenticity.", "Desc2": "The attached file is a backup record of a message sent in the chat," }, "rules" : "User conduct is moderated according to these [rules]", diff --git a/lib/telegram/commands/addEvidence.ts b/lib/telegram/commands/addEvidence.ts index e63c37c..03323be 100644 --- a/lib/telegram/commands/addEvidence.ts +++ b/lib/telegram/commands/addEvidence.ts @@ -18,17 +18,20 @@ var botAddress: string; const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); var myBot; - +var myQueue myCache.on("expired",function(key,value){ - myBot.deleteMessage(value, key); + myQueue.add(async () => {try{await myBot.deleteMessage(value, key)}catch{}}); }); -const processCommand = async (bot: any, settings: groupSettings, msg: any, questionId: number|string, batchedSend: any ): Promise => { - myBot = bot - const evidencePath = await upload(bot, settings.lang, msg); +const processCommand = async (queue: any, bot: any, settings: groupSettings, msg: any, questionId: number|string, batchedSend: any ): Promise => { + if (!myBot) + myBot = bot + if (!myQueue) + myQueue = queue + const evidencePath = await upload(queue, bot, settings.lang, msg); const evidenceJsonPath = await uploadEvidenceJson(settings.lang, msg, evidencePath); try{ - bot.sendMessage(msg.chat.id, `${langJson[settings.lang].addevidence.submitted}(https://ipfs.kleros.io${evidencePath}).`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].addevidence.submitted}(https://ipfs.kleros.io${evidencePath}).`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"})}catch{}}); } catch(e){ console.log(e) } @@ -37,7 +40,7 @@ const processCommand = async (bot: any, settings: groupSettings, msg: any, quest return evidenceJsonPath; } -const upload = async (bot: TelegramBot, lang: string, msg: TelegramBot.Message): Promise => { +const upload = async (queue:any, bot: TelegramBot, lang: string, msg: TelegramBot.Message): Promise => { if (msg.reply_to_message.text){ return await uploadTextEvidence(lang, msg); } else if (msg.reply_to_message.location){ @@ -47,19 +50,28 @@ const upload = async (bot: TelegramBot, lang: string, msg: TelegramBot.Message): } else { var file: TelegramBot.File; if (msg.reply_to_message.sticker){ - file = await bot.getFile(msg.reply_to_message.sticker.file_id); + file = await queue.add(async () => {try{ + const val = await bot.getFile(msg.reply_to_message.sticker.file_id); + return val + }catch{}}); } else if (msg.reply_to_message.photo){ - file = await bot.getFile(msg.reply_to_message.photo[msg.reply_to_message.photo.length-1].file_id); + file = await queue.add(async () => {try{const val = await bot.getFile(msg.reply_to_message.photo[msg.reply_to_message.photo.length-1].file_id) + return val}catch{}}); } else if (msg.reply_to_message.audio){ - file = await bot.getFile(msg.reply_to_message.audio.file_id); + file = await queue.add(async () => {try{const val = await bot.getFile(msg.reply_to_message.audio.file_id) + return val}catch{}}); } else if (msg.reply_to_message.voice){ - file = await bot.getFile(msg.reply_to_message.voice.file_id); + file = await queue.add(async () => {try{const val = await bot.getFile(msg.reply_to_message.voice.file_id) + return val}catch{}}); } else if (msg.reply_to_message.video){ - file = await bot.getFile(msg.reply_to_message.video.file_id); + file = await queue.add(async () => {try{const val = await bot.getFile(msg.reply_to_message.video.file_id) + return val}catch{}}); } else if (msg.reply_to_message.video_note){ - file = await bot.getFile(msg.reply_to_message.video_note.file_id); + file = await queue.add(async () => {try{const val = await bot.getFile(msg.reply_to_message.video_note.file_id) + return val}catch{}}); } else if (msg.reply_to_message.document){ - file = await bot.getFile(msg.reply_to_message.document.file_id); + file = await queue.add(async () => {try{const val = await bot.getFile(msg.reply_to_message.document.file_id) + return val}catch{}}); } const filePath = `https://api.telegram.org/file/bot${process.env.BOT_TOKEN}/`+file.file_path; const fileIPFS = await uploadFileEvidence(filePath, file.file_path.replace('/','_')); @@ -118,7 +130,6 @@ const uploadTextEvidence = async (lang: string, msg: TelegramBot.Message): Promi var remainderMatch = match[1].split(' ') remainderMatch.shift(); const reason = remainderMatch.join(' ') - console.log(reason) textReason = reason.length > 0? `Evidence Submitted with explanation: ${reason}` : '' } const author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' ID:'+msg.reply_to_message.from.id ; @@ -177,16 +188,17 @@ const submitEvidence = async (batchedSend: any, evidencePath: string, questionId } /* - * /addevidence [questionId] + * /evidence [questionId] */ -const regexp = /\/addevidence/ -const regexpFull = /\/addevidence (.+)/ -const regexpFullReason = /\/addevidence (.+) (.+)/ +const regexp = /\/evidence/ +const regexpFull = /\/evidence (.+)/ +const regexpFullReason = /\/evidence (.+) (.+)/ -const callback = async (db: any, settings: groupSettings, bot: any, botID: number, msg: any, matchh: string[], batchedSend: any) => { +const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botID: number, msg: any, matchh: string[], batchedSend: any) => { if (!msg.reply_to_message) { try{ - const resp = bot.sendMessage(msg.chat.id, `/addevidence ${langJson[settings.lang].errorReply}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `/evidence ${langJson[settings.lang].errorReply}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) + return val}catch{}}) myCache.set(resp.message_id, msg.chat.id) } catch (e){ console.log(e) @@ -224,7 +236,8 @@ const callback = async (db: any, settings: groupSettings, bot: any, botID: numbe //TODO Evidence IDs and button callback UX if (!match || match.length < 2){ try{ - const msgresponse = await bot.sendMessage(msg.chat.id, `You did not specify an evidence group.`, opts) + const msgresponse = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `You did not specify an evidence group.`, opts) + return val}catch{}}) myCache.set(msgresponse.message_id, msg.chat.id) } catch(e){ console.log(e) @@ -240,7 +253,8 @@ const callback = async (db: any, settings: groupSettings, bot: any, botID: numbe const evidenceID = getActiveEvidenceGroupId(db, 'telegram', String(msg.chat.id), Number(remainderMatch[0])); if (!evidenceID){ try{ - const resp = await bot.sendMessage(msg.chat.id, langJson[settings.lang].addevidence.errorId, opts) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].addevidence.errorId, opts) + return val}catch{}}) myCache.set(resp.message_id, msg.chat.id) } catch(e){ console.log(e) @@ -254,7 +268,8 @@ const callback = async (db: any, settings: groupSettings, bot: any, botID: numbe setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), 3, 14, Math.ceil( new Date().getTime() / 1000)); } else if ((Math.ceil( new Date().getTime() / 1000) < reportAllowance.timestamp_refresh + 5760) && reportAllowance.evidence_allowance == 0 ){ try{ - const resp = await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorAllowance); + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorAllowance) + return val}catch{}}); myCache.set(resp.message_id, msg.chat.id) } catch (e){ console.log(e) @@ -267,7 +282,7 @@ const callback = async (db: any, settings: groupSettings, bot: any, botID: numbe } try { - const evidencePath = await processCommand(bot, settings, msg, evidenceID,batchedSend); + const evidencePath = await processCommand(queue, bot, settings, msg, evidenceID,batchedSend); } catch (e) { console.log(e); } diff --git a/lib/telegram/commands/addEvidenceHelp.ts b/lib/telegram/commands/addEvidenceHelp.ts index 0dc9e04..53aa07c 100644 --- a/lib/telegram/commands/addEvidenceHelp.ts +++ b/lib/telegram/commands/addEvidenceHelp.ts @@ -9,10 +9,10 @@ import { groupSettings } from "../../../types"; */ const regexp = /\/addevidencehelp/ -const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { +const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { const groupId = getUsersWithQuestionsNotFinalized(db, 'telegram', msg.text.substring(22)) if (!groupId || groupId.length === 0){ - bot.sendMessage(msg.chat.id, `There are no reports to add evidence to in your group.`); + queue.add(() => bot.sendMessage(msg.chat.id, `There are no reports to add evidence to in your group.`)); } var inline_keyboard_evidence = [] var inline_keyboard_evidence_cursor = []; @@ -36,7 +36,7 @@ const callback = async (db: any, settings: groupSettings, bot: any, botId: numbe inline_keyboard: inline_keyboard_evidence } } - bot.sendMessage(msg.chat.id, `Let me help you find the report you want to add evidence to. Which user is the report about?`,opts); + queue.add(() => bot.sendMessage(msg.chat.id, `Let me help you find the report you want to add evidence to. Which user is the report about?`,opts)); } export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/captcha.ts b/lib/telegram/commands/captcha.ts index 4a415b6..7abb1bf 100644 --- a/lib/telegram/commands/captcha.ts +++ b/lib/telegram/commands/captcha.ts @@ -5,13 +5,16 @@ import {groupSettings} from "../../../types"; const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); var myBot; - +var myQueue; myCache.on("expired",function(key,value){ - myBot.deleteMessage(value, key); + myQueue.add(async () => {try{await myBot.deleteMessage(value, key)}catch{}}); }); -const callback = async (bot: any, settings: groupSettings, msg: any) => { - myBot = bot +const callback = async (queue: any, bot: any, settings: groupSettings, msg: any) => { + if (!myBot) + myBot = bot + if (!myQueue) + myQueue = queue try{ @@ -45,7 +48,8 @@ const callback = async (bot: any, settings: groupSettings, msg: any) => { ] } }; - const msg_welcome = bot.sendMessage(msg.chat.id, `Welcome [${msg.from.first_name}](tg://user?id=${msg.from.id}) ${langJson[settings.lang].greeting2}(${settings.rules}). ${langJson[settings.lang].greeting3}`, msg.chat.is_forum? optsThread: opts); + const msg_welcome = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `Welcome [${msg.from.first_name}](tg://user?id=${msg.from.id}) ${langJson[settings.lang].greeting2}(${settings.rules}). ${langJson[settings.lang].greeting3}`, msg.chat.is_forum? optsThread: opts) + return val}catch{}}); myCache.set(msg_welcome.message_id, msg.chat.id) } catch(e){ console.log(e) diff --git a/lib/telegram/commands/fedinfo.ts b/lib/telegram/commands/fedinfo.ts index c14b7bd..81a839c 100644 --- a/lib/telegram/commands/fedinfo.ts +++ b/lib/telegram/commands/fedinfo.ts @@ -1,67 +1,38 @@ import * as TelegramBot from "node-telegram-bot-api"; import { groupSettings } from "../../../types"; -import {setFederation,getFederationName} from "../../db"; +import {getFederationName,getGroupFederation,getGroupFederationFollowing} from "../../db"; import langJson from "../assets/lang.json"; +const NodeCache = require( "node-cache" ); +const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); +var myBot; +var myQueue; +myCache.on("expired",function(key,value){ + myQueue.add(async () => {try{await myBot.deleteMessage(value, key)}catch{}}); + }); /* * /joinfed */ const regexp = /\/fedinfo\s?(.+)?/ -const callback = async (db: any, settings: groupSettings, bot: any, botId: string, msg: any, match: string[]) => { +const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: string, msg: any, match: string[]) => { try{ - if (msg.chat.type !== "private"){ - const opts = msg.chat.is_forum? { - message_thread_id: msg.message_thread_id, - parse_mode: 'Markdown', - reply_markup: { - inline_keyboard: [ - [ - { - text: 'Get Help (DM)', - url: `https://t.me/${process.env.BOT_USERNAME}?start=newfed` - } - ] - ] - } - }: { - parse_mode: 'Markdown', - reply_markup: { - inline_keyboard: [ - [ - { - text: 'Get Help (DM)', - url: `https://t.me/${process.env.BOT_USERNAME}?start=newfed` - } - ] - ] - } - } - bot.sendMessage(msg.chat.id, `DM me for help with your federation : )`, opts); - return; - } - const name = getFederationName(db, 'telegram',msg.from.id); - console.log(name) - if (name){ - bot.sendMessage(settings.channelID, `Your federation *${name}* with id \`${msg.from.id}\` already exists.`,msg.chat.is_forum? { - message_thread_id: msg.message_thread_id, - parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); - return - } - if (!match[1]){ - bot.sendMessage(settings.channelID, `Please name your federation eg: \`/newfed My New Federation\``,msg.chat.is_forum? { - message_thread_id: msg.message_thread_id, - parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); - return - } else{ - const name = match[1].substring(0,65) - setFederation(db, 'telegram',name, msg.from.id) - bot.sendMessage(settings.channelID, `Your new federation is called *${match[1].substring(0,65)}* with id ${msg.from.id}. You can add groups to your federation by sending \`/joinfed ${msg.from.id}\` in each group.`,msg.chat.is_forum? { - message_thread_id: msg.message_thread_id, - parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); - } - //joinFederation(db, 'telegram', String(msg.chat.id), String(msg.from.id)) - //bot.sendMessage(msg.chat.id, 'Your group has joined the federation.', msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) + if (!myBot) + myBot = bot + if (!myQueue) + myQueue = queue + // TODO private fed info + const fed_id = getGroupFederation(db, 'telegram',String(msg.chat.id)); + const fed_id_following = getGroupFederationFollowing(db, 'telegram',String(msg.chat.id)); + let resp; + if (fed_id || fed_id_following){ + const name = getFederationName(db, 'telegram', fed_id ?? fed_id_following); + resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `This group is ${fed_id? 'in': 'following'} the *${name}* federation with id \`${fed_id ?? fed_id_following}\``, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) + return val}catch{}}) + } else + resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `No federation set.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) + return val}catch{}}); + myCache.set(resp.message_id,msg.chat.id) } catch(e){ console.log(e) } diff --git a/lib/telegram/commands/getAccount.ts b/lib/telegram/commands/getAccount.ts index 755f0ad..e0f98b6 100644 --- a/lib/telegram/commands/getAccount.ts +++ b/lib/telegram/commands/getAccount.ts @@ -9,11 +9,11 @@ import { groupSettings } from "../../../types"; const regexp = /\/getaccount/ var address: string; -const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { +const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { try{ if (!address) address = process.env.TRANSACTION_BATCHER_CONTRACT_ADDRESS; - bot.sendMessage(settings.channelID, `${langJson[settings.lang].getAccount}: ${address}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `${langJson[settings.lang].getAccount}: ${address}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{})}catch{}}); } catch(e){ console.log('gettaccount error. '+e) } diff --git a/lib/telegram/commands/getChannel.ts b/lib/telegram/commands/getChannel.ts index cb37347..8daf6ce 100644 --- a/lib/telegram/commands/getChannel.ts +++ b/lib/telegram/commands/getChannel.ts @@ -1,13 +1,13 @@ import * as TelegramBot from "node-telegram-bot-api"; -import {getRule, getInviteURLChannel, getChannelID} from "../../db"; +import {getRule, getInviteURLChannel, getFederatedInviteURLChannel, getChannelID} from "../../db"; import langJson from "../assets/lang.json"; import { groupSettings } from "../../../types"; const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); var myBot; - +var myQueue; myCache.on("expired",function(key,value){ - myBot.deleteMessage(value, key); + myQueue.add(async () => {try{await myBot.deleteMessage(value, key)}catch{}}); }); /* @@ -15,14 +15,25 @@ myCache.on("expired",function(key,value){ */ const regexp = /\/notifications/ -const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { - myBot = bot; +const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { + if (!myBot) + myBot = bot + if (!myQueue) + myQueue = queue const channel_invite = getInviteURLChannel(db, 'telegram', String(msg.chat.id)); - if(!channel_invite){ - const resp = await bot.sendMessage(msg.chat.id, `Notifications channel not set. Ask an admin to /setchannel.`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}); + if(settings.federation_id || settings.federation_id_following){ + const inviteurl = getFederatedInviteURLChannel(db, 'telegram', settings.federation_id); + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `The notifications for this group's federation are sent to this [channel](${inviteurl}).`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}) + return val}catch{}}); + myCache.set(resp.message_id, msg.chat.id) + } + if(!channel_invite && !msg.chat.is_forum){ + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `Notifications channel for this group is not set. Ask an admin to \`/setchannel\`.`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}) + return val}catch{}}); myCache.set(resp.message_id, msg.chat.id) } else { - const resp = await bot.sendMessage(msg.chat.id, `I notify this [channel](${channel_invite}) about moderation activity.`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}); + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `I notify this [channel](${channel_invite}) about moderation activity.`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}) + return val}catch{}}); myCache.set(resp.message_id, msg.chat.id) } } diff --git a/lib/telegram/commands/getReports.ts b/lib/telegram/commands/getReports.ts index 94b65c2..49434a0 100644 --- a/lib/telegram/commands/getReports.ts +++ b/lib/telegram/commands/getReports.ts @@ -1,22 +1,26 @@ import * as TelegramBot from "node-telegram-bot-api"; const escape = require('markdown-escape') import langJson from "../assets/lang.json"; -import {getReportsUserInfo ,getActiveReportsInfo} from "../../db"; +import {getReportsUserInfo ,getActiveReportsInfo,getReportsUserInfoFederation, getInviteURL,getLocalBanHistory, getFederatedBanHistory, getFederatedFollowingBanHistory, getTitle} from "../../db"; import { groupSettings } from "../../../types"; +import {calcPenalty} from "../../cron" const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); var myBot; - +var myQueue; myCache.on("expired",function(key,value){ - myBot.deleteMessage(value, key); + myQueue.add(async () => {try{await myBot.deleteMessage(value, key)}catch{}}); }); /* * /getreports */ -const regexp = /\/getreports/ +const regexp = /\/reportinfo/ -const callback = async (db: any, settings: groupSettings, bot: any, botid: number, msg: any) => { - myBot = bot +const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botid: number, msg: any) => { + if (!myBot) + myBot = bot + if (!myQueue) + myQueue = queue try{ if (msg.chat.type !== "private"){ const opts = msg.chat.is_forum? { @@ -27,7 +31,7 @@ const callback = async (db: any, settings: groupSettings, bot: any, botid: numbe [ { text: 'Get Report Info', - url: `https://t.me/${process.env.BOT_USERNAME}?start=getreport${msg.chat.id}${(msg.reply_to_message && !msg.reply_to_message.forum_topic_created)? msg.reply_to_message.from.id: ''}` + url: `https://t.me/${process.env.BOT_USERNAME}?start=getreport${msg.chat.id}${(msg.reply_to_message && !msg.reply_to_message.forum_topic_created)? msg.reply_to_message.from.id: ''}${(settings.federation_id ?? settings.federation_id_following + 'following') ?? ''}` } ] ] @@ -39,52 +43,86 @@ const callback = async (db: any, settings: groupSettings, bot: any, botid: numbe [ { text: 'Get Report Info', - url: `https://t.me/${process.env.BOT_USERNAME}?start=getreport${msg.chat.id}${(msg.reply_to_message && !msg.reply_to_message.forum_topic_created)? msg.reply_to_message.from.id: ''}` + url: `https://t.me/${process.env.BOT_USERNAME}?start=getreport${msg.chat.id}${(msg.reply_to_message && !msg.reply_to_message.forum_topic_created)? msg.reply_to_message.from.id: ''}${(settings.federation_id ?? settings.federation_id_following) ?? ''}` } ] ] } } - const resp = await bot.sendMessage(msg.chat.id, `DM me for report info : )`, opts); + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `DM me for report info : )`, opts) + return val}catch{}}); myCache.set(resp.message_id, msg.chat.id) return; } let group_id: string; - let user_id: string - if(msg.text.length > 35){ + let user_id: string; + let federation_id: string; + + if(msg.text.length > 45){ group_id = msg.text.substring(16,30) - user_id = msg.text.substring(30) + user_id = msg.text.substring(30,40) + federation_id = msg.text.substring(40) } else if (msg.text.length > 16){ group_id = msg.text.substring(16,30) - } else return; - + if(user_id){ + const banHistory = federation_id? (msg.text.length > 55 ? getFederatedFollowingBanHistory(db,'telegram',user_id,group_id,federation_id,false) : getFederatedBanHistory(db, 'telegram',user_id,federation_id,false)): getLocalBanHistory(db,'telegram',user_id,group_id,false) const reports = getReportsUserInfo(db, 'telegram', group_id, user_id); - const user = await bot.getChatMember(group_id, user_id) + const user = await queue.add(async () => {try{const val = await bot.getChatMember(group_id, user_id) + return val}catch{}}) const fromUsername = (user.user.username || user.user.first_name || `no-username-set`); - if (reports.length == 0){ - bot.sendMessage(msg.chat.id, `${langJson[settings.lang].getReports.noReports} *${escape(fromUsername)}*.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}:{parse_mode: "Markdown"}); - return; + const ban_level = banHistory.length + var reportMessage: string = "" + var max_timestamp = 0 + for (const ban of banHistory){ + if (ban.timestamp_active > max_timestamp) + max_timestamp = ban.timestamp_active + else if (ban.timestamp_finalized > max_timestamp) + max_timestamp = ban.timestamp_finalized + } + + if (ban_level > 0){ + const date_lastreport = new Date(banHistory[ban_level-1].timestamp*1000).toUTCString() + const date_parole = new Date(1000*calcPenalty(ban_level, max_timestamp)).toUTCString() + reportMessage += `*${escape(fromUsername)}* broke the rules atleast ${ban_level} time(s), and is banned until ${date_parole}.\n\n` } - var reportMessage: string = `${langJson[settings.lang].getReports.ReportsFor} ${escape(fromUsername)}:\n\n`; - reports.forEach( (report) => { - console.log(report) + reportMessage += `*${langJson[settings.lang].getReports.ReportsFor} ${escape(fromUsername)}*:\n\n`; + if (reports.length === 0){ + reportMessage += `${langJson[settings.lang].getReports.noReports}.\n` + } + reports.forEach( report => { const reportAnswer = report.answered? (report.active? langJson[settings.lang].getReports.broke : langJson[settings.lang].getReports.nobreak) : 'unanswered'; const MsgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + report.msg_id; - const msgTime = new Date(report.timestamp_msg*1000).toDateString(); const msgTimehours = new Date(report.timestamp_msg*1000).toUTCString(); const reportState = report.finalized? langJson[settings.lang].getReports.reportFinal : langJson[settings.lang].getReports.reportCurrent; - reportMessage += ` - [${langJson[settings.lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), [${langJson[settings.lang].addevidence.MessageSent}](${MsgLink}) ${msgTime}, ${msgTimehours} ([${langJson[settings.lang].socialConsensus.consensus5}](${report.msgBackup})), ${reportState} ${langJson[settings.lang].answer}, ${reportAnswer}, \`/addevidence ${report.evidenceIndex}\`\n`; + reportMessage += ` - [${langJson[settings.lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), [Message](${MsgLink}), Sent ${msgTimehours.substring(0,12)}([${langJson[settings.lang].socialConsensus.consensus5}](${report.msgBackup})), ${reportState} ${langJson[settings.lang].answer}, ${reportAnswer}${report.finalized? ".":`, \`/evidence ${report.evidenceIndex}\`.`}\n`; }); - bot.sendMessage(msg.chat.id, reportMessage , msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown", disable_web_page_preview: true}:{parse_mode: "Markdown", disable_web_page_preview: true}); + if(federation_id){ + const reportsFederation = getReportsUserInfoFederation(db, 'telegram', user_id, federation_id,group_id); + reportMessage += `\n*Federal reports for ${escape(fromUsername)}*:\n\n` + if (reportsFederation.length == 0){ + reportMessage += `${langJson[settings.lang].getReports.noReports}.\n` + } + for(const report of reportsFederation) { + // TODO getTitle + const chatname = (await queue.add(async () => {try{const val = await bot.getChat(group_id) + return val}catch{}}))?.title + const invite_url = getInviteURL(db,'telegram',group_id) + const reportAnswer = report.answered? (report.active? langJson[settings.lang].getReports.broke : langJson[settings.lang].getReports.nobreak) : 'unanswered'; + const MsgLink = 'https://t.me/c/' + report.group_id.substring(4) + '/' + report.msg_id; + const msgTimehours = new Date(report.timestamp_msg*1000).toUTCString(); + const reportState = report.finalized? langJson[settings.lang].getReports.reportFinal : langJson[settings.lang].getReports.reportCurrent; + reportMessage += ` - [${langJson[settings.lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), [message](${MsgLink}), sent in [${chatname}](${invite_url}), at ${msgTimehours.substring(0,12)}([${langJson[settings.lang].socialConsensus.consensus5}](${report.msgBackup})), ${reportState} ${langJson[settings.lang].answer}, ${reportAnswer}\n`; } + } + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, reportMessage , msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown", disable_web_page_preview: true}:{parse_mode: "Markdown", disable_web_page_preview: true})}catch{}}); return; } else { const reports = getActiveReportsInfo(db, 'telegram', group_id); if (reports.length == 0){ - bot.sendMessage(msg.chat.id, langJson[settings.lang].getReports.noActiveReports + '\n\n' + langJson[settings.lang].getReports.specificUser, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}:{parse_mode: "Markdown"}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[settings.lang].getReports.noActiveReports + '\n\n' + langJson[settings.lang].getReports.specificUser, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}:{parse_mode: "Markdown"})}catch{}}); return; } var reportMessage: string = langJson[settings.lang].getReports.reportMessage + ':\n\n'; @@ -97,7 +135,7 @@ const callback = async (db: any, settings: groupSettings, bot: any, botid: numbe }); reportMessage += '\n\n' reportMessage += langJson[settings.lang].getReports.specificUser; - bot.sendMessage(msg.chat.id, reportMessage, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown", disable_web_page_preview: true}:{parse_mode: "Markdown", disable_web_page_preview: true}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, reportMessage, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown", disable_web_page_preview: true}:{parse_mode: "Markdown", disable_web_page_preview: true})}catch{}}); } } catch(e){ console.log(e) diff --git a/lib/telegram/commands/getRules.ts b/lib/telegram/commands/getRules.ts index 89a155b..3f39a24 100644 --- a/lib/telegram/commands/getRules.ts +++ b/lib/telegram/commands/getRules.ts @@ -5,9 +5,9 @@ import { groupSettings } from "../../../types"; const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); var myBot; - +var myQueue; myCache.on("expired",function(key,value){ - myBot.deleteMessage(value, key); + myQueue.add(async () => {try{await myBot.deleteMessage(value, key)}catch{}}); }); /* @@ -15,10 +15,14 @@ myCache.on("expired",function(key,value){ */ const regexp = /\/rules/ -const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { - myBot = bot +const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { + if (!myBot) + myBot = bot + if (!myQueue) + myQueue = queue getRule(db,'telegram', msg.chat.id,Math.floor(Date.now()/1000)) - const msgresponse = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].rules}(${settings.rules}).`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id, disable_web_page_preview: false}:{parse_mode: "Markdown", disable_web_page_preview: false}); + const msgresponse = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].rules}(${settings.rules}).`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id, disable_web_page_preview: false}:{parse_mode: "Markdown", disable_web_page_preview: false}) + return val}catch{}}); myCache.set(msgresponse.message_id, msg.chat.id) } diff --git a/lib/telegram/commands/greeting.ts b/lib/telegram/commands/greeting.ts index 54c966a..6cda784 100644 --- a/lib/telegram/commands/greeting.ts +++ b/lib/telegram/commands/greeting.ts @@ -5,13 +5,17 @@ import {groupSettings} from "../../../types"; const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); var myBot; +var myQueue; myCache.on("expired",function(key,value){ - myBot.deleteMessage(value, key); + myQueue.add(async () => {try{await myBot.deleteMessage(value, key)}catch{}}); }); -const callback = async (bot: any, settings: groupSettings, msg: any) => { - myBot = bot +const callback = async (queue: any, bot: any, settings: groupSettings, msg: any) => { + if (!myBot) + myBot = bot + if (!myQueue) + myQueue = queue try{ const opts = { parse_mode: 'Markdown', @@ -45,10 +49,12 @@ const callback = async (bot: any, settings: groupSettings, msg: any) => { let msg_welcome; if(settings.captcha){ const options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false}; - bot.restrictChatMember(msg.chat.id, msg.from.id, options); - msg_welcome = await bot.sendMessage(msg.chat.id, `Hi 👋 Welcome [${msg.from.first_name}](tg://user?id=${msg.from.id}). ${langJson[settings.lang].greeting2}(${settings.rules}).`, msg.chat.is_forum? optsThread: opts); + queue.add(async () => {try{await bot.restrictChatMember(msg.chat.id, msg.from.id, options)}catch{}}); + msg_welcome = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `Hi 👋 Welcome [${msg.from.first_name}](tg://user?id=${msg.from.id}). ${langJson[settings.lang].greeting2}(${settings.rules}).`, msg.chat.is_forum? optsThread: opts) + return val}catch{}}); } else if (settings.greeting_mode){ - msg_welcome = await bot.sendMessage(msg.chat.id, `Hi 👋 Welcome [${msg.from.first_name}](tg://user?id=${msg.from.id}). ${langJson[settings.lang].greeting2}(${settings.rules}).`, msg.chat.is_forum? {message_thread_id: settings.thread_id_welcome,disable_web_page_preview: true}: {disable_web_page_preview: true}); + msg_welcome = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `Hi 👋 Welcome [${msg.from.first_name}](tg://user?id=${msg.from.id}). ${langJson[settings.lang].greeting2}(${settings.rules}).`, msg.chat.is_forum? {message_thread_id: settings.thread_id_welcome,disable_web_page_preview: true}: {disable_web_page_preview: true}) + return val}catch{}}); } myCache.set(msg_welcome.message_id, msg.chat.id) } catch(e){ diff --git a/lib/telegram/commands/help.ts b/lib/telegram/commands/help.ts index 8d4910b..6fa0a8e 100644 --- a/lib/telegram/commands/help.ts +++ b/lib/telegram/commands/help.ts @@ -7,9 +7,9 @@ import { groupSettings } from "../../../types"; */ const regexp = /\/help/ -const helpgnosis = (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { +const helpgnosis = (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { try{ - bot.sendMessage(msg.chat.id, `⛓️ *Gnosis Chain* ⛓️ + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `⛓️ *Gnosis Chain* ⛓️ Susie uses [xDAI](https://docs.gnosischain.com/about/tokens/xdai), a stable coin, on [Gnosis Chain](https://www.gnosis.io/). Don't know what that means? It means Susie uses a cheap and fast decentralized tool to coordinate moderation fairly and transparently. @@ -22,15 +22,15 @@ Don't have any cryptocurrency? No problem, there's a convinient [fiat on-ramp](h Need help adding the Gnosis Chain network to your wallet? Don't worry, there's a [guide](https://docs.gnosischain.com/tools/wallets/metamask#2-configure) for that. Need more help? Don't worry, there's a @SusieSupport group for that` - ,{parse_mode: 'Markdown', disable_web_page_preview: true}) + ,{parse_mode: 'Markdown', disable_web_page_preview: true})}catch{}}) } catch(e){ console.log(e) } } -const helpnotifications = (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { +const helpnotifications = (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { try{ - bot.sendMessage(msg.chat.id, `🔔 *Notifications* 🔔 + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `🔔 *Notifications* 🔔 Susie sends notifications about moderation actions and report updates. These notifications are restricted to a separate chat in topic mode. In regular Telegram groups, notifications can be sent to a notification channel to avoid cluttering the main chat. @@ -39,21 +39,22 @@ How to enable notification channels: 1. Make a channel 2. Add Susie 3. Susie will send a channel ID -4. Use that channel ID to set notifications with /setchannel in the original group +4. Use that channel ID to set notifications with \`/setchannel\` in the original group *User commands*: -- /notifications: Returns current notification channel +- \`/notifications\`: Returns current notification channel *Admin commands*: -- /setchannel : Sets the notification channel to the specified channel id` - ,{parse_mode: 'Markdown', disable_web_page_preview: true}) - bot.sendVideo(msg.chat.id, `https://ipfs.kleros.io/ipfs/QmaWKFxR8TNzWW1xDuzXe4XFE5wCFJVuFP6AKCQ3LRAQqB/Screen%20Recording%202022-12-13%20at%209.19.17%20PM(1).mp4`); +- \`/setchannel\` : Sets the notification channel to the specified channel id +- \`/setfedchannel\` : Sets the notification channel for your federation to the specified channel id` + ,{parse_mode: 'Markdown', disable_web_page_preview: true})}catch{}}) + //queue.add(async () => {try{await bot.sendVideo(msg.chat.id, `https://ipfs.kleros.io/ipfs/QmaWKFxR8TNzWW1xDuzXe4XFE5wCFJVuFP6AKCQ3LRAQqB/Screen%20Recording%202022-12-13%20at%209.19.17%20PM(1).mp4`)); } catch(e){ console.log(e) } } -const callback = (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { +const callback = (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { if (msg.chat.type !== "private"){ const opts = msg.chat.is_forum? { message_thread_id: msg.message_thread_id, @@ -81,13 +82,13 @@ const callback = (db: any, settings: groupSettings, bot: any, botId: number, msg ] } } - bot.sendMessage(msg.chat.id, `DM me for help : )`, opts); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `DM me for help : )`, opts)}catch{}}); return; } - bot.sendMessage(msg.chat.id, message,opts); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, message,opts)}catch{}}); } -const respond = (settings: groupSettings, bot: any, helpType: string, callbackQuery: TelegramBot.CallbackQuery) => { +const respond = (queue: any, settings: groupSettings, bot: any, helpType: string, callbackQuery: TelegramBot.CallbackQuery) => { const optsResponse = { chat_id: callbackQuery.message.chat.id, message_id: callbackQuery.message.message_id, @@ -96,14 +97,14 @@ const respond = (settings: groupSettings, bot: any, helpType: string, callbackQu }; try{ if (helpType !== 'back'){ - bot.editMessageReplyMarkup({ inline_keyboard: [[ + queue.add(async () => {try{await bot.editMessageReplyMarkup({ inline_keyboard: [[ { text: 'back', callback_data: `3|back` } - ]]}, optsResponse) + ]]}, optsResponse)}catch{}}); } else { - bot.editMessageReplyMarkup({ + queue.add(async () => {try{await bot.editMessageReplyMarkup({ inline_keyboard: [ [ { @@ -152,25 +153,25 @@ const respond = (settings: groupSettings, bot: any, helpType: string, callbackQu callback_data: `3|web2.5` } ] - ]}, optsResponse) - bot.editMessageText(message,optsResponse) + ]}, optsResponse)}catch{}}); + queue.add(async () => {try{await bot.editMessageText(message,optsResponse)}catch{}}) } switch(helpType){ case 'greeting': { - bot.editMessageText(`👋 *Greeting* 👋 + queue.add(async () => {try{await bot.editMessageText(`👋 *Greeting* 👋 Welcome your members with a greeting informing them of the group rules *Admin commands:* -- /welcome : Toggles on/off welcomes messages. -- /captcha : Toggles on/off rules captcha. +- \`/welcome\` : Toggles on/off welcomes messages. +- \`/captcha\` : Toggles on/off rules captcha. When a new person joins, or after 5 minutes, the previous welcome messages will get deleted\n\nCaptchas remain for up to 5 minutes. If a user forgets to respond within 5 minutes, they should rejoin the group to prompt a new captcha. - `,optsResponse) + `,optsResponse)}catch{}}) break; } case 'language': { - bot.editMessageText(`🗣️ *Languages* 🗣️ + queue.add(async () => {try{await bot.editMessageText(`🗣️ *Languages* 🗣️ Susie's replies can be changed to one of the languages below. @@ -178,36 +179,36 @@ Susie's replies can be changed to one of the languages below. - ES (Español) *soon* *Admin commands*: -- /setlang : Set your preferred language. +- \`/setlang\` : Set your preferred language. Content moderation requires a nuanced understanding of context and language. Setting a language not only changes Susie's responses, but also specifies language skilled jurors. Please make sure to set the appropriate language for your community for effective moderation.` - ,optsResponse) + ,optsResponse)}catch{}}) break; } case 'topics': { - bot.editMessageText(`ℹ️ *Topics* ℹ️ + queue.add(async () => {try{await bot.editMessageText(`ℹ️ *Topics* ℹ️ Topics allow large (>200 member) groups to focus discussion in dedicated **topic** chats. Susie supports topics. When changing a group to topic mode, you will need to /start Susie again. *Admin commands*: -- /start: Start topic mode.` - ,optsResponse) +- \`/start\`: Start topic mode.` + ,optsResponse)}catch{}}) break; } case 'addevidence': { - bot.editMessageText(`🔍 *Evidence* 🔍 + queue.add(async () => {try{await bot.editMessageText(`🔍 *Evidence* 🔍 To prevent important messages from deletion, pre-emptively, messages can be saved as evidence. *User commands*: -- /addevidence \n\nReply to a message to add it as evidence` - ,optsResponse) +- \`/evidence\` \n\nReply to a message to add it as evidence` + ,optsResponse)}catch{}}) break; } case 'report': { - bot.editMessageText(`🚨 *Report* 🚨 + queue.add(async () => {try{await bot.editMessageText(`🚨 *Report* 🚨 As groups grow, so do their moderation problems. We're all busy people who don't have time to monitor groups 24/7. Users often complain about admin abuse and have no recourse. Who moderates the moderator? @@ -222,27 +223,27 @@ When users are reported, a question is created on Reality.Eth asking 'did the us Answers to reports can be disputed, creating a case in the Kleros court. Refer to the [docs](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator) to learn more. *User commands*: -- /report : Reply to a message to report it -- /getreports: Returns active reports -- /getreports : Returns active reports for user` - ,optsResponse) +- \`/report\` : Reply to a message to report it +- \`/reportinfo\`: Returns active reports +- \`/reportinfo\` : Returns active reports for user` + ,optsResponse)}catch{}}) break; } case 'rules': { - bot.editMessageText(`⚖️ *Rules* ⚖️ + queue.add(async () => {try{await bot.editMessageText(`⚖️ *Rules* ⚖️ The Kleros Moderate Community Guidelines apply as the [default rules]((https://ipfs.kleros.io/ipfs/QmYYcNfEYLtxPM8fof4wf9Tqj7gBGMDMmNnBqZKR1zSczX/Kleros%20Moderate%20Community%20Guidelines%20v1.pdf)). Crafting precise policies can be challenging, if you are certain in setting a new policy, you can set new rules with /setrules *User commands*: -- /rules: Returns current rules +- \`/rules\`: Returns current rules *Admin commands*: -- /setrules : Sets the rules to the the url -- /setrules : Sets the rules to a replied message` - ,optsResponse) +- \`/setrules\` : Sets the rules to the the url +- \`/setrules\` : Sets the rules to a replied message` + ,optsResponse)}catch{}}) break; } case 'notifications': { - bot.editMessageText(`🔔 *Notifications* 🔔 + queue.add(async () => {try{await bot.editMessageText(`🔔 *Notifications* 🔔 Susie sends notifications about moderation actions and report updates. These notifications are restricted to a separate chat in topic mode. In regular Telegram groups, notifications can be sent to a notification channel to avoid cluttering the main chat. @@ -254,29 +255,30 @@ How to enable notification channels: 4. Use that channel ID to set notifications with /setchannel in the original group *User commands*: -- /notifications: Returns current notification channel +- \'/notifications\': Returns current notification channel *Admin commands*: -- /setchannel : Sets the notification channel to the specified channel id` - ,optsResponse) +- \`/setchannel\` : Sets the notification channel to the specified channel id +- \`/setfedchannel\` : Sets the notification channel for your federation to the specified channel id` + ,optsResponse)}catch{}}) break; } case 'federation': { - bot.editMessageText(`🌐 *Federations* + queue.add(async () => {try{await bot.editMessageText(`🌐 *Federations* Moderating a single group is hard, but managing multiple is even harder? Do you have to ban spammers manually, in all your groups? No more! With federations, Susie can enforce a ban on a user in all federate groups. *User commands*: -- /getfed: Returns current federation +- \`/fedinfo\`: Returns current federation *Admin commands*: -- /newfed: Creates a federation -- /joinfed: Joins the current group to a Federation` - ,optsResponse) +- \`/newfed\`: Creates a federation +- \`/joinfed\`: Joins the current group to a Federation` + ,optsResponse)}catch{}}) break; } case 'web2.5': { - bot.editMessageText(`⛓️ *Gnosis Chain* ⛓️ + queue.add(async () => {try{await bot.editMessageText(`⛓️ *Gnosis Chain* ⛓️ Susie uses [xDAI](https://docs.gnosischain.com/about/tokens/xdai), a stable coin, on [Gnosis Chain](https://www.gnosis.io/). Don't know what that means? It means Susie uses a cheap and fast public ledger to coordinate moderation fairly and transparently. @@ -289,37 +291,37 @@ Don't have any cryptocurrency? No problem, there's a convinient [fiat on-ramp](h Need help adding the Gnosis Chain network to your wallet? Don't worry, there's a [guide](https://docs.gnosischain.com/tools/wallets/metamask#2-configure) for that. Need more help? Don't worry, there's a @SusieSupport group for that` - ,optsResponse) + ,optsResponse)}catch{}}) break; } case 'court': { - bot.editMessageText(`⚖️ *Court* ⚖️ + queue.add(async () => {try{await bot.editMessageText(`⚖️ *Court* ⚖️ Disputes are resolved by the [Kleros Court](https://kleros.gitbook.io/docs/) with a randomly selected jury. If the jury made a mistake, the case can be appealed, drawing a larger pool of random jurors and providing an opportunity to provide more context, analysis, and arguments. If you would like a chance to serve as a jury member, buy PNK ([Gnosis Chain](https://swapr.eth.link/#/swap?chainId=100) or [Mainnet](https://app.uniswap.org/#/swap?outputCurrency=0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d&inputCurrency=ETH)) and [stake](https://court.kleros.io/) in the curation subcourt of the Kleros Court on Gnosis Chain. To discuss the merits of a dispute, see @klerosjuror.` - ,optsResponse) + ,optsResponse)}catch{}}) break; } case 'lawyer': { - bot.editMessageText(`🧑‍⚖️ *Find a Lawyer* 🧑‍⚖️ + queue.add(async () => {try{await bot.editMessageText(`🧑‍⚖️ *Find a Lawyer* 🧑‍⚖️ Disputes over reported behavior can be complicated and nuanced. Often, disputes resolve on the merits of the message and rules alone. In some cases, disputes are better resolved by presenting the court with analysis and arguments. If you would like to offer your services as a lawyer or solicit services, please join this [group](https://t.me/+9fvGGkGfSZ1hZDBk). ` - ,optsResponse) + ,optsResponse)}catch{}}) break; } case 'open': { - bot.editMessageText(`✨ *Open Source* ✨ + queue.add(async () => {try{await bot.editMessageText(`✨ *Open Source* ✨ Susie is [open source](https://github.com/kleros/kleros-moderate). Feel free to make an issue, feature request, bug report, comments, suggests, PRs, forks, etc : ) ` - ,optsResponse) + ,optsResponse)}catch{}}) break; //Susie is hosted. You can self-host Susie. A raspberry pi or an old laptop are sufficient to keep your own instance of Susie online. To learn more about self-hosting, guide *coming soon*. } diff --git a/lib/telegram/commands/joinfed.ts b/lib/telegram/commands/joinfed.ts index 1ca6e4e..1fd0f2a 100644 --- a/lib/telegram/commands/joinfed.ts +++ b/lib/telegram/commands/joinfed.ts @@ -5,9 +5,10 @@ import langJson from "../assets/lang.json"; const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); var myBot; +var myQueue; myCache.on("expired",function(key,value){ - myBot.deleteMessage(value, key); + myQueue.add(async () => {try{await myBot.deleteMessage(value, key)}catch{}}); }); /* @@ -15,27 +16,33 @@ myCache.on("expired",function(key,value){ */ const regexp = /\/joinfed\s?(.+)?/ -const callback = async (db: any, settings: groupSettings, bot: any, botId: string, msg: any, match: string[]) => { +const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: string, msg: any, match: string[]) => { try{ + if (!myBot) + myBot = bot + if (!myQueue) + myQueue = queue if (!match[1]){ - const resp = bot.sendMessage(settings.channelID, `Please specify a federation eg. \`/joinfed \`.`,msg.chat.is_forum? { + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(settings.channelID, `Please specify a federation eg. \`/joinfed \`.`,msg.chat.is_forum? { message_thread_id: msg.message_thread_id, - parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); + parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}) + return val}catch{}}); myCache.set(resp.message_id, msg.chat.id) } else{ - const name = getFederationName(db, 'telegram',String(Number(match[1]))) + const name = getFederationName(db, 'telegram',match[1]) if (!name){ - const resp = bot.sendMessage(settings.channelID, `Federation not found. The federation id of any group can be found by sending \`/fedinfo\` in a group.`,msg.chat.is_forum? { + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(settings.channelID, `Federation not found. Use /fedinfo in a group whose federation you want to join to find its ID.`,msg.chat.is_forum? { message_thread_id: msg.message_thread_id, - parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); + parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}) + return val}catch{}}); myCache.set(resp.message_id, msg.chat.id) } - else if (msg.from.id === match[1]){ - bot.sendMessage(settings.channelID, `Your group is now a member of the *${name}* Federation. Reputation extends through all member communities.`,msg.chat.is_forum? {message_thread_id: msg.message_thread_id,parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); + else if (msg.from.id == match[1]){ + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `Your group is now part of the *${name}* federation.`,msg.chat.is_forum? {message_thread_id: msg.message_thread_id,parse_mode: 'Markdown'}:{parse_mode: 'Markdown'})}catch{}}); joinFederation(db, 'telegram', String(msg.chat.id), match[1]) } else{ - bot.sendMessage(settings.channelID, `Your group is now a following of the *${name}* Federation. The reputation of users in groups of the federation extend to this group.`,msg.chat.is_forum? {message_thread_id: msg.message_thread_id,parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `Your group is now following the *${name}* federation.`,msg.chat.is_forum? {message_thread_id: msg.message_thread_id,parse_mode: 'Markdown'}:{parse_mode: 'Markdown'})}catch{}}); followFederation(db, 'telegram', String(msg.chat.id), match[1]) } } diff --git a/lib/telegram/commands/leavefed.ts b/lib/telegram/commands/leavefed.ts index 03e3c13..f468e1c 100644 --- a/lib/telegram/commands/leavefed.ts +++ b/lib/telegram/commands/leavefed.ts @@ -8,10 +8,10 @@ import langJson from "../assets/lang.json"; */ const regexp = /\/leavefed/ -const callback = async (db: any, settings: groupSettings, bot: any, botId: string, msg: any, match: string[]) => { +const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: string, msg: any, match: string[]) => { try{ leaveFederation(db, 'telegram', String(msg.chat.id), String(msg.from.id)) - bot.sendMessage(msg.chat.id, 'Your group has left the federation.', msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, 'Your group has left the federation.', msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{})}catch{}}) } catch(e){ console.log(e) } diff --git a/lib/telegram/commands/newfed.ts b/lib/telegram/commands/newfed.ts index ea1ff97..1bb3de3 100644 --- a/lib/telegram/commands/newfed.ts +++ b/lib/telegram/commands/newfed.ts @@ -5,9 +5,10 @@ import langJson from "../assets/lang.json"; const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); var myBot; +var myQueue; myCache.on("expired",function(key,value){ - myBot.deleteMessage(value, key); + myQueue.add(async () => {try{await myBot.deleteMessage(value, key)}catch{}}); }); /* @@ -15,9 +16,12 @@ myCache.on("expired",function(key,value){ */ const regexp = /\/newfed\s?(.+)?/ -const callback = async (db: any, settings: groupSettings, bot: any, botId: string, msg: any, match: string[]) => { +const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: string, msg: any, match: string[]) => { try{ - myBot = bot + if (!myBot) + myBot = bot + if (!myQueue) + myQueue = queue if (msg.chat.type !== "private"){ const opts = msg.chat.is_forum? { message_thread_id: msg.message_thread_id, @@ -45,29 +49,30 @@ const callback = async (db: any, settings: groupSettings, bot: any, botId: strin ] } } - const resp = await bot.sendMessage(msg.chat.id, `DM me for help with your federation : )`, opts); + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `DM me for help with your federation : )`, opts) + return val}catch{}}); myCache.set(resp.message_id, msg.chat.id) return; } - const name = getFederationName(db, 'telegram',msg.from.id); + const name = getFederationName(db, 'telegram',String(msg.from.id)); console.log(name) if (name){ - bot.sendMessage(settings.channelID, `Your federation *${name}* with id \`${msg.from.id}\` already exists.`,msg.chat.is_forum? { + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `Your federation *${name}* with id \`${msg.from.id}\` already exists.`,msg.chat.is_forum? { message_thread_id: msg.message_thread_id, - parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); + parse_mode: 'Markdown'}:{parse_mode: 'Markdown'})}catch{}}); return } if (!match[1]){ - bot.sendMessage(settings.channelID, `Please name your federation eg: \`/newfed My New Federation\``,msg.chat.is_forum? { + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `Please name your federation eg: \`/newfed My New Federation\``,msg.chat.is_forum? { message_thread_id: msg.message_thread_id, - parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); + parse_mode: 'Markdown'}:{parse_mode: 'Markdown'})}catch{}}); return } else{ const name = match[1].substring(0,65) setFederation(db, 'telegram',name, String(msg.from.id)) - bot.sendMessage(settings.channelID, `Your new federation is called *${match[1].substring(0,65)}* with id ${msg.from.id}. You can add groups to your federation by sending \`/joinfed ${msg.from.id}\` in each group.`,msg.chat.is_forum? { + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `Your new federation is called *${match[1].substring(0,65)}* with id ${msg.from.id}. You can add groups to your federation by sending \`/joinfed ${msg.from.id}\` in each group.\n\nIt is highly reccomended to create a notification channel for your federation with \`/setfedchannel\` so moderation can easily be monitored throughout the federation in one place.`,msg.chat.is_forum? { message_thread_id: msg.message_thread_id, - parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}); + parse_mode: 'Markdown'}:{parse_mode: 'Markdown'})}catch{}}); } //joinFederation(db, 'telegram', String(msg.chat.id), String(msg.from.id)) //bot.sendMessage(msg.chat.id, 'Your group has joined the federation.', msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) diff --git a/lib/telegram/commands/report.ts b/lib/telegram/commands/report.ts index d7db3cf..611bc65 100644 --- a/lib/telegram/commands/report.ts +++ b/lib/telegram/commands/report.ts @@ -15,24 +15,32 @@ const myCache = new NodeCache( { stdTTL: 900, checkperiod: 1200 } ); const myCacheGarbageCollection = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); const myCacheGarbageCollectionSlow = new NodeCache( { stdTTL: 900, checkperiod: 1200 } ); var myBot; +var myQueue; myCacheGarbageCollection.on("expired",function(key,value){ - myBot.deleteMessage(value, key); + myQueue.add(async () => {try{await myBot.deleteMessage(value, key)}catch{}}); }); myCacheGarbageCollectionSlow.on("expired",function(key,value){ - myBot.deleteMessage(value, key); + myQueue.add(async () => {try{await myBot.deleteMessage(value, key)}catch{}}); }); -const callback = async (db:any, settings: groupSettings, bot: any, botId: number, msg: any, match: string[]) => { +const callback = async (queue: any, db:any, settings: groupSettings, bot: any, botId: number, msg: any, match: string[]) => { try{ - myBot = bot + if(msg.text.substring(0,11) === '/reportinfo') + return + if (!myBot) + myBot = bot + if (!myQueue) + myQueue = queue if (!msg.reply_to_message) { - const resp = await bot.sendMessage(msg.chat.id, `/report ${langJson[settings.lang].errorReply}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `/report ${langJson[settings.lang].errorReply}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + return val}catch{}}); myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return; } if (msg.reply_to_message.date < Date.now()/1000-86400*7){ - const resp = await bot.sendMessage(msg.chat.id, `Live and let live. This message is more than one week old. The future is asynchronous, but we believe moderation should not be punitive. Next time try to make the report sooner.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `Live and let live. This message is more than one week old. The future is asynchronous, but we believe moderation should not be punitive. Next time try to make the report sooner.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + return val}catch{}}); myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return; } @@ -42,18 +50,22 @@ const callback = async (db:any, settings: groupSettings, bot: any, botId: number if (msg.reply_to_message.from.is_bot){ let resp; if(msg.reply_to_message.from.username === "GroupAnonymousBot") - resp = await bot.sendMessage(msg.chat.id, `User is anonymous. Ask admins to disable anonymouse admins to moderate admin behavior.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `User is anonymous. Ask admins to disable anonymouse admins to moderate admin behavior.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + return val}catch{}}); else - resp = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.errorModBot}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.errorModBot}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + return val}catch{}}); myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return } let report: TelegramBot.ChatMember if(!settings.admin_reportable){ - report = await bot.getChatMember(msg.chat.id,msg.reply_to_message.from.id) + report = await queue.add(async () => {try{const val = await bot.getChatMember(msg.chat.id,msg.reply_to_message.from.id) + return val}catch{}}) if(report.status === "administrator" || report.status === "creator"){ - const resp = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.errorAdmin}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.errorAdmin}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + return val}catch{}}); myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return } @@ -66,13 +78,15 @@ const callback = async (db:any, settings: groupSettings, bot: any, botId: number const cachedReportRequestMessage = myCache.get([msg.chat.id, msg.reply_to_message.message_id].toString()) if (cachedReportRequestMessage){ // message already reported const msgLinkReport = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + cachedReportRequestMessage; - const resp = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.reported}(${msgLinkReport})`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.reported}(${msgLinkReport})`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}) + return val}catch{}}); myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return; } const reportedQuestionId = getQuestionId(db, 'telegram', String(msg.chat.id), reportedUserID, String(msg.reply_to_message.message_id)); if (reportedQuestionId){ - const resp = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.reported}(https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${reportedQuestionId})`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true}); + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.reported}(https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${reportedQuestionId})`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true}) + return val}catch{}}); myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return; } @@ -82,23 +96,27 @@ const callback = async (db:any, settings: groupSettings, bot: any, botId: number const rules = getRule(db, 'telegram', String(msg.chat.id), msg.reply_to_message.date); if (!rules){ - const resp = await bot.sendMessage(msg.chat.id, langJson[settings.lang].report.norules, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].report.norules, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + return val}catch{}}); myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return; } - const evidencepath = await upload(bot, settings.lang, msg); + const evidencepath = await upload(queue, bot, settings.lang, msg); const msgBackup = 'https://ipfs.kleros.io'+evidencepath; // TODO report const reportAllowance = getAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id)); - if(!settings.admin_reportable && (report.status === "administrator" || report.status === "creator")){ - + const reporter = await queue.add(async () => {try{const val = await bot.getChatMember(msg.chat.id,msg.from.id) + return val}catch{}}) + if(!settings.admin_reportable && (reporter.status === "administrator" || reporter.status === "creator")){ + console.log(report.status) } else if (!reportAllowance){ setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), 2, 15, currentTimeMs); } else if (currentTimeMs < reportAllowance.timestamp_refresh + 28800 && reportAllowance.report_allowance == 0 ){ - const resp = await bot.sendMessage(msg.chat.id, langJson[settings.lang].report.noallowance, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].report.noallowance, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + return val}catch{}}); myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return; } else{ @@ -139,7 +157,8 @@ const callback = async (db:any, settings: groupSettings, bot: any, botId: number } }; const msgLink = `https://t.me/c/${String(msg.chat.id).substring(4)}/${msg.chat.is_forum? `${msg.message_thread_id}/`:''}${msg.reply_to_message.message_id}`; - const reportRequestMsg: TelegramBot.Message = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].socialConsensus.consensus2} [${fromUsername}](tg://user?id=${reportedUserID}) ${langJson[settings.lang].socialConsensus.consensus3}(${rules}) ${langJson[settings.lang].socialConsensus.consensus4}(${msgLink}) ([${langJson[settings.lang].socialConsensus.consensus5}](${msgBackup}))?`, msg.chat.is_forum? optsThread: opts); + const reportRequestMsg: TelegramBot.Message = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].socialConsensus.consensus2} [${fromUsername}](tg://user?id=${reportedUserID}) ${langJson[settings.lang].socialConsensus.consensus3}(${rules}) ${langJson[settings.lang].socialConsensus.consensus4}(${msgLink}) ([${langJson[settings.lang].socialConsensus.consensus5}](${msgBackup}))?`, msg.chat.is_forum? optsThread: opts) + return val}catch{}}); myCache.set([msg.chat.id, msg.reply_to_message.message_id].toString(),`${msg.chat.is_forum? `${msg.message_thread_id}/${reportRequestMsg.message_id}`:''}${reportRequestMsg.message_id}`) ; myCacheGarbageCollectionSlow.set(reportRequestMsg.message_id, msg.chat.id) return; @@ -147,13 +166,14 @@ const callback = async (db:any, settings: groupSettings, bot: any, botId: number console.log(e) } } -const reportMsg = async (settings: groupSettings, db: any, bot: any, msg: any, fromUsername: string, reportedUserID: string, rules: string, msgId: string, msgBackup: string, reportedBy: string, batchedSend: any) => { +const reportMsg = async (queue: any, settings: groupSettings, db: any, bot: any, msg: any, fromUsername: string, reportedUserID: string, rules: string, msgId: string, msgBackup: string, reportedBy: string, batchedSend: any) => { try { var inviteURL = myCache.get(msg.chat.id) if (!inviteURL){ inviteURL = getInviteURL(db, 'telegram', String(msg.chat.id)); if (!inviteURL){ - inviteURL = await bot.exportChatInviteLink(msg.chat.id); + inviteURL = await queue.add(async () => {try{const val = await bot.exportChatInviteLink(msg.chat.id) + return val}catch{}}); setInviteURL(db, 'telegram', String(msg.chat.id), inviteURL); } myCache.set(msg.chat.id, inviteURL) @@ -182,12 +202,12 @@ const reportMsg = async (settings: groupSettings, db: any, bot: any, msg: any, f addReport(db, questionId, 'telegram', String(msg.chat.id), reportedUserID, fromUsername , (msg.chat.is_forum? `${msg.message_thread_id}/`:'')+String(msg.reply_to_message.message_id), msg.reply_to_message.date,evidenceIndex, msgBackup); - bot.sendMessage(settings.channelID, `[${fromUsername}](tg://user?id=${reportedUserID})'s conduct due to this [message](${msgLink}) ([backup](${msgBackup})) is reported for breaking the [rules](${rules}).\n\nDid *${fromUsername}* break the rules? The [question](${appealUrl}) can be answered with a minimum bond of 5 DAI. Need assistance answering the question? [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpgnosis) me for help : )\n\nTo save a record, reply to messages you want saved with \`/addevidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `[${fromUsername}](tg://user?id=${reportedUserID})'s conduct due to this [message](${msgLink}) ([backup](${msgBackup})) is reported for breaking the [rules](${rules}).\n\nDid *${fromUsername}* break the rules? The [question](${appealUrl}) can be answered with a minimum bond of 5 DAI. Need assistance answering the question? [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpgnosis) me for help : )\n\nTo save a record, reply to messages you want saved with \`/evidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); return questionId; } catch (e) { console.log(e); try{ - bot.sendMessage(msg.chat.id, `${langJson[settings.lang].errorTxn}. ${e.reason}. `,msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].errorTxn}. ${e.reason}. `,msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {})}catch{}}); } catch(e){ console.log(e) } diff --git a/lib/telegram/commands/setChannel.ts b/lib/telegram/commands/setChannel.ts index fd1e353..8cf1508 100644 --- a/lib/telegram/commands/setChannel.ts +++ b/lib/telegram/commands/setChannel.ts @@ -1,14 +1,14 @@ import * as TelegramBot from "node-telegram-bot-api"; import {groupSettings} from "../../../types"; import {setChannelID, setInviteURLChannel} from "../../db"; -import {validateUrl} from "./setRules"; import langJson from "../assets/lang.json"; const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); var myBot; +var myQueue; myCache.on("expired",function(key,value){ - myBot.deleteMessage(value, key); + myQueue.add(async () => {try{await myBot.deleteMessage(value, key)}catch{}}); }); /* * /setchannel [public channel name] @@ -16,54 +16,70 @@ myCache.on("expired",function(key,value){ const regexp = /\/setchannel/ const regexpFull = /\/setchannel (.+)/ -const callback = async (db: any, settings: groupSettings, bot: TelegramBot, botId: string, msg: any, match: string[], batchedSend: any) => { +const callback = async (queue: any, db: any, settings: groupSettings, bot: TelegramBot, botId: string, msg: any, match: string[], batchedSend: any) => { try { if (msg.chat.is_fourm) return + if (msg.text.substring(0,14) === "/setchannelfed") + return + if (!myBot) + myBot = bot + if (!myQueue) + myQueue = queue const newmatch = msg.text.match(regexpFull); if (!newmatch || newmatch.length < 2){ - const resp = await bot.sendMessage(msg.chat.id, `/setchannel must be followed by a channel id. [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpnotifications) me if you need more help : )`, {parse_mode: "Markdown", disable_web_page_preview: true}); + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `/setchannel must be followed by a channel id. [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpnotifications) me if you need more help : )`, {parse_mode: "Markdown", disable_web_page_preview: true}) + return val}catch{}}); myCache.set(resp.message_id, msg.chat.id) return; } try{ - const channel = await bot.getChat(newmatch[1]); + const channel = await queue.add(async () => {try{const val = await bot.getChat(newmatch[1]) + return val}catch{}}); if(channel.type !== "channel"){ - const resp = await bot.sendMessage(msg.chat.id, '/setchannel must be followed by a valid channel.'); + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, '/setchannel must be followed by a valid channel.') + return val}catch{}}); myCache.set(resp.message_id, msg.chat.id) return; } } catch(e){ try{ - const resp = await bot.sendMessage(msg.chat.id, `${newmatch[1]} is not a valid channel.`); + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${newmatch[1]} is not a valid channel.`) + return val}catch{}}); myCache.set(resp.message_id, msg.chat.id) } catch(e){ console.log(e) } return; } - const channelUser = await bot.getChatMember(newmatch[1], String(msg.from.id)); + const channelUser = await queue.add(async () => {try{const val = await bot.getChatMember(newmatch[1], String(msg.from.id)) + return val}catch{}}); if(channelUser.status !== "administrator" && channelUser.status !== "creator"){ - const resp = await bot.sendMessage(msg.chat.id, 'You are not an authorized admin of the channel.'); + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, 'You are not an authorized admin of the channel.') + return val}catch{}}); myCache.set(resp.message_id, msg.chat.id) return; } - const channelUserSusie = await bot.getChatMember(newmatch[1], botId); + const channelUserSusie = await queue.add(async () => {try{const val = await bot.getChatMember(newmatch[1], botId) + return val}catch{}}); if (channelUserSusie.status !== "administrator"){ - const resp = await bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {caption: langJson[settings.lang].errorAdminRights}); + const resp = await queue.add(async () => {try{const val = await bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {caption: langJson[settings.lang].errorAdminRights}) + return val}catch{}}); myCache.set(resp.message_id, msg.chat.id) return; } if(!channelUserSusie.can_invite_users){ - const resp = await bot.sendMessage(msg.chat.id, 'Susie must be able to invite users to the channel.'); + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, 'Susie must be able to invite users to the channel.') + return val}catch{}}); myCache.set(resp.message_id, msg.chat.id) return; } - const invite_url_channel = await bot.exportChatInviteLink(newmatch[1]); + const invite_url_channel = await queue.add(async () => {try{const val = await bot.exportChatInviteLink(newmatch[1]) + return val}catch{}}); setInviteURLChannel(db, 'telegram', String(msg.chat.id), invite_url_channel); setChannelID(db, 'telegram', String(msg.chat.id), newmatch[1]); - bot.sendMessage(msg.chat.id, `Moderation notifications will now be sent to this [channel](${invite_url_channel}).`, {parse_mode: "Markdown"}); - bot.sendMessage(newmatch[1], `This channel will now relay moderation notifications for ${msg.chat.title}`, {parse_mode: "Markdown"}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `Moderation notifications will now be sent to this [channel](${invite_url_channel}).`, {parse_mode: "Markdown"})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(newmatch[1], `This channel will now relay moderation notifications for ${msg.chat.title}`, {parse_mode: "Markdown"})}catch{}}); } catch (error) { console.log(error); } diff --git a/lib/telegram/commands/setChannelFed.ts b/lib/telegram/commands/setChannelFed.ts new file mode 100644 index 0000000..c145f59 --- /dev/null +++ b/lib/telegram/commands/setChannelFed.ts @@ -0,0 +1,93 @@ +import * as TelegramBot from "node-telegram-bot-api"; +import {groupSettings} from "../../../types"; +import {setFederationChannelID, setFederationInviteURLChannel,getFederationName} from "../../db"; +import {validateUrl} from "./setRules"; +import langJson from "../assets/lang.json"; +const NodeCache = require( "node-cache" ); +const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); +var myBot; +var myQueue; + +myCache.on("expired",function(key,value){ + myQueue.add(async () => {try{await myBot.deleteMessage(value, key)}catch{}}); + }); +/* + * /setchannelfed + */ +const regexp = /\/setfedchannel/ +const regexpFull = /\/setfedchannel (.+)/ + +const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: string, msg: any, match: string[], batchedSend: any) => { + try { + if (!myBot) + myBot = bot + if (!myQueue) + myQueue = queue + const name = getFederationName(db,'telegram',String(msg.from.id)) + if (!name){ + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `No federation found. Please first create a federation with \`/newfed\``,msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown', disable_web_page_preview: true} : {parse_mode: 'Markdown', disable_web_page_preview: true}) + return val}catch{}}); + myCache.set(resp.message_id, msg.chat.id) + return; + } + const newmatch = msg.text.match(regexpFull); + if (!newmatch || newmatch.length < 2){ + console.log(msg) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `/setchannelfed must be followed by a channel id. [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpnotifications) me if you need more help : )`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown', disable_web_page_preview: true} : {parse_mode: 'Markdown', disable_web_page_preview: true}) + return val}catch{}}); + myCache.set(resp.message_id, msg.chat.id) + return; + } + try{ + const channel = await queue.add(async () => {try{const val = await bot.getChat(newmatch[1]) + return val}catch{}}); + if(channel.type !== "channel"){ + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, '/setchannelfed must be followed by a valid channel.', msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) + return val}catch{}}); + myCache.set(resp.message_id, msg.chat.id) + return; + } + } catch(e){ + try{ + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${newmatch[1]} is not a valid channel.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) + return val}catch{}}); + myCache.set(resp.message_id, msg.chat.id) + } catch(e){ + console.log(e) + } + return; + } + const channelUser = await queue.add(async () => {try{const val = await bot.getChatMember(newmatch[1], String(msg.from.id)) + return val}catch{}}); + if(channelUser.status !== "administrator" && channelUser.status !== "creator"){ + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, 'You are not an authorized admin of the channel.',msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) + return val}catch{}}); + myCache.set(resp.message_id, msg.chat.id) + return; + } + const channelUserSusie = await queue.add(async () => {try{const val = await bot.getChatMember(newmatch[1], botId) + return val}catch{}}); + if (channelUserSusie.status !== "administrator"){ + const resp = await queue.add(async () => {try{const val = await bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {caption: langJson[settings.lang].errorAdminRights},msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) + return val}catch{}}); + myCache.set(resp.message_id, msg.chat.id) + return; + } + if(!channelUserSusie.can_invite_users){ + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, 'Susie must be able to invite users to the channel.',msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) + return val}catch{}}); + myCache.set(resp.message_id, msg.chat.id) + return; + } + const invite_url_channel = await queue.add(async () => {try{const val = await bot.exportChatInviteLink(newmatch[1]) + return val}catch{}}); + setFederationInviteURLChannel(db, 'telegram', String(msg.chat.id), invite_url_channel); + setFederationChannelID(db, 'telegram', String(msg.chat.id), newmatch[1]); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `Moderation notifications for the federation will now be sent to this [channel](${invite_url_channel}).`, {parse_mode: "Markdown"})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(newmatch[1], `This channel will now relay moderation notifications for the federation *${name}*`, {parse_mode: "Markdown"})}catch{}}); + } catch (error) { + console.log(error); + } +} + +export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/setLanguage.ts b/lib/telegram/commands/setLanguage.ts index 6975f26..55c5c51 100644 --- a/lib/telegram/commands/setLanguage.ts +++ b/lib/telegram/commands/setLanguage.ts @@ -8,15 +8,15 @@ import { groupSettings } from "../../../types"; const regexp = /\/setlanguage/ const regexpFull = /\/setlanguage (.+)/ -const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { +const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { const match = msg.text.match(regexpFull); const langCode = match? match[1].toLowerCase(): ''; if (langJson[langCode]) { - setLanguageConfirm(db, bot, settings, langCode, msg) + setLanguageConfirm(queue, db, bot, settings, langCode, msg) } else { const errorLanguage = `The language you requested is not yet available. Head to @KlerosModerateNews or @linguoKleros for information on how to add more translations!` - await bot.sendMessage(msg.chat.id, errorLanguage, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, errorLanguage, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {})}catch{}}) const opts = msg.chat.is_forum? { message_thread_id: msg.message_thread_id, parse_mode: 'Markdown', @@ -43,20 +43,22 @@ const callback = async (db: any, settings: groupSettings, bot: any, botId: numbe ] } } - await bot.sendMessage(msg.chat.id,'List of available languages',opts) + queue.add(async () => {try{await bot.sendMessage(msg.chat.id,'List of available languages',opts)}catch{}}) } } -const setLanguageConfirm = async (db: any, bot: any, settings: groupSettings, langCode: string, msg: any) => { +const setLanguageConfirm = async (queue: any, db: any, bot: any, settings: groupSettings, langCode: string, msg: any) => { try{ - bot.deleteMessage(msg.chat.id, String(msg.message_id)) + queue.add(async () => {try{await bot.deleteMessage(msg.chat.id, String(msg.message_id))}catch{}}) setLang(db, 'telegram', String(msg.chat.id),langCode); setRules(db, 'telegram', String(msg.chat.id), langJson[langCode].defaultRules, Math.floor(Date.now()/1000)); - bot.sendMessage(msg.chat.id, langJson[langCode].confirmationLanguage, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[langCode].confirmationLanguage, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {})}catch{}}); if (msg.chat.is_forum){ - const msgDefaultRules = await bot.sendMessage(msg.chat.id, `${langJson[langCode].defaultRulesMsg1}(${langJson[langCode].defaultRules}). ${langJson[langCode].defaultRulesMsg2}.`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: settings.thread_id_rules}: {}) - const msgRules = await bot.forwardMessage(msg.chat.id, msg.chat.id, msgDefaultRules.message_id, {message_thread_id: settings.thread_id_rules}); - bot.pinChatMessage(msg.chat.id, msgRules.message_id, {message_thread_id: settings.thread_id_rules}) + const msgDefaultRules = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[langCode].defaultRulesMsg1}(${langJson[langCode].defaultRules}). ${langJson[langCode].defaultRulesMsg2}.`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: settings.thread_id_rules}: {}) + return val}catch{}}) + const msgRules = await queue.add(async () => {try{const val = await bot.forwardMessage(msg.chat.id, msg.chat.id, msgDefaultRules.message_id, {message_thread_id: settings.thread_id_rules}) + return val}catch{}}); + queue.add(async () => {try{await bot.pinChatMessage(msg.chat.id, msgRules.message_id, {message_thread_id: settings.thread_id_rules})}catch{}}) } } catch(e){ console.log('setLanguageConfirm error '+e); diff --git a/lib/telegram/commands/setRules.ts b/lib/telegram/commands/setRules.ts index 5daaf38..f51725c 100644 --- a/lib/telegram/commands/setRules.ts +++ b/lib/telegram/commands/setRules.ts @@ -18,26 +18,28 @@ const validateUrl = (s: string): boolean => { } }; -const callback = async (db: any, settings: groupSettings, bot: any, botId: string, msg: any, match: string[]) => { +const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: string, msg: any, match: string[]) => { try{ if (msg.reply_to_message && !msg.reply_to_message.forum_topic_created) { const enc = new TextEncoder(); const rulesPath = await ipfsPublish('rules.txt', enc.encode(msg.reply_to_message.text)) setRules(db, 'telegram', String(msg.chat.id), 'https://ipfs.kleros.io'+rulesPath, new Date().getTime()/1000); - bot.sendMessage(msg.chat.id, `The community rules are [updated](https://ipfs.kleros.io${rulesPath}).`, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules, parse_mode: 'Markdown'}: {parse_mode: "Markdown"}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `The community rules are [updated](https://ipfs.kleros.io${rulesPath}).`, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules, parse_mode: 'Markdown'}: {parse_mode: "Markdown"})}catch{}}); if(msg.chat.is_forum){ - const msgRules = await bot.forwardMessage(msg.chat.id, msg.chat.id, msg.reply_to_message.message_id, {message_thread_id: settings.thread_id_rules}); - bot.pinChatMessage(msg.chat.id, msgRules.message_id, {message_thread_id: settings.thread_id_rules}) + const msgRules = await queue.add(async () => {try{const val = await bot.forwardMessage(msg.chat.id, msg.chat.id, msg.reply_to_message.message_id, {message_thread_id: settings.thread_id_rules}) + return val}catch{}}); + queue.add(async () => {try{await bot.pinChatMessage(msg.chat.id, msgRules.message_id, {message_thread_id: settings.thread_id_rules})}catch{}}) } } else if (validateUrl(match[1])) { setRules(db, 'telegram', String(msg.chat.id), match[1], Math.floor(new Date().getTime()/1000)); if(msg.chat.is_forum){ - const msgRules = await bot.forwardMessage(msg.chat.id, msg.chat.id, msg.message_id, {message_thread_id: settings.thread_id_rules}); - bot.pinChatMessage(msg.chat.id, msgRules.message_id, {message_thread_id: settings.thread_id_rules}) + const msgRules = await queue.add(async () => {try{const val = await bot.forwardMessage(msg.chat.id, msg.chat.id, msg.message_id, {message_thread_id: settings.thread_id_rules}) + return val}catch{}}); + queue.add(async () => {try{await bot.pinChatMessage(msg.chat.id, msgRules.message_id, {message_thread_id: settings.thread_id_rules})}catch{}}) } - await bot.sendMessage(msg.chat.id, langJson[settings.lang].rulesUpdated, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules}: {}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[settings.lang].rulesUpdated, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules}: {})}catch{}}); } else { - await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorRules, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules}: {}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorRules, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules}: {})}catch{}}); } } catch(e){ console.log(e) diff --git a/lib/telegram/commands/socialConsensus.ts b/lib/telegram/commands/socialConsensus.ts index 202562b..544bc0d 100644 --- a/lib/telegram/commands/socialConsensus.ts +++ b/lib/telegram/commands/socialConsensus.ts @@ -11,7 +11,7 @@ var botAddress: string; * social consensus callback */ -const callback = async (db: any, settings: groupSettings, bot: TelegramBot, callbackQuery: TelegramBot.CallbackQuery, batchedSend: any) => { +const callback = async (queue: any, db: any, settings: groupSettings, bot: TelegramBot, callbackQuery: TelegramBot.CallbackQuery, batchedSend: any) => { if(!botAddress) botAddress = await (await new Wallet(process.env.PRIVATE_KEY)).address.toLowerCase(); @@ -54,13 +54,14 @@ const callback = async (db: any, settings: groupSettings, bot: TelegramBot, call } try{ if (newConfirmations > 1){ - bot.editMessageReplyMarkup({ inline_keyboard: []}, optsFinal) - bot.editMessageText("User Reported.",optsFinal) - const user = (await bot.getChatMember(String(msg.chat.id), String(calldata[1]))).user; + queue.add(async () => {try{await bot.editMessageReplyMarkup({ inline_keyboard: []}, optsFinal)}catch{}}) + queue.add(async () => {try{await bot.editMessageText("User Reported.",optsFinal)}catch{}}) + const user = (await queue.add(async () => {try{const val = await bot.getChatMember(String(msg.chat.id), String(calldata[1])) + return val}catch{}})).user; const fromUsername = user.username || user.first_name || `no-username-set`; - reportMsg(settings, db, bot, msg, fromUsername, String(calldata[1]), msg.entities[1].url, String(calldata[2]), msg.entities[3].url, calldata[3],batchedSend); + reportMsg(queue, settings, db, bot, msg, fromUsername, String(calldata[1]), msg.entities[1].url, String(calldata[2]), msg.entities[3].url, calldata[3],batchedSend); } else{ - bot.editMessageReplyMarkup(markdown, opts) + queue.add(async () => {try{await bot.editMessageReplyMarkup(markdown, opts)}catch{}}) } } catch(e){ console.log('social consensus error'+e); diff --git a/lib/telegram/commands/start.ts b/lib/telegram/commands/start.ts index 86335ea..17799b5 100644 --- a/lib/telegram/commands/start.ts +++ b/lib/telegram/commands/start.ts @@ -1,16 +1,66 @@ import * as TelegramBot from "node-telegram-bot-api"; -import {setThreadID, getThreadIDNotifications, setRules} from "../../db"; +import {setThreadID, getThreadIDNotifications, setRules,setTitle} from "../../db"; import langJson from "../assets/lang.json"; import {groupSettings} from "../../../types"; +const NodeCache = require( "node-cache" ); +const myCache = new NodeCache( { stdTTL: 180, checkperiod: 240 } ); +var myBot; +var myQueue; +myCache.on("expired",function(key,value){ + myQueue.add(async () => {try{await myBot.deleteMessage(value, key)}catch{}}); + }); /* * /start */ const regexp = /\/start/ -const callback = async (db: any, settings: groupSettings, bot: any, botID: string, msg: any) => { - // admin check +const callback = async (queue:any, db: any, settings: groupSettings, bot: any, botID: string, msg: any,match: string[], batchsend: any, skip_lang_check?: boolean) => { + // admin chek + if (!myBot) + myBot = bot + if (!myQueue) + myQueue = queue try{ + const lang_code = msg?.from?.language_code + if (msg.chat.type === "supergroup" && !skip_lang_check && lang_code !== 'en'){ + if(myCache.get(msg.chat.id)) + return + const opts = msg.chat.is_forum? { + parse_mode: 'Markdown', + message_thread_id: msg.message_thread_id, + disable_web_page_preview: true, + reply_markup: { + inline_keyboard: [ + [ + { + text: 'I understand', + callback_data: `6` + } + ] + ] + } + } : { + parse_mode: 'Markdown', + disable_web_page_preview: true, + reply_markup: { + inline_keyboard: [ + [ + { + text: 'I understand', + callback_data: `6` + } + ] + ] + } + } + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `My native language is English. I am learning new languages, starting with [Spanish](https://linguo.kleros.io/home). Please reach out to @SusieSupport to let me know which language I should learn next.\n\nTo continue, please understand that I can currently only effectively moderate communities in English.`, opts) + return val}catch{}}) + myCache.set(msg.chat.id,resp.message_id) + return; + } + + if (msg.chat.type === "private"){ const opts = { parse_mode: 'Markdown', @@ -25,47 +75,49 @@ const callback = async (db: any, settings: groupSettings, bot: any, botID: strin ] } } - bot.sendMessage(msg.chat.id, `Hi! My name is Susie, nice to meet you : ) + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `Hi! My name is Susie, nice to meet you : ) -I am a [Kleros Moderate](https://kleros.io/moderate) community manager at your service. Use the command /help to find out more about how to use me to my full potential. +I am a [Kleros Moderate](https://kleros.io/moderate) community manager at your service. Use /help to learn how to use me to my full potential. -Join my news channel @KlerosModerateNews to get information on all the latest updates.`, opts) +Join my news channel @KlerosModerateNews to get information on all the latest updates.`, opts)}catch{}}) return; } - const botUser = await bot.getChatMember(msg.chat.id, botID) + const botUser = await queue.add(async () => {try{const val = await bot.getChatMember(msg.chat.id, botID) + return val}catch{}}) if(botUser.status !== "administrator" || !botUser.can_restrict_members){ const video = msg.chat.is_forum? 'QmSdP3SDoHCdW739xLDBKM3gnLeeZug77RgwgxBJSchvYV/guide_topics.mp4' : 'QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4' - bot.sendVideo(msg.chat.id, `https://ipfs.kleros.io/ipfs/${video}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, caption: "Please give Susie full admin rights.\n\nThen try to /start community moderation again."} : {caption: "Please give Susie full admin rights.\n\nThen try to /start community moderation again."}); + queue.add(async () => {try{await bot.sendVideo(msg.chat.id, `https://ipfs.kleros.io/ipfs/${video}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, caption: "Please give Susie full admin rights.\n\nThen try to /start community moderation again."} : {caption: "Please give Susie full admin rights.\n\nThen try to /start community moderation again."})}catch{}}); return; } if (msg.chat.is_forum){ if(!botUser.can_manage_topics){ - bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmSdP3SDoHCdW739xLDBKM3gnLeeZug77RgwgxBJSchvYV/guide_topics.mp4', {message_thread_id: msg.message_thread_id, caption: "Susie needs permissions to manage topics to effectively moderate your community.\n\nThen try to /start community moderation again."}); + queue.add(async () => {try{await bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmSdP3SDoHCdW739xLDBKM3gnLeeZug77RgwgxBJSchvYV/guide_topics.mp4', {message_thread_id: msg.message_thread_id, caption: "Susie needs permissions to manage topics to effectively moderate your community.\n\nThen try to /start community moderation again."})}catch{}}); return; } const thread_ids = getThreadIDNotifications(db, 'telegram', String(msg.chat.id)); if (thread_ids){ - bot.sendMessage(msg.chat.id, "Already started.", {message_thread_id: msg.message_thread_id}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, "Already started.", {message_thread_id: msg.message_thread_id})}catch{}}); return } - console.log(msg); - await topicMode(db,bot,settings,msg.chat); + await topicMode(queue, db,bot,settings,msg.chat); } + console.log(msg.chat.id) + //setTitle(db, 'telegram', String(msg.chat.id), msg.chat.title) setRules(db, 'telegram', String(msg.chat.id), langJson[settings.lang].defaultRules, Math.floor(Date.now()/1000)); - bot.sendMessage(msg.chat.id, `Hi! My community moderation tools are at your service. [DM](https://t.me/${process.env.BOT_USERNAME}?start=help) me to find out more about how to use me to my full potential : ) + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `Hi! My community moderation tools are at your service. [DM](https://t.me/${process.env.BOT_USERNAME}?start=help) me to find out more about how to use me to my full potential : ) - Use /setrules to change the default [rules](${langJson[settings.lang].defaultRules}). - User reports are made by replying to a message with /report -- Penalties progress from 1 day to 1 week, and 1 year bans for each violation.`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id, disable_web_page_preview: true}: {parse_mode: "Markdown", disable_web_page_preview: true}) +- Penalties progress from 1 day to 1 week, and 1 year bans for each violation.`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id, disable_web_page_preview: true}: {parse_mode: "Markdown", disable_web_page_preview: true})}catch{}}) return; } catch (e){ try{ if (msg.chat.is_forum){ - bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmSdP3SDoHCdW739xLDBKM3gnLeeZug77RgwgxBJSchvYV/guide_topics.mp4', {message_thread_id: msg.message_thread_id, caption: "Must have can manage topics"}); + queue.add(async () => {try{await bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmSdP3SDoHCdW739xLDBKM3gnLeeZug77RgwgxBJSchvYV/guide_topics.mp4', {message_thread_id: msg.message_thread_id, caption: "Must have can manage topics"})}catch{}}); } else{ - bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {caption: langJson[settings.lang].errorAdminRights+"Topics must be enabled"}); + queue.add(async () => {try{await bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {caption: langJson[settings.lang].errorAdminRights+"Topics must be enabled"})}catch{}}); } } catch (e){ console.log(e) @@ -73,15 +125,15 @@ Join my news channel @KlerosModerateNews to get information on all the latest up } } -const topicMode = async (db:any, bot: any, settings: groupSettings, chat: TelegramBot.Chat): Promise<[string,string]> => { +const topicMode = async (queue: any, db:any, bot: any, settings: groupSettings, chat: TelegramBot.Chat): Promise<[string,string]> => { // tg bugging, won't display icon_color if set - const topicRules = await bot.createForumTopic(chat.id, 'Rules', {icon_custom_emoji_id: '4929691942553387009'}); - const topicModeration = await bot.createForumTopic(chat.id, 'Moderation Notifications', {icon_custom_emoji_id: '4929336692923432961'}); + const topicRules = await queue.add(async () => {try{const val = await bot.createForumTopic(chat.id, 'Rules', {icon_custom_emoji_id: '4929691942553387009'})}catch{}}); + const topicModeration = await queue.add(async () => {try{const val = await bot.createForumTopic(chat.id, 'Moderation Notifications', {icon_custom_emoji_id: '4929336692923432961'})}catch{}}); - bot.sendMessage(chat.id, `Please follow the community [rules](${settings.rules}). Misbehavior can be reported with /report.`, {parse_mode: "Markdown", message_thread_id: topicRules.message_thread_id}); + queue.add(async () => {try{await bot.sendMessage(chat.id, `Please follow the community [rules](${settings.rules}). Misbehavior can be reported with /report.`, {parse_mode: "Markdown", message_thread_id: topicRules.message_thread_id})}catch{}}); //bot.sendMessage(chat_id, `${langJson[settings.lang].greeting2}(${settings.rules}). ${langJson[settings.lang].greeting3}`, {parse_mode: "Markdown", message_thread_id: topicRules.message_thread_id}); - bot.sendMessage(chat.id, `${langJson[settings.lang].greeting1}[Kleros Moderate](https://kleros.io/moderate/).`, {parse_mode: "Markdown", message_thread_id: topicModeration.message_thread_id}); - bot.closeForumTopic(chat.id, topicRules.message_thread_id) + queue.add(async () => {try{await bot.sendMessage(chat.id, `${langJson[settings.lang].greeting1}[Kleros Moderate](https://kleros.io/moderate/).`, {parse_mode: "Markdown", message_thread_id: topicModeration.message_thread_id})}catch{}}); + queue.add(async () => {try{await bot.closeForumTopic(chat.id, topicRules.message_thread_id)}catch{}}) setThreadID(db,'telegram',String(chat.id),String(topicRules.message_thread_id), String(topicModeration.message_thread_id)) return [topicRules.message_thread_id, topicModeration.message_thread_id] } diff --git a/lib/telegram/commands/toggleAdminReportable.ts b/lib/telegram/commands/toggleAdminReportable.ts index 396ed23..8503eb5 100644 --- a/lib/telegram/commands/toggleAdminReportable.ts +++ b/lib/telegram/commands/toggleAdminReportable.ts @@ -8,10 +8,10 @@ import {groupSettings} from "../../../types"; */ const regexp = /\/adminreportable/ -const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { +const callback = async (queue, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { try{ setAdminReportableMode(db, 'telegram', String(msg.chat.id),settings.admin_reportable? 0: 1) - bot.sendMessage(msg.chat.id, settings.admin_reportable? "Admins are immune from reports." : "Admins are now held accountable like regular users.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, settings.admin_reportable? "Admins are immune from reports." : "Admins are now held accountable like regular users.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {})}catch{}}); } catch(e){ console.log(e) } diff --git a/lib/telegram/commands/toggleCaptcha.ts b/lib/telegram/commands/toggleCaptcha.ts index a8a11e0..f22da4f 100644 --- a/lib/telegram/commands/toggleCaptcha.ts +++ b/lib/telegram/commands/toggleCaptcha.ts @@ -9,16 +9,16 @@ import {groupSettings} from "../../../types"; */ const regexp = /\/captcha/ -const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { +const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { try{ if (msg.chat.is_forum && !settings.thread_id_welcome){ - toggleWelcome.createWelcomeThread(db,settings,bot,msg) + toggleWelcome.createWelcomeThread(queue, db,settings,bot,msg) } setCaptchaMode(db, 'telegram', String(msg.chat.id),settings.captcha? 0: 1) // if toggling on captcha, turn on greetings if (!settings.captcha) setGreetingMode(db, 'telegram', String(msg.chat.id),1) - bot.sendMessage(msg.chat.id, settings.captcha? "Captcha is off." : "Captcha is on.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, settings.captcha? "Captcha is off." : "Captcha is on.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {})}catch{}}); } catch(e){ console.log(e) } diff --git a/lib/telegram/commands/toggleWelcome.ts b/lib/telegram/commands/toggleWelcome.ts index 4f160cf..b38b74d 100644 --- a/lib/telegram/commands/toggleWelcome.ts +++ b/lib/telegram/commands/toggleWelcome.ts @@ -8,22 +8,24 @@ import {groupSettings} from "../../../types"; */ const regexp = /\/welcome/ -const callback = async (db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { +const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { try{ if (msg.chat.is_forum && !settings.thread_id_welcome){ - await createWelcomeThread(db, settings,bot,msg) + await createWelcomeThread(queue, db, settings,bot,msg) } setGreetingMode(db, 'telegram', String(msg.chat.id),settings.greeting_mode? 0: 1) - bot.sendMessage(msg.chat.id, settings.greeting_mode? "Welcome messages are off." : "Welcome messages are on.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, settings.greeting_mode? "Welcome messages are off." : "Welcome messages are on.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {})}catch{}}); } catch(e){ console.log(e) } } -const createWelcomeThread = async (db: any, settings: groupSettings, bot: any, msg: any) => { - const topicWelcome = await bot.createForumTopic(msg.chat.id, 'Welcome', {icon_custom_emoji_id: '4929292553544531969'}); - const msg1: TelegramBot.Message = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].greeting1}[Kleros Moderate](https://kleros.io/moderate/).\n\nPlease treat this group with the same respect you would a public park. We, too, are a shared community resource — a place to share..`, {parse_mode: "Markdown", message_thread_id: topicWelcome.message_thread_id}); - bot.pinChatMessage(msg.chat.id, msg1.message_id, {message_thread_id: topicWelcome.message_thread_id}) +const createWelcomeThread = async (queue:any, db: any, settings: groupSettings, bot: any, msg: any) => { + const topicWelcome = await queue.add(async () => {try{const val = await bot.createForumTopic(msg.chat.id, 'Welcome', {icon_custom_emoji_id: '4929292553544531969'}) + return val}catch{}}); + const msg1: TelegramBot.Message = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].greeting1}[Kleros Moderate](https://kleros.io/moderate/).\n\nPlease treat this group with the same respect you would a public park. We, too, are a shared community resource — a place to share..`, {parse_mode: "Markdown", message_thread_id: topicWelcome.message_thread_id}) + return val}catch{}}); + queue.add(async () => {try{await bot.pinChatMessage(msg.chat.id, msg1.message_id, {message_thread_id: topicWelcome.message_thread_id})}catch{}}) setThreadIDWelcome(db, 'telegram', String(msg.chat.id), String(topicWelcome.message_thread_id)) } diff --git a/lib/telegram/commands/welcome.ts b/lib/telegram/commands/welcome.ts index 8d50802..f344a23 100644 --- a/lib/telegram/commands/welcome.ts +++ b/lib/telegram/commands/welcome.ts @@ -6,11 +6,11 @@ import {groupSettings} from "../../../types"; * Welcome Message */ -const callback = async (settings: groupSettings, bot: any, msg: any) => { +const callback = async (queue: any, settings: groupSettings, bot: any, msg: any) => { try { if (msg.old_chat_member.status !== "left") return; - bot.sendMessage(msg.chat.id, `${langJson[settings.lang].welcome}[Kleros Moderate](https://kleros.io/moderate/) bot. \n\n/start to begin community sourced moderation.`, msg.chat.is_forum? {parse_mode: "Markdown"} : {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].welcome}[Kleros Moderate](https://kleros.io/moderate/) bot. \n\n/start to begin community sourced moderation.`, msg.chat.is_forum? {parse_mode: "Markdown"} : {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"})}catch{}}); //const options = msg.chat.is_forum? {message_thread_id: msg.message_thread_id, caption: "To get started, give Susie admin rights."} : {caption: "To get started, give Susie admin rights."} //bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', options); } catch (error) { diff --git a/lib/telegram/index.ts b/lib/telegram/index.ts index c27c0a5..70880cb 100644 --- a/lib/telegram/index.ts +++ b/lib/telegram/index.ts @@ -6,6 +6,7 @@ import * as getRules from "../../lib/telegram/commands/getRules"; import * as getLeaderboard from "../../lib/telegram/commands/getLeaderboard"; import * as addEvidenceHelp from "../../lib/telegram/commands/addEvidenceHelp"; import * as report from "../../lib/telegram/commands/report"; +import * as fedinfo from "../../lib/telegram/commands/fedinfo"; import * as welcome from "../../lib/telegram/commands/welcome"; import * as toggleWelcome from "../../lib/telegram/commands/toggleWelcome"; import * as toggleAdminReportable from "../../lib/telegram/commands/toggleAdminReportable"; @@ -20,13 +21,16 @@ import * as joinFed from "../../lib/telegram/commands/joinfed"; import * as start from "../../lib/telegram/commands/start"; import * as setLanguage from "../../lib/telegram/commands/setLanguage"; import * as setChannel from "../../lib/telegram/commands/setChannel"; +import * as setChannelFed from "../../lib/telegram/commands/setChannelFed"; import * as getChannel from "../../lib/telegram/commands/getChannel"; import * as getReports from "../../lib/telegram/commands/getReports"; import langJson from "./assets/lang.json"; import {groupSettings, groupSettingsUnderspecified} from "../../types"; -import {openDb, getGroupSettings, getRule, getReportsUserInfo,getFederatedBanHistoryBase, getFederatedFollowingBanHistoryBase, getLocalBanHistoryBase, eraseThreadID} from "../db"; - +import {openDb, getGroupSettings, getRule, getReportsUserInfoActive,getFederatedBanHistory, getFederatedFollowingBanHistory, getLocalBanHistory, eraseThreadID} from "../db"; +import { calcPenalty } from "../cron"; const Web3 = require('web3') +const {default: PQueue} = require('p-queue'); +const queue = new PQueue({intervalCap: 20, interval: 1000,carryoverConcurrencyCount: true}); const _batchedSend = require('web3-batched-send') const web3 = new Web3(process.env.WEB3_PROVIDER_URL) const batchedSend = _batchedSend( @@ -49,7 +53,9 @@ const batchedSend = _batchedSend( federation_id_following: '' } const ModeratorBot = require('node-telegram-bot-api'); -const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: true, testEnvironment: true}); +const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: {params: {"allowed_updates": JSON.stringify(["my_chat_member", "chat_member", "message","callback_query", "new_chat_members", "inline_query"])}}, testEnvironment: true}); +//const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: true, testEnvironment: true}); + //bot. var botId: number; const db = openDb(); @@ -58,9 +64,10 @@ const myCache = new NodeCache( { stdTTL: 900, checkperiod: 1200 } ); // Throttling const myCacheGarbageCollection = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); +const myCacheThrottle = new NodeCache( { stdTTL: 60, checkperiod: 90 } ); myCacheGarbageCollection.on("expired",function(key,value){ - bot.deleteMessage(value, key); + queue.add(async () => {try{await bot.deleteMessage(value, key)}catch{}}); }); const delay = (delayInms) => { @@ -77,20 +84,20 @@ bot.on("my_chat_member", async function(myChatMember: any) { await delay(2000); if( myChatMember.new_chat_member.status === "administrator"){ try{ - bot.sendMessage(myChatMember.chat.id, `The channel id is ${myChatMember.chat.id}`, {parse_mode: "HTML"}); + queue.add(async () => {try{await bot.sendMessage(myChatMember.chat.id, `The channel id is ${myChatMember.chat.id}`, {parse_mode: "HTML"})}catch{}}); } catch(e) { console.log('channel id msg error'+e); } } return; } else if (myChatMember.chat.type === "supergroup") - welcome.callback(settings, bot, myChatMember); + welcome.callback(queue, settings, bot, myChatMember); else if (myChatMember.chat.type === "private") return else try{ const video = myChatMember.chat.is_forum? 'QmSdP3SDoHCdW739xLDBKM3gnLeeZug77RgwgxBJSchvYV/guide_topics.mp4' : 'QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4' - bot.sendVideo(myChatMember.chat.id, `https://ipfs.kleros.io/ipfs/${video}`, {caption: "Hi! I'm Susie, a moderation and group management bot. Please promote me to an admin then try to /start me to unlock my full potential."}); + queue.add(async () => {try{await bot.sendVideo(myChatMember.chat.id, `https://ipfs.kleros.io/ipfs/${video}`, {caption: "Hi! I'm Susie, a moderation and group management bot. Please promote me to an admin then try to /start me to unlock my full potential."})}catch{}}); } catch(e){ console.log(e) } @@ -99,47 +106,101 @@ bot.on("my_chat_member", async function(myChatMember: any) { } }); -bot.on("new_chat_members", async function (chatMemberUpdated: TelegramBot.ChatMemberUpdated) { + +//invite_url only present in private groups +/* +bot.on("chat_member", async function (msg: any) { + if (msg.new_chat_member){ + if(msg.invite_link?.creator?.is_bot){ + const options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false}; + bot.restrictChatMember(msg.chat.id, msg.new_chat_member.id, options) + } + else{ + const options = await bot.getChat(msg.chat.id).permissions + bot.restrictChatMember(msg.chat.id, msg.new_chat_member.id, options) + } + } +}) +*/ + +bot.on("new_chat_members", async function (chatMemberUpdated: any) { if(!hasStarted(chatMemberUpdated.chat.id)||throttled(chatMemberUpdated.from.id)||chatMemberUpdated.chat.type !== "supergroup") return; - const settings = validate(chatMemberUpdated.chat); + + const settings = validate(chatMemberUpdated.chat); let calculateHistory = [] if (settings.federation_id) - calculateHistory = getFederatedBanHistoryBase(db, 'telegram', String(chatMemberUpdated.from.id),String(chatMemberUpdated.chat.id),false) + calculateHistory = getFederatedBanHistory(db, 'telegram', String(chatMemberUpdated.new_chat_member.id),settings.federation_id,true) else if (settings.federation_id_following) - calculateHistory = getFederatedFollowingBanHistoryBase(db, 'telegram', String(chatMemberUpdated.from.id),String(chatMemberUpdated.chat.id),settings.federation_id_following,false) + calculateHistory = getFederatedFollowingBanHistory(db, 'telegram', String(chatMemberUpdated.new_chat_member.id),String(chatMemberUpdated.chat.id),settings.federation_id_following,true) else - calculateHistory = getLocalBanHistoryBase(db, 'telegram', String(chatMemberUpdated.from.id),String(chatMemberUpdated.chat.id),false) + calculateHistory = getLocalBanHistory(db, 'telegram', String(chatMemberUpdated.new_chat_member.id),String(chatMemberUpdated.chat.id),true) + + console.log(calculateHistory) - if (calculateHistory) - return + if (calculateHistory.length > 0){ + var max_timestamp = 0 + for (const ban of calculateHistory){ + if (ban.timestamp_active > max_timestamp) + max_timestamp = ban.timestamp_active + else if (ban.timestamp_finalized > max_timestamp) + max_timestamp = ban.timestamp_finalized + } + const parole_time = calcPenalty(calculateHistory.length, max_timestamp) + if (parole_time*1000 > Date.now()){ + queue.add(async () => {try{await bot.banChatMember(chatMemberUpdated.chat.id, chatMemberUpdated.new_chat_member.id, {until_date: parole_time})}catch{}}) + return + } + } + + let calculateHistoryActive = [] + if (settings.federation_id) + calculateHistoryActive = getFederatedBanHistory(db, 'telegram', String(chatMemberUpdated.new_chat_member.id),settings.federation_id,false) + else if (settings.federation_id_following) + calculateHistoryActive = getFederatedFollowingBanHistory(db, 'telegram', String(chatMemberUpdated.new_chat_member.id),String(chatMemberUpdated.chat.id),settings.federation_id_following,false) + else + calculateHistoryActive = getLocalBanHistory(db, 'telegram', String(chatMemberUpdated.new_chat_member.id),String(chatMemberUpdated.chat.id),false) + + if (calculateHistoryActive.length > calculateHistory.length ){ + var max_timestamp = 0 + for (const ban of calculateHistoryActive){ + if (ban.timestamp_active > max_timestamp) + max_timestamp = ban.timestamp_active + else if (ban.timestamp_finalized > max_timestamp) + max_timestamp = ban.timestamp_finalized + } + const parole_time = calcPenalty(calculateHistoryActive.length, max_timestamp) + if (parole_time > Date.now()){ + const options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false, until_date: parole_time}; + queue.add(async () => {try{await bot.restrictChatMember(chatMemberUpdated.chat.id, chatMemberUpdated.new_chat_member.id, options)}catch{}}) + return; + } + } if(settings.captcha || settings.greeting_mode) - greeting.callback(bot, settings, chatMemberUpdated); + greeting.callback(queue, bot, settings, chatMemberUpdated); }); // Handle callback queries bot.on('callback_query', async function onCallbackQuery(callbackQuery: TelegramBot.CallbackQuery) { const calldata = callbackQuery.data.split('|'); - if (calldata.length < 2) - return - if((!hasStarted(callbackQuery.message.chat.id) && callbackQuery.message.chat.type == "supergroup")||throttled(callbackQuery.from.id)) + if((callbackQuery.data !== '6' && !hasStarted(callbackQuery.message.chat.id) && callbackQuery.message.chat.type == "supergroup")||throttled(callbackQuery.from.id)) return; const settings = validate(callbackQuery.message.chat); if (Number(calldata[0]) === 0){ // set language if (callbackQuery.from.id !== Number(calldata[1])) return; - setLanguage.setLanguageConfirm(db, bot, settings, calldata[2], callbackQuery.message); + setLanguage.setLanguageConfirm(queue, db, bot, settings, calldata[2], callbackQuery.message); } else if (Number(calldata[0]) === 1){ // add evidence if (callbackQuery.from.id !== Number(calldata[1])) return; // handle addevidence callback } else if (Number(calldata[0]) === 2){ // report confirmations - socialConsensus.callback(db, settings, bot, callbackQuery, batchedSend); + socialConsensus.callback(queue, db, settings, bot, callbackQuery, batchedSend); } else if (Number(calldata[0]) === 3){ // report confirmations - help.respond(settings, bot, calldata[1], callbackQuery); + help.respond(queue, settings, bot, calldata[1], callbackQuery); } else if (Number(calldata[0]) === 4){ - const reports = getReportsUserInfo(db, 'telegram', calldata[1], calldata[2]); + const reports = getReportsUserInfoActive(db, 'telegram', calldata[1], calldata[2]); var reportMessage: string = `To add evidence, reply to the message you want saved in the original chat with the evidence index.\n\n` reports.forEach( (report) => { const MsgLink = 'https://t.me/c/' + calldata[1].substring(4) + '/' + report.msg_id; @@ -154,8 +215,8 @@ bot.on('callback_query', async function onCallbackQuery(callbackQuery: TelegramB disable_web_page_preview: true }; try{ - bot.editMessageReplyMarkup({inline_keyboard: [[]]}, optsResponse) - bot.editMessageText(reportMessage , optsResponse); + queue.add(async () => {try{await bot.editMessageReplyMarkup({inline_keyboard: [[]]}, optsResponse)}catch{}}) + queue.add(async () => {try{await bot.editMessageText(reportMessage , optsResponse)}catch{}}); } catch (e){ console.log(e) } @@ -163,10 +224,17 @@ bot.on('callback_query', async function onCallbackQuery(callbackQuery: TelegramB if (callbackQuery.from.id !== Number(calldata[1])) return; const options = {can_send_messages: true, can_send_media_messages: true, can_send_polls: true, can_send_other_messages: true, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false}; - bot.restrictChatMember(callbackQuery.message.chat.id, callbackQuery.from.id, options); - bot.deleteMessage(callbackQuery.message.chat.id, callbackQuery.message.message_id) + queue.add(async () => {try{await bot.restrictChatMember(callbackQuery.message.chat.id, callbackQuery.from.id, options)}catch{}}); + queue.add(async () => {try{await bot.deleteMessage(callbackQuery.message.chat.id, callbackQuery.message.message_id)}catch{}}) + } else if (Number(calldata[0]) === 6){ + const member = await queue.add(async () => {try{const val = await bot.getChatMember(callbackQuery.message.chat.id, callbackQuery.from.id) + return val}catch{}}) + if (member.status === "admin" || member.status === "creator"){ + queue.add(async () => {try{await bot.deleteMessage(callbackQuery.message.chat.id, callbackQuery.message.message_id)}catch{}}) + start.callback(queue, db, settings,bot,String(botId),callbackQuery.message,[],batchedSend, true) + } } - }); + }); const commands: {regexp: RegExp, callback: any}[] = [ getAccount, @@ -175,6 +243,7 @@ const commands: {regexp: RegExp, callback: any}[] = [ report, toggleWelcome, start, + fedinfo, toggleCaptcha, help, newFed, @@ -183,38 +252,43 @@ const commands: {regexp: RegExp, callback: any}[] = [ leaveFed, joinFed, setChannel, + setChannelFed, addEvidence, getReports, setLanguage, ]; -const adminOnlyCommands = [joinFed, leaveFed, newFed, toggleCaptcha, setLanguage, setChannel, toggleWelcome, toggleAdminReportable, start, setRulesCommand ] +const adminOnlyCommands = [joinFed, leaveFed, newFed, toggleCaptcha, setLanguage, setChannelFed, setChannel, toggleWelcome, toggleAdminReportable, start, setRulesCommand ] commands.forEach((command) => { bot.onText( command.regexp, - async (msg: any, match: string[]) => { + async (msg: any, match: string[]) => { if(throttled(msg.from.id)) return const groupSettings = validate(msg.chat); if(msg.chat.type === "private"){ if (msg.text === '/start help'){ - help.callback(db, groupSettings, bot, botId, msg); + help.callback(queue, db, groupSettings, bot, botId, msg); return } else if(msg.text === '/start helpgnosis'){ - help.helpgnosis(db, groupSettings, bot, botId, msg); + help.helpgnosis(queue, db, groupSettings, bot, botId, msg); return } else if(msg.text === '/start helpnotifications'){ - help.helpnotifications(db, groupSettings, bot, botId, msg); + help.helpnotifications(queue, db, groupSettings, bot, botId, msg); return } else if (msg.text.substring(0,22) === '/start addevidencehelp'){ - addEvidenceHelp.callback(db, groupSettings, bot, botId, msg); + addEvidenceHelp.callback(queue, db, groupSettings, bot, botId, msg); return } else if (msg.text.substring(0,16) === '/start getreport'){ - getReports.callback(db, groupSettings, bot, botId, msg); + getReports.callback(queue, db, groupSettings, bot, botId, msg); return } else if (msg.text === '/start newfed' || msg.text.substring(0,7) === '/newfed'){ - newFed.callback(db, groupSettings, bot, String(botId), msg, match); + newFed.callback(queue, db, groupSettings, bot, String(botId), msg, match); + return + } + else if (msg.text === '/start setfedchannel' || msg.text.substring(0,14) === '/setfedchannel'){ + setChannelFed.callback(queue, db, groupSettings, bot, String(botId), msg, match, batchedSend); return } else if (msg.text !== '/start' && msg.text != '/help' && msg.text !== '/start botstart') return @@ -223,7 +297,8 @@ commands.forEach((command) => { if (command === start){ if (hasStarted(msg.chat.id)){ try{ - const resp = await bot.sendMessage(msg.chat.id, "Susie is already moderating this community.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id} : {}) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, "Susie is already moderating this community.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id} : {}) + return val}catch{}}); myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return } catch(e){ @@ -236,7 +311,8 @@ commands.forEach((command) => { try{ if (!botId) - botId = (await bot.getMe()).id; + botId = (await queue.add(async () => {try{const val = await bot.getMe() + return val}catch{}})).id; } catch(e){ console.log(e) } @@ -245,7 +321,8 @@ commands.forEach((command) => { var status = myCache.get("status"+msg.chat.id+msg.from.id) if (!status){ try{ - status = (await bot.getChatMember(msg.chat.id, String(msg.from.id))).status; + status = (await queue.add(async () => {try{const val = await bot.getChatMember(msg.chat.id, String(msg.from.id)) + return val}catch{}})).status; myCache.set("status"+msg.chat.id+msg.from.id,status) } catch(e){ console.log(e) @@ -254,7 +331,8 @@ commands.forEach((command) => { } if (!(status === 'creator' || status === 'administrator')) { try{ - const resp = await bot.sendMessage(msg.chat.id, langJson[groupSettings.lang].errorAdminOnly, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[groupSettings.lang].errorAdminOnly, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + return val}catch{}}) myCacheGarbageCollection.set(resp.message_id, msg.chat.id) } catch(e){ console.log(e) @@ -264,8 +342,8 @@ commands.forEach((command) => { } // todo success bool return val, to not always delete settings - command.callback(db, groupSettings, bot, botId, msg, match,batchedSend); - if (command === setLanguage || command === setRulesCommand || command === setChannel || command === toggleWelcome || command === toggleCaptcha || command === toggleAdminReportable) + command.callback(queue, db, groupSettings, bot, botId, msg, match,batchedSend); + if (command === setLanguage || command === setRulesCommand || command === joinFed || command === setChannel || command === toggleWelcome || command === toggleCaptcha || command === toggleAdminReportable) myCache.del(msg.chat.id) if (command === start) myCache.del("started"+msg.chat.id) @@ -275,10 +353,10 @@ commands.forEach((command) => { const throttled = (userId: number): boolean => { - const count = myCache.get(userId) ?? 1 - if (count >100) + const count = myCacheThrottle.get(userId) ?? 1 + if (count >20) return true - myCache.set(userId.toString(), count + 1) + myCacheThrottle.set(userId.toString(), count + 1) return false; } @@ -297,7 +375,7 @@ const hasStarted = (chatid: number): boolean=> { } } -const validate = (chat: any): groupSettings=> { +const validate = (chat: any, language_code?: string): groupSettings=> { if (!hasStarted(chat.id)){ let settings = defaultSettings; settings.channelID = String(chat.id) @@ -332,15 +410,15 @@ const validate = (chat: any): groupSettings=> { const checkMigration = async (groupSettings: groupSettings, chat: any): Promise => { if (chat.is_forum && !groupSettings.thread_id_notifications){ // turn topics on try{ - const threads = await start.topicMode(db, bot, groupSettings, chat); - bot.sendMessage(chat.id, "Started topic mode", {messsage_thread_id: groupSettings.thread_id_notifications}) + const threads = await start.topicMode(queue, db, bot, groupSettings, chat); + queue.add(async () => {try{await bot.sendMessage(chat.id, "Started topic mode", {messsage_thread_id: groupSettings.thread_id_notifications})}catch{}}) groupSettings.thread_id_rules = threads[0] groupSettings.thread_id_notifications = threads[1] groupSettings.channelID = String(chat.id) myCache.set(chat.id, groupSettings) } catch(e){ try{ - bot.sendMessage(chat.id, "Susie cannot manage groups in topic mode with out permission to manage topics. Please ask an admin to enable this permission to allow Susie to continue help moderating your community.", {messsage_thread_id: groupSettings.thread_id_notifications}) + queue.add(async () => {try{await bot.sendMessage(chat.id, "Susie cannot manage groups in topic mode with out permission to manage topics. Please ask an admin to enable this permission to allow Susie to continue help moderating your community.", {messsage_thread_id: groupSettings.thread_id_notifications})}catch{}}) } catch(e){ console.log(e) } From 82c3396d0731d785cd212ffec4df15054fa6a495 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Wed, 21 Dec 2022 01:43:43 -0700 Subject: [PATCH 013/111] fix: bugs --- lib/cron.ts | 44 ++++++++++++++++-------- lib/db.ts | 28 +++++++-------- lib/telegram/assets/lang.json | 6 ++-- lib/telegram/commands/addEvidenceHelp.ts | 3 +- lib/telegram/commands/getReports.ts | 6 ++-- lib/telegram/commands/help.ts | 4 +-- lib/telegram/commands/report.ts | 6 ++-- lib/telegram/commands/setChannelFed.ts | 5 +-- lib/telegram/index.ts | 13 +++---- 9 files changed, 63 insertions(+), 52 deletions(-) diff --git a/lib/cron.ts b/lib/cron.ts index fd33c1a..0b9fec3 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -1,5 +1,5 @@ require('dotenv').config() -import {openDb, getGroupSettings, getRule, getCron, getFederationChannel, getFederatedFollowingBanHistory, getLocalBanHistory, getFederatedBanHistory, setCron, getGroupsInAndFollowingFederation, getReportMessageTimestampAndActive, setReport} from "./db"; +import {openDb, getGroupSettings, getRule, getCron, getFederationChannel, getInviteURL, getFederatedFollowingBanHistory, getLocalBanHistory, getFederatedBanHistory, setCron, getGroupsInAndFollowingFederation, getReportMessageTimestampAndActive, setReport} from "./db"; import request from "graphql-request"; import {BigNumber} from "ethers"; import TelegramBot from "node-telegram-bot-api"; @@ -40,8 +40,8 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo console.log(history.last_timestamp) console.log(history.last_block) // hardcode values for tests - //history.last_timestamp = 1671604752 - //history.last_block = 8173468 + //history.last_timestamp = 1671607558 + //history.last_block = 8173661 const timestampNew = currentTime const timestampLastUpdated = history.last_timestamp const reports = {}; @@ -98,9 +98,12 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo // settings[1] language try{ queue.add(async () => {try{await bot.sendMessage(settings.channelID, `The dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - queue.add(async () => {try{await bot.sendMessage(process.env.JUSTICE_LEAGUE, `The dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + const chatname = (await queue.add(async () => {try{const val = await bot.getChat(data.moderationInfo.UserHistory.group.groupID) + return val}catch{}}))?.title + const invite_url = getInviteURL(db,'telegram',data.moderationInfo.UserHistory.group.groupID) + queue.add(async () => {try{await bot.sendMessage(process.env.JUSTICE_LEAGUE, `The dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) in the group [${chatname}](${invite_url}) has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); if(settings.federation_id) - queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `The dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `The dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) in the group [${chatname}](${invite_url})has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); } catch(e){ console.log(e) } @@ -113,9 +116,12 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo const disputeURL = `https://resolve.kleros.io/cases/${BigNumber.from(data.id).toNumber()}`; try{ queue.add(async () => {try{await bot.sendMessage(settings.channelID, `Arbitration is requested for the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})). Consequences of the report are lifted for the duration of the [dispute](${disputeURL}) (on Gnosis Chain).`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - queue.add(async () => {try{await bot.sendMessage(process.env.JUSTICE_LEAGUE, `Arbitration is requested for the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})). Consequences of the report are lifted for the duration of the [dispute](${disputeURL}) (on Gnosis Chain).`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + const chatname = (await queue.add(async () => {try{const val = await bot.getChat(data.moderationInfo.UserHistory.group.groupID) + return val}catch{}}))?.title + const invite_url = getInviteURL(db,'telegram',data.moderationInfo.UserHistory.group.groupID) + queue.add(async () => {try{await bot.sendMessage(process.env.JUSTICE_LEAGUE, `[Arbitration](${disputeURL}) is requested for the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) in the group [${chatname}](${invite_url}).`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); if(settings.federation_id) - queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `Arbitration is requested for the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})). Consequences of the report are lifted for the duration of the [dispute](${disputeURL}) (on Gnosis Chain).`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `[Arbitration](${disputeURL}) is requested for the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) in the group [${chatname}](${invite_url}).`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); handleTelegramUpdate(db, bot,settings, data.moderationInfo,timestampNew, false, false, true); } catch (e){ console.log(e) @@ -130,9 +136,12 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo // settings[1] language try{ queue.add(async () => {try{await bot.sendMessage(settings.channelID, `An appeal has been funded in the dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})). Juror's voted in the previous round that *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. The contribution funded ${data.RulingFunded == data.currentRuling ? 'the previous round winning option': 'a different option that the previous round'}. If you think the funded option is incorrect, you can win some of their deposit by funding the correct side of the [appeal](${disputeURL})`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - queue.add(async () => {try{await bot.sendMessage(process.env.JUSTICE_LEAGUE, `An appeal has been funded in the dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})). Juror's voted in the previous round that *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. The contribution funded ${data.RulingFunded == data.currentRuling ? 'the previous round winning option': 'a different option that the previous round'}. If you think the funded option is incorrect, you can win some of their deposit by funding the correct side of the [appeal](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + const chatname = (await queue.add(async () => {try{const val = await bot.getChat(data.moderationInfo.UserHistory.group.groupID) + return val}catch{}}))?.title + const invite_url = getInviteURL(db,'telegram',data.moderationInfo.UserHistory.group.groupID) + queue.add(async () => {try{await bot.sendMessage(process.env.JUSTICE_LEAGUE, `An appeal has been funded in the dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) in the group ${chatname}[${invite_url}]. Juror's voted in the previous round that *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. The contribution funded ${data.RulingFunded == data.currentRuling ? 'the previous round winning option': 'a different option that the previous round'}. If you think the funded option is incorrect, you can win some of their deposit by funding the correct side of the [appeal](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); if(settings.federation_id) - queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `An appeal has been funded in the dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})). Juror's voted in the previous round that *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. The contribution funded ${data.RulingFunded == data.currentRuling ? 'the previous round winning option': 'a different option that the previous round'}. If you think the funded option is incorrect, you can win some of their deposit by funding the correct side of the [appeal](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `An appeal has been funded in the dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) in the group ${chatname}[${invite_url}]. Juror's voted in the previous round that *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. The contribution funded ${data.RulingFunded == data.currentRuling ? 'the previous round winning option': 'a different option that the previous round'}. If you think the funded option is incorrect, you can win some of their deposit by funding the correct side of the [appeal](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); } catch(e){ console.log(e) } @@ -178,9 +187,13 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo //console.log('answered') queue.add(async () => {try{await bot.sendMessage(settings.channelID, `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) violate the [rules](${data.moderationInfo.rules})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - queue.add(async () => {try{await bot.sendMessage(process.env.JUSTICE_LEAGUE, `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) violate the [rules](${data.moderationInfo.rules})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + const chatname = (await queue.add(async () => {try{const val = await bot.getChat(data.moderationInfo.UserHistory.group.groupID) + return val}catch{}}))?.title + const invite_url = getInviteURL(db,'telegram',data.moderationInfo.UserHistory.group.groupID) + queue.add(async () => {try{await bot.sendMessage(process.env.JUSTICE_LEAGUE, `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) in the group [${chatname}](${invite_url}) violate the [rules](${data.moderationInfo.rules})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if(settings.federation_id) - queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) violate the [rules](${data.moderationInfo.rules})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) in the group [${chatname}](${invite_url}) violate the [rules](${data.moderationInfo.rules})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); handleTelegramUpdate(db, bot,settings, data.moderationInfo,timestampNew, data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001", false, false); } catch(e){ console.log(e) @@ -196,7 +209,7 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo const sherrif = await queue.add(async () => {try{const val = await bot.getChatMember(data.group.groupID, data.sheriff.user.userID) return val}catch{}}); //console.log(sherrif) - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `There's a new sheriff in town 👑🥇🤠[${sherrif.user.username}](tg://user?id=${sherrif.user.id})🤠🥇👑`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(data.group.groupID, `There's a new sheriff in town 👑🥇🤠[${sherrif.user.username}](tg://user?id=${sherrif.user.id})🤠🥇👑`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); } catch(e){ console.log(e) } @@ -208,7 +221,7 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo try{ const deputysherrif = await queue.add(async () => {try{const val = await bot.getChatMember(data.group.groupID, data.deputySheriff.user.userID) return val}catch{}}) - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `There's a new deputy sheriff in town 🥈[${deputysherrif.user.username}](tg://user?id=${deputysherrif.user.id})🥈`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(data.group.groupID, `There's a new deputy sheriff in town 🥈[${deputysherrif.user.username}](tg://user?id=${deputysherrif.user.id})🥈`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); } catch(e){ console.log(e) } @@ -226,10 +239,11 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo } else if (data.status === "NeighborhoodWatch"){ message = "🤝 ***Neighborhood Watch Recognition*** 🤝\n\n The Neighborhood Watch recognition is given to members who help protect their community. Thank you for your service 🙏" } else if (data.status === "BoyWhoCriedWolf"){ - "Have you ever heard of the fable of 💩 the boy who cried wolf 💩?\n\nBe careful, too many unanswered reports could hurt your reputation, " + message = "Have you ever heard of the fable of 💩 the boy who cried wolf 💩?\n\nBe careful, too many unanswered reports could hurt your reputation, " } + console.log(data) if(data.status !== "CommunityMember") - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `${message} [${userUpdate.user.username}](tg://user?id=${userUpdate.user.id})`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(data.group.groupID, `${message} [${userUpdate.user.username}](tg://user?id=${userUpdate.user.id})`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); } catch(e){ console.log(e) } diff --git a/lib/db.ts b/lib/db.ts index 4eafb40..20497db 100644 --- a/lib/db.ts +++ b/lib/db.ts @@ -104,14 +104,14 @@ const setInviteURLChannel = (db: any, platform: string, groupId: string, inviteU } } -const setFederationInviteURLChannel = (db: any, platform: string, groupId: string, inviteUrlChannel: string) => { +const setFederationInviteURLChannel = (db: any, platform: string, federation_id: string, inviteUrlChannel: string) => { try{ const stmt = db.prepare( - `INSERT INTO federations (platform, group_id, invite_url_channel) + `INSERT INTO federations (platform, federation_id, invite_url_channel) VALUES (?, ?, ?) - ON CONFLICT (platform, group_id) DO UPDATE SET + ON CONFLICT (platform, federation_id) DO UPDATE SET invite_url_channel = ?;`); - const info = stmt.run(platform, groupId, inviteUrlChannel, inviteUrlChannel); + const info = stmt.run(platform, federation_id, inviteUrlChannel, inviteUrlChannel); } catch(err) { console.log("db error: setFederationInviteURLChannel, "+err); } @@ -126,21 +126,21 @@ const setChannelID = (db: any, platform: string, groupId: string, channel_id: st channel_id = ?;`); const info = stmt.run(platform, groupId, channel_id, channel_id); } catch(err) { - console.log("db error: set setChannelID"); + console.log("db error: setChannelID"); console.log(err); } } -const setFederationChannelID = (db: any, platform: string, groupId: string, channel_id: string) => { +const setFederationChannelID = (db: any, platform: string, federation_id: string, channel_id: string) => { try{ const stmt = db.prepare( - `INSERT INTO federations (platform, group_id, notification_channel_id) + `INSERT INTO federations (platform, federation_id, notification_channel_id) VALUES (?, ?, ?) - ON CONFLICT (platform, group_id) DO UPDATE SET + ON CONFLICT (platform, federation_id) DO UPDATE SET notification_channel_id = ?;`); - const info = stmt.run(platform, groupId, channel_id, channel_id); + const info = stmt.run(platform, federation_id, channel_id, channel_id); } catch(err) { - console.log("db error: set setChannelID"); + console.log("db error: setFederationChannelID"); console.log(err); } } @@ -327,10 +327,10 @@ const getInviteURLChannel = (db: any, platform: string, groupId: string) => { } } -const getFederatedInviteURLChannel = (db: any, platform: string, groupId: string) => { +const getFederatedInviteURLChannel = (db: any, platform: string, federation_id: string) => { try{ const stmt = db.prepare('SELECT invite_url_channel FROM federations WHERE platform = ? AND federation_id = ?'); - return stmt.get(platform, groupId)?.invite_url_channel || ''; + return stmt.get(platform, federation_id)?.invite_url_channel || ''; } catch(err){ console.log("db error: getFederatedInviteURLChannel, "+err); } @@ -507,7 +507,7 @@ const setReport = (db: any, questionId: string, active: boolean, answered: boole const getActiveEvidenceGroupId = (db: any, platform: string, groupId: string, evidenceIndex: number) => { try{ - const stmt = db.prepare( `SELECT question_id FROM reports WHERE platform = ? AND group_id = ? AND evidenceIndex = ? AND finalized IS NULL`); + const stmt = db.prepare( `SELECT question_id FROM reports WHERE platform = ? AND group_id = ? AND evidenceIndex = ? AND NOT finalized = 1`); return stmt.get(platform, groupId, evidenceIndex)?.question_id; } catch(err) { console.log("db error: getActiveEvidenceGroupId" + err); @@ -743,7 +743,7 @@ const getFederatedBanHistory = (db: any, platform: string, userId: string, feder const getUsersWithQuestionsNotFinalized = (db: any, platform: string, groupId: string) => { try{ - const stmt = db.prepare( `SELECT DISTINCT user_id, username FROM reports WHERE platform = ? AND group_id = ? AND finalized IS NULL`); + const stmt = db.prepare( `SELECT DISTINCT user_id, username FROM reports WHERE platform = ? AND group_id = ? AND NOT finalized = 1`); return stmt.all(platform, groupId); } catch(err) { console.log("db error: getActiveEvidenceGroupId"); diff --git a/lib/telegram/assets/lang.json b/lib/telegram/assets/lang.json index 917febe..2b0630d 100644 --- a/lib/telegram/assets/lang.json +++ b/lib/telegram/assets/lang.json @@ -10,14 +10,14 @@ "getAccount": "Bot address", "errorAdminRights": "Please make sure to enable all of the admin rights for the bot.", "getReports" :{ - "noReports": "No local reports for user", - "noFedReports": "No federal reports for user", + "noReports": "None", + "noFedReports": "No federal reports", "broke": "broke the rules", "nobreak": "did not break the rules", "reportFinal": "final", "reportCurrent": "current", "noActiveReports": "There are no active answered reports.", - "specificUser": "To find all reports for a specific user, reply to their message with `/reportinfo`.", + "specificUser": "To find all reports for a specific user, reply to their message with `/info`.", "reportMessage": "Active Answered Reports", "reportMessage1": "reported for message sent", "reportMessage2": "backup", diff --git a/lib/telegram/commands/addEvidenceHelp.ts b/lib/telegram/commands/addEvidenceHelp.ts index 53aa07c..b6f7199 100644 --- a/lib/telegram/commands/addEvidenceHelp.ts +++ b/lib/telegram/commands/addEvidenceHelp.ts @@ -12,7 +12,8 @@ const regexp = /\/addevidencehelp/ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { const groupId = getUsersWithQuestionsNotFinalized(db, 'telegram', msg.text.substring(22)) if (!groupId || groupId.length === 0){ - queue.add(() => bot.sendMessage(msg.chat.id, `There are no reports to add evidence to in your group.`)); + queue.add(() => bot.sendMessage(msg.chat.id, `There are no reports to add evidence to in your group.`)); + return } var inline_keyboard_evidence = [] var inline_keyboard_evidence_cursor = []; diff --git a/lib/telegram/commands/getReports.ts b/lib/telegram/commands/getReports.ts index 49434a0..7a19633 100644 --- a/lib/telegram/commands/getReports.ts +++ b/lib/telegram/commands/getReports.ts @@ -14,7 +14,7 @@ myCache.on("expired",function(key,value){ /* * /getreports */ -const regexp = /\/reportinfo/ +const regexp = /\/info/ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botid: number, msg: any) => { if (!myBot) @@ -108,9 +108,9 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, } for(const report of reportsFederation) { // TODO getTitle - const chatname = (await queue.add(async () => {try{const val = await bot.getChat(group_id) + const chatname = (await queue.add(async () => {try{const val = await bot.getChat(report.group_id) return val}catch{}}))?.title - const invite_url = getInviteURL(db,'telegram',group_id) + const invite_url = getInviteURL(db,'telegram',report.group_id) const reportAnswer = report.answered? (report.active? langJson[settings.lang].getReports.broke : langJson[settings.lang].getReports.nobreak) : 'unanswered'; const MsgLink = 'https://t.me/c/' + report.group_id.substring(4) + '/' + report.msg_id; const msgTimehours = new Date(report.timestamp_msg*1000).toUTCString(); diff --git a/lib/telegram/commands/help.ts b/lib/telegram/commands/help.ts index 6fa0a8e..c4eb11b 100644 --- a/lib/telegram/commands/help.ts +++ b/lib/telegram/commands/help.ts @@ -224,8 +224,8 @@ Answers to reports can be disputed, creating a case in the Kleros court. Refer t *User commands*: - \`/report\` : Reply to a message to report it -- \`/reportinfo\`: Returns active reports -- \`/reportinfo\` : Returns active reports for user` +- \`/info\`: Returns active reports +- \`/info\` : Returns active reports for user` ,optsResponse)}catch{}}) break; } diff --git a/lib/telegram/commands/report.ts b/lib/telegram/commands/report.ts index 611bc65..6c24d66 100644 --- a/lib/telegram/commands/report.ts +++ b/lib/telegram/commands/report.ts @@ -25,7 +25,7 @@ myCacheGarbageCollectionSlow.on("expired",function(key,value){ }); const callback = async (queue: any, db:any, settings: groupSettings, bot: any, botId: number, msg: any, match: string[]) => { try{ - if(msg.text.substring(0,11) === '/reportinfo') + if(msg.text.substring(0,11) === '/info') return if (!myBot) myBot = bot @@ -74,7 +74,7 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b const fromUsername = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name || `no-username-set`); const reportedUserID = String(msg.reply_to_message.from.id); const currentTimeMs = Date.now()/1000; - +/* const cachedReportRequestMessage = myCache.get([msg.chat.id, msg.reply_to_message.message_id].toString()) if (cachedReportRequestMessage){ // message already reported const msgLinkReport = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + cachedReportRequestMessage; @@ -82,7 +82,7 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b return val}catch{}}); myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return; - } + }*/ const reportedQuestionId = getQuestionId(db, 'telegram', String(msg.chat.id), reportedUserID, String(msg.reply_to_message.message_id)); if (reportedQuestionId){ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.reported}(https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${reportedQuestionId})`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true}) diff --git a/lib/telegram/commands/setChannelFed.ts b/lib/telegram/commands/setChannelFed.ts index c145f59..8cf06ca 100644 --- a/lib/telegram/commands/setChannelFed.ts +++ b/lib/telegram/commands/setChannelFed.ts @@ -59,6 +59,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, } const channelUser = await queue.add(async () => {try{const val = await bot.getChatMember(newmatch[1], String(msg.from.id)) return val}catch{}}); + console.log(channelUser) if(channelUser.status !== "administrator" && channelUser.status !== "creator"){ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, 'You are not an authorized admin of the channel.',msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) return val}catch{}}); @@ -81,8 +82,8 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, } const invite_url_channel = await queue.add(async () => {try{const val = await bot.exportChatInviteLink(newmatch[1]) return val}catch{}}); - setFederationInviteURLChannel(db, 'telegram', String(msg.chat.id), invite_url_channel); - setFederationChannelID(db, 'telegram', String(msg.chat.id), newmatch[1]); + setFederationInviteURLChannel(db, 'telegram', String(msg.from.id), invite_url_channel); + setFederationChannelID(db, 'telegram', String(msg.from.id), newmatch[1]); queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `Moderation notifications for the federation will now be sent to this [channel](${invite_url_channel}).`, {parse_mode: "Markdown"})}catch{}}); queue.add(async () => {try{await bot.sendMessage(newmatch[1], `This channel will now relay moderation notifications for the federation *${name}*`, {parse_mode: "Markdown"})}catch{}}); } catch (error) { diff --git a/lib/telegram/index.ts b/lib/telegram/index.ts index 70880cb..e609aec 100644 --- a/lib/telegram/index.ts +++ b/lib/telegram/index.ts @@ -207,7 +207,7 @@ bot.on('callback_query', async function onCallbackQuery(callbackQuery: TelegramB reportMessage += `- [Message](${MsgLink}) ([${langJson[settings.lang].socialConsensus.consensus5}](${report.msgBackup})) [${langJson[settings.lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), \`/addevidence ${report.evidenceIndex}\` \n`; }); - reportMessage +='\n eg. /addevidence 1 This message breaks the rules because xyz.' + reportMessage +='\n eg. \`/evidence\` 1 This message breaks the rules because xyz.' const optsResponse = { chat_id: callbackQuery.message.chat.id, message_id: callbackQuery.message.message_id, @@ -264,6 +264,9 @@ commands.forEach((command) => { bot.onText( command.regexp, async (msg: any, match: string[]) => { + if (!botId) + botId = (await queue.add(async () => {try{const val = await bot.getMe() + return val}catch{}})).id; if(throttled(msg.from.id)) return const groupSettings = validate(msg.chat); @@ -309,14 +312,6 @@ commands.forEach((command) => { return; } - try{ - if (!botId) - botId = (await queue.add(async () => {try{const val = await bot.getMe() - return val}catch{}})).id; - } catch(e){ - console.log(e) - } - if (msg.chat.type !== "private" && adminOnlyCommands.indexOf(command)!==-1){ var status = myCache.get("status"+msg.chat.id+msg.from.id) if (!status){ From 65deeda76271cdcfc7b6e38a0cca523f714e7e39 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Wed, 21 Dec 2022 13:05:42 -0700 Subject: [PATCH 014/111] fix(format) --- lib/telegram/commands/getAccount.ts | 4 ++-- lib/telegram/commands/getChannel.ts | 2 +- lib/telegram/commands/help.ts | 5 ++++- lib/telegram/commands/joinfed.ts | 4 ++-- lib/telegram/commands/setChannel.ts | 2 +- lib/telegram/index.ts | 2 +- 6 files changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/telegram/commands/getAccount.ts b/lib/telegram/commands/getAccount.ts index e0f98b6..0f24ba3 100644 --- a/lib/telegram/commands/getAccount.ts +++ b/lib/telegram/commands/getAccount.ts @@ -12,8 +12,8 @@ var address: string; const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { try{ if (!address) - address = process.env.TRANSACTION_BATCHER_CONTRACT_ADDRESS; - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `${langJson[settings.lang].getAccount}: ${address}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{})}catch{}}); + address = (await new Wallet(process.env.PRIVATE_KEY)).address + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${langJson[settings.lang].getAccount}*: ${address}\n\n*Transaction Batch Address*: ${process.env.TRANSACTION_BATCHER_CONTRACT_ADDRESS}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}:{parse_mode: "Markdown"})}catch{}}); } catch(e){ console.log('gettaccount error. '+e) } diff --git a/lib/telegram/commands/getChannel.ts b/lib/telegram/commands/getChannel.ts index 8daf6ce..59bf291 100644 --- a/lib/telegram/commands/getChannel.ts +++ b/lib/telegram/commands/getChannel.ts @@ -32,7 +32,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, return val}catch{}}); myCache.set(resp.message_id, msg.chat.id) } else { - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `I notify this [channel](${channel_invite}) about moderation activity.`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `I notify this [channel](${channel_invite}) about moderation activity.`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id, disable_web_page_preview: true}:{parse_mode: "Markdown", disable_web_page_preview: true}) return val}catch{}}); myCache.set(resp.message_id, msg.chat.id) } diff --git a/lib/telegram/commands/help.ts b/lib/telegram/commands/help.ts index c4eb11b..426761a 100644 --- a/lib/telegram/commands/help.ts +++ b/lib/telegram/commands/help.ts @@ -202,8 +202,11 @@ Topics allow large (>200 member) groups to focus discussion in dedicated **topic To prevent important messages from deletion, pre-emptively, messages can be saved as evidence. +Note that Susie uses a proxy contract to efficiently batch reports. In case of dispute over authenticity, evidence submitted by the Kleros Moderate bot is time stamped in chat. Moreover, this timestamp should be consistent with any evidence submitted by the bot address through the transaction batching contract. + *User commands*: -- \`/evidence\` \n\nReply to a message to add it as evidence` +- \`/evidence\` : Reply to a message to add it as evidence. +- \`/getaccount\`: Gets bot and transaction batcher addresses.` ,optsResponse)}catch{}}) break; } diff --git a/lib/telegram/commands/joinfed.ts b/lib/telegram/commands/joinfed.ts index 1fd0f2a..f794ef3 100644 --- a/lib/telegram/commands/joinfed.ts +++ b/lib/telegram/commands/joinfed.ts @@ -38,11 +38,11 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, myCache.set(resp.message_id, msg.chat.id) } else if (msg.from.id == match[1]){ - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `Your group is now part of the *${name}* federation.`,msg.chat.is_forum? {message_thread_id: msg.message_thread_id,parse_mode: 'Markdown'}:{parse_mode: 'Markdown'})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `Your group is now part of the *${name}* federation.`,msg.chat.is_forum? {message_thread_id: msg.message_thread_id,parse_mode: 'Markdown'}:{parse_mode: 'Markdown'})}catch{}}); joinFederation(db, 'telegram', String(msg.chat.id), match[1]) } else{ - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `Your group is now following the *${name}* federation.`,msg.chat.is_forum? {message_thread_id: msg.message_thread_id,parse_mode: 'Markdown'}:{parse_mode: 'Markdown'})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `Your group is now following the *${name}* federation.`,msg.chat.is_forum? {message_thread_id: msg.message_thread_id,parse_mode: 'Markdown'}:{parse_mode: 'Markdown'})}catch{}}); followFederation(db, 'telegram', String(msg.chat.id), match[1]) } } diff --git a/lib/telegram/commands/setChannel.ts b/lib/telegram/commands/setChannel.ts index 8cf1508..a1720df 100644 --- a/lib/telegram/commands/setChannel.ts +++ b/lib/telegram/commands/setChannel.ts @@ -78,7 +78,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: Teleg return val}catch{}}); setInviteURLChannel(db, 'telegram', String(msg.chat.id), invite_url_channel); setChannelID(db, 'telegram', String(msg.chat.id), newmatch[1]); - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `Moderation notifications will now be sent to this [channel](${invite_url_channel}).`, {parse_mode: "Markdown"})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `Moderation notifications will now be sent to this [channel](${invite_url_channel}).`, {parse_mode: "Markdown", disable_web_page_preview: true})}catch{}}); queue.add(async () => {try{await bot.sendMessage(newmatch[1], `This channel will now relay moderation notifications for ${msg.chat.title}`, {parse_mode: "Markdown"})}catch{}}); } catch (error) { console.log(error); diff --git a/lib/telegram/index.ts b/lib/telegram/index.ts index e609aec..15a0733 100644 --- a/lib/telegram/index.ts +++ b/lib/telegram/index.ts @@ -386,7 +386,7 @@ const validate = (chat: any, language_code?: string): groupSettings=> { const fullSettings = { lang: groupSettings?.lang ?? defaultSettings.lang, rules: groupSettings?.rules ?? defaultSettings.rules, - channelID: groupSettings?.channelID ?? String(chat.id), + channelID: chat.is_forum? String(chat.id): (groupSettings?.channelID ?? String(chat.id)), greeting_mode: groupSettings?.greeting_mode ?? defaultSettings.greeting_mode, admin_reportable: groupSettings?.admin_reportable ?? defaultSettings.admin_reportable, captcha: groupSettings?.captcha ?? defaultSettings.captcha, From 5a6d85fd55368373fee6e372dcded7769475b71e Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Wed, 21 Dec 2022 14:18:23 -0700 Subject: [PATCH 015/111] feat: simple rules --- lib/cron.ts | 12 +++--------- lib/telegram/assets/lang.json | 2 +- lib/telegram/commands/help.ts | 14 ++++++++++---- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/cron.ts b/lib/cron.ts index 0b9fec3..94b2c91 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -8,10 +8,8 @@ import {Wallet} from "@ethersproject/wallet"; const {default: PQueue} = require('p-queue'); import {groupSettings, groupSettingsUnderspecified} from "../types"; const ModeratorBot = require('node-telegram-bot-api'); -const NodeCache = require( "node-cache" ); const Web3 = require('web3') const realitio_bot = require('./realitioReporting') -const myCache = new NodeCache( { stdTTL: 900, checkperiod: 1200 } ); const db = openDb(); const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: false, testEnvironment: true}); const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCount: true}); @@ -270,13 +268,9 @@ const validate = (chatId: string): groupSettings=> { federation_id: '', federation_id_following: '' } - var groupSettings : groupSettingsUnderspecified = myCache.get(chatId) - if (!groupSettings){ - const rules = getRule(db, 'telegram', chatId, Math.floor(Date.now()/1000)) - groupSettings = getGroupSettings(db, 'telegram', chatId) - groupSettings.rules = rules - myCache.set(chatId, groupSettings) - } + var groupSettings : groupSettingsUnderspecified = getGroupSettings(db, 'telegram', chatId) + groupSettings.rules = getRule(db, 'telegram', chatId, Math.floor(Date.now()/1000)) + const fullSettings = { lang: groupSettings?.lang ?? defaultSettings.lang, rules: groupSettings?.rules ?? defaultSettings.rules, diff --git a/lib/telegram/assets/lang.json b/lib/telegram/assets/lang.json index 2b0630d..eb55e88 100644 --- a/lib/telegram/assets/lang.json +++ b/lib/telegram/assets/lang.json @@ -80,7 +80,7 @@ "greeting1": "Welcome, this group is moderated with ", "greeting2": "Please make sure to follow the [community rules]", "greeting3": "Users who break the rules can be reported by replying to a message with the command /report.", - "defaultRules": "https://ipfs.kleros.io/ipfs/QmRxgfYYLRdrCnd492GRinJLT2PvyPkvDhpA5eawEXs3bP/Kleros%20Moderate%20Community%20Guidelines%20v1.0.pdf", + "defaultRules": "https://ipfs.kleros.io/ipfs/QmbgRUB4dEgcvRfYmWo34GJhpBGNWWJNsbz8dxN2QLTyLb/Kleros%20Moderate%20Community%20Rules%20v1.0.pdf", "defaultRulesMsg1": "The Kleros Moderate Community Guidelines apply as the default [rules]", "defaultRulesMsg1alt": "The Kleros Moderate Community Guidelines apply as the default rules", "defaultRulesMsg2": "Crafting precise policies can be challenging, if you are certain in setting a new policy, you can set new rules with /setrules \\[url] or /setrules \\[reply to message]" diff --git a/lib/telegram/commands/help.ts b/lib/telegram/commands/help.ts index 426761a..eb7429b 100644 --- a/lib/telegram/commands/help.ts +++ b/lib/telegram/commands/help.ts @@ -138,7 +138,7 @@ const respond = (queue: any, settings: groupSettings, bot: any, helpType: string text: '🧑‍⚖️ Lawyer', callback_data: `3|lawyer` }, { - text: '✨ Open', + text: '🕵️ Privacy', callback_data: `3|open` } ],[ @@ -320,12 +320,18 @@ If you would like to offer your services as a lawyer or solicit services, please break; } case 'open': { - queue.add(async () => {try{await bot.editMessageText(`✨ *Open Source* ✨ + queue.add(async () => {try{await bot.editMessageText(`🕵️ *Privacy* 🕵️ -Susie is [open source](https://github.com/kleros/kleros-moderate). Feel free to make an issue, feature request, bug report, comments, suggests, PRs, forks, etc : ) +Effective moderation requires understsanding the full context and nuance of messages. To achieve this goal, Susie can: + +- save messages to submit as evidence on behalf of users. +- create open invitations for moderators or jurors to join the group and investigate reports. + +When you invite Susie to your group, have a similar expectation of privacy as a conversation in a public town square. Susie enforces the rules protecting members from harassment, but free speech and sharing of unpopular opinions are also protected with a fair dispute resolution process. ` ,optsResponse)}catch{}}) break; + //Susie is [open source](https://github.com/kleros/kleros-moderate). Feel free to make an issue, feature request, bug report, comments, suggests, PRs, forks, etc : ) //Susie is hosted. You can self-host Susie. A raspberry pi or an old laptop are sufficient to keep your own instance of Susie online. To learn more about self-hosting, guide *coming soon*. } default: { @@ -386,7 +392,7 @@ const opts = { text: '🧑‍⚖️ Lawyer', callback_data: `3|lawyer` }, { - text: '✨ Open', + text: '🕵️ Privacy', callback_data: `3|open` } ], From dcb84f48793bb84973953733a9e0aad632c9b32b Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Wed, 21 Dec 2022 20:58:15 -0700 Subject: [PATCH 016/111] fix: catch async queue --- lib/cron.ts | 8 ++++++++ lib/realitioReporting.ts | 1 - lib/telegram/commands/addEvidence.ts | 22 ++++++++++++++++++++++ lib/telegram/commands/captcha.ts | 2 ++ lib/telegram/commands/fedinfo.ts | 4 ++++ lib/telegram/commands/getChannel.ts | 6 ++++++ lib/telegram/commands/getReports.ts | 6 +++++- lib/telegram/commands/getRules.ts | 2 ++ lib/telegram/commands/greeting.ts | 2 ++ lib/telegram/commands/joinfed.ts | 4 ++++ lib/telegram/commands/newfed.ts | 2 ++ lib/telegram/commands/report.ts | 23 ++++++++++++++++++++++- lib/telegram/commands/setChannel.ts | 20 ++++++++++++++++++++ lib/telegram/commands/setChannelFed.ts | 23 ++++++++++++++++++++++- lib/telegram/commands/setLanguage.ts | 4 ++++ lib/telegram/commands/setRules.ts | 4 ++++ lib/telegram/commands/start.ts | 7 ++++++- lib/telegram/commands/toggleWelcome.ts | 4 ++++ lib/telegram/index.ts | 6 ++++++ 19 files changed, 145 insertions(+), 5 deletions(-) diff --git a/lib/cron.ts b/lib/cron.ts index 94b2c91..1870a88 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -206,6 +206,8 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo try{ const sherrif = await queue.add(async () => {try{const val = await bot.getChatMember(data.group.groupID, data.sheriff.user.userID) return val}catch{}}); + if(!sherrif) + continue //console.log(sherrif) queue.add(async () => {try{await bot.sendMessage(data.group.groupID, `There's a new sheriff in town 👑🥇🤠[${sherrif.user.username}](tg://user?id=${sherrif.user.id})🤠🥇👑`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); } catch(e){ @@ -219,6 +221,8 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo try{ const deputysherrif = await queue.add(async () => {try{const val = await bot.getChatMember(data.group.groupID, data.deputySheriff.user.userID) return val}catch{}}) + if(!deputysherrif) + continue queue.add(async () => {try{await bot.sendMessage(data.group.groupID, `There's a new deputy sheriff in town 🥈[${deputysherrif.user.username}](tg://user?id=${deputysherrif.user.id})🥈`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); } catch(e){ console.log(e) @@ -231,6 +235,8 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo try{ const userUpdate = await queue.add(async () => {try{const val = await bot.getChatMember(data.group.groupID, data.user.userID) return val}catch{}}) + if(!userUpdate) + continue let message = "" if (data.status === "GoodSamaritan"){ message = "🎖 ***Good Samaritan Award***🎖\n\nThe Good Samaritan award is this group's highest honor, given to members who performed exemplary deeds of service for their group or their fellow members. Thank you for your service 🙏" @@ -364,6 +370,8 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, if(liftbans){ const permissions = await queue.add(async () => {try{const val = await bot.getChat(moderationInfo.UserHistory.group.groupID).permissions return val}catch{}}) + if(!permissions) + return queue.add(async () => {try{await bot.restrictChatMember(moderationInfo.UserHistory.group.groupID, moderationInfo.UserHistory.user.userID, permissions)}catch{}}); queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}* has no other active reports. All bans are lifted.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); } else diff --git a/lib/realitioReporting.ts b/lib/realitioReporting.ts index e20fee1..7ce3af5 100644 --- a/lib/realitioReporting.ts +++ b/lib/realitioReporting.ts @@ -16,7 +16,6 @@ module.exports = async (web3, lastBlock, realitioAddress, proxyAddress) => { fromBlock: lastBlock, toBlock: 'latest' }) - console.log('realitio reporting: '+ruleEvents.length) // A Ruling was made for (const eventLog of ruleEvents) { diff --git a/lib/telegram/commands/addEvidence.ts b/lib/telegram/commands/addEvidence.ts index 03323be..00b608c 100644 --- a/lib/telegram/commands/addEvidence.ts +++ b/lib/telegram/commands/addEvidence.ts @@ -54,24 +54,38 @@ const upload = async (queue:any, bot: TelegramBot, lang: string, msg: TelegramBo const val = await bot.getFile(msg.reply_to_message.sticker.file_id); return val }catch{}}); + if(!file) + return } else if (msg.reply_to_message.photo){ file = await queue.add(async () => {try{const val = await bot.getFile(msg.reply_to_message.photo[msg.reply_to_message.photo.length-1].file_id) return val}catch{}}); + if(!file) + return } else if (msg.reply_to_message.audio){ file = await queue.add(async () => {try{const val = await bot.getFile(msg.reply_to_message.audio.file_id) return val}catch{}}); + if(!file) + return } else if (msg.reply_to_message.voice){ file = await queue.add(async () => {try{const val = await bot.getFile(msg.reply_to_message.voice.file_id) return val}catch{}}); + if(!file) + return } else if (msg.reply_to_message.video){ file = await queue.add(async () => {try{const val = await bot.getFile(msg.reply_to_message.video.file_id) return val}catch{}}); + if(!file) + return } else if (msg.reply_to_message.video_note){ file = await queue.add(async () => {try{const val = await bot.getFile(msg.reply_to_message.video_note.file_id) return val}catch{}}); + if(!file) + return } else if (msg.reply_to_message.document){ file = await queue.add(async () => {try{const val = await bot.getFile(msg.reply_to_message.document.file_id) return val}catch{}}); + if(!file) + return } const filePath = `https://api.telegram.org/file/bot${process.env.BOT_TOKEN}/`+file.file_path; const fileIPFS = await uploadFileEvidence(filePath, file.file_path.replace('/','_')); @@ -199,6 +213,8 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, try{ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `/evidence ${langJson[settings.lang].errorReply}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) return val}catch{}}) + if(!resp) + return myCache.set(resp.message_id, msg.chat.id) } catch (e){ console.log(e) @@ -238,6 +254,8 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, try{ const msgresponse = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `You did not specify an evidence group.`, opts) return val}catch{}}) + if(!msgresponse) + return myCache.set(msgresponse.message_id, msg.chat.id) } catch(e){ console.log(e) @@ -255,6 +273,8 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, try{ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].addevidence.errorId, opts) return val}catch{}}) + if(!resp) + return myCache.set(resp.message_id, msg.chat.id) } catch(e){ console.log(e) @@ -270,6 +290,8 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, try{ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorAllowance) return val}catch{}}); + if(!resp) + return myCache.set(resp.message_id, msg.chat.id) } catch (e){ console.log(e) diff --git a/lib/telegram/commands/captcha.ts b/lib/telegram/commands/captcha.ts index 7abb1bf..01225c5 100644 --- a/lib/telegram/commands/captcha.ts +++ b/lib/telegram/commands/captcha.ts @@ -50,6 +50,8 @@ const callback = async (queue: any, bot: any, settings: groupSettings, msg: any) }; const msg_welcome = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `Welcome [${msg.from.first_name}](tg://user?id=${msg.from.id}) ${langJson[settings.lang].greeting2}(${settings.rules}). ${langJson[settings.lang].greeting3}`, msg.chat.is_forum? optsThread: opts) return val}catch{}}); + if(!msg_welcome) + return myCache.set(msg_welcome.message_id, msg.chat.id) } catch(e){ console.log(e) diff --git a/lib/telegram/commands/fedinfo.ts b/lib/telegram/commands/fedinfo.ts index 81a839c..8e185e2 100644 --- a/lib/telegram/commands/fedinfo.ts +++ b/lib/telegram/commands/fedinfo.ts @@ -29,9 +29,13 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, const name = getFederationName(db, 'telegram', fed_id ?? fed_id_following); resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `This group is ${fed_id? 'in': 'following'} the *${name}* federation with id \`${fed_id ?? fed_id_following}\``, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) return val}catch{}}) + if(!resp) + return } else resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `No federation set.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) return val}catch{}}); + if(!resp) + return myCache.set(resp.message_id,msg.chat.id) } catch(e){ console.log(e) diff --git a/lib/telegram/commands/getChannel.ts b/lib/telegram/commands/getChannel.ts index 59bf291..2ef2053 100644 --- a/lib/telegram/commands/getChannel.ts +++ b/lib/telegram/commands/getChannel.ts @@ -25,15 +25,21 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, const inviteurl = getFederatedInviteURLChannel(db, 'telegram', settings.federation_id); const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `The notifications for this group's federation are sent to this [channel](${inviteurl}).`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}) return val}catch{}}); + if(!resp) + return myCache.set(resp.message_id, msg.chat.id) } if(!channel_invite && !msg.chat.is_forum){ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `Notifications channel for this group is not set. Ask an admin to \`/setchannel\`.`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}) return val}catch{}}); + if(!resp) + return myCache.set(resp.message_id, msg.chat.id) } else { const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `I notify this [channel](${channel_invite}) about moderation activity.`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id, disable_web_page_preview: true}:{parse_mode: "Markdown", disable_web_page_preview: true}) return val}catch{}}); + if(!resp) + return myCache.set(resp.message_id, msg.chat.id) } } diff --git a/lib/telegram/commands/getReports.ts b/lib/telegram/commands/getReports.ts index 7a19633..0531e8b 100644 --- a/lib/telegram/commands/getReports.ts +++ b/lib/telegram/commands/getReports.ts @@ -51,7 +51,9 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, } const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `DM me for report info : )`, opts) return val}catch{}}); - myCache.set(resp.message_id, msg.chat.id) + if(!resp) + return + myCache.set(resp?.message_id, msg.chat.id) return; } @@ -73,6 +75,8 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, const reports = getReportsUserInfo(db, 'telegram', group_id, user_id); const user = await queue.add(async () => {try{const val = await bot.getChatMember(group_id, user_id) return val}catch{}}) + if(!user) + return const fromUsername = (user.user.username || user.user.first_name || `no-username-set`); const ban_level = banHistory.length var reportMessage: string = "" diff --git a/lib/telegram/commands/getRules.ts b/lib/telegram/commands/getRules.ts index 3f39a24..46259fb 100644 --- a/lib/telegram/commands/getRules.ts +++ b/lib/telegram/commands/getRules.ts @@ -23,6 +23,8 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, getRule(db,'telegram', msg.chat.id,Math.floor(Date.now()/1000)) const msgresponse = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].rules}(${settings.rules}).`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id, disable_web_page_preview: false}:{parse_mode: "Markdown", disable_web_page_preview: false}) return val}catch{}}); + if(!msgresponse) + return; myCache.set(msgresponse.message_id, msg.chat.id) } diff --git a/lib/telegram/commands/greeting.ts b/lib/telegram/commands/greeting.ts index 6cda784..2b60886 100644 --- a/lib/telegram/commands/greeting.ts +++ b/lib/telegram/commands/greeting.ts @@ -56,6 +56,8 @@ const callback = async (queue: any, bot: any, settings: groupSettings, msg: any) msg_welcome = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `Hi 👋 Welcome [${msg.from.first_name}](tg://user?id=${msg.from.id}). ${langJson[settings.lang].greeting2}(${settings.rules}).`, msg.chat.is_forum? {message_thread_id: settings.thread_id_welcome,disable_web_page_preview: true}: {disable_web_page_preview: true}) return val}catch{}}); } + if(!msg_welcome) + return myCache.set(msg_welcome.message_id, msg.chat.id) } catch(e){ console.log(e) diff --git a/lib/telegram/commands/joinfed.ts b/lib/telegram/commands/joinfed.ts index f794ef3..3cdd6bc 100644 --- a/lib/telegram/commands/joinfed.ts +++ b/lib/telegram/commands/joinfed.ts @@ -27,6 +27,8 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}) return val}catch{}}); + if (!resp) + return resp myCache.set(resp.message_id, msg.chat.id) } else{ const name = getFederationName(db, 'telegram',match[1]) @@ -35,6 +37,8 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}) return val}catch{}}); + if (!resp) + return resp myCache.set(resp.message_id, msg.chat.id) } else if (msg.from.id == match[1]){ diff --git a/lib/telegram/commands/newfed.ts b/lib/telegram/commands/newfed.ts index 1bb3de3..cdbd5a4 100644 --- a/lib/telegram/commands/newfed.ts +++ b/lib/telegram/commands/newfed.ts @@ -51,6 +51,8 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, } const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `DM me for help with your federation : )`, opts) return val}catch{}}); + if (!resp) + return resp myCache.set(resp.message_id, msg.chat.id) return; } diff --git a/lib/telegram/commands/report.ts b/lib/telegram/commands/report.ts index 6c24d66..955481f 100644 --- a/lib/telegram/commands/report.ts +++ b/lib/telegram/commands/report.ts @@ -34,6 +34,8 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b if (!msg.reply_to_message) { const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `/report ${langJson[settings.lang].errorReply}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) return val}catch{}}); + if (!resp) + return resp myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return; } @@ -41,6 +43,8 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b if (msg.reply_to_message.date < Date.now()/1000-86400*7){ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `Live and let live. This message is more than one week old. The future is asynchronous, but we believe moderation should not be punitive. Next time try to make the report sooner.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) return val}catch{}}); + if (!resp) + return resp myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return; } @@ -55,7 +59,8 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b else resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.errorModBot}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) return val}catch{}}); - + if (!resp) + return resp myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return } @@ -63,9 +68,13 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b if(!settings.admin_reportable){ report = await queue.add(async () => {try{const val = await bot.getChatMember(msg.chat.id,msg.reply_to_message.from.id) return val}catch{}}) + if (!report) + return report if(report.status === "administrator" || report.status === "creator"){ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.errorAdmin}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) return val}catch{}}); + if (!resp) + return resp myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return } @@ -87,6 +96,8 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b if (reportedQuestionId){ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.reported}(https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${reportedQuestionId})`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true}) return val}catch{}}); + if (!resp) + return resp myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return; } @@ -98,6 +109,8 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b if (!rules){ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].report.norules, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) return val}catch{}}); + if (!resp) + return resp myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return; } @@ -110,6 +123,8 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b const reportAllowance = getAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id)); const reporter = await queue.add(async () => {try{const val = await bot.getChatMember(msg.chat.id,msg.from.id) return val}catch{}}) + if (!reporter) + return reporter if(!settings.admin_reportable && (reporter.status === "administrator" || reporter.status === "creator")){ console.log(report.status) } else if (!reportAllowance){ @@ -117,6 +132,8 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b } else if (currentTimeMs < reportAllowance.timestamp_refresh + 28800 && reportAllowance.report_allowance == 0 ){ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].report.noallowance, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) return val}catch{}}); + if (!resp) + return resp myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return; } else{ @@ -159,6 +176,8 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b const msgLink = `https://t.me/c/${String(msg.chat.id).substring(4)}/${msg.chat.is_forum? `${msg.message_thread_id}/`:''}${msg.reply_to_message.message_id}`; const reportRequestMsg: TelegramBot.Message = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].socialConsensus.consensus2} [${fromUsername}](tg://user?id=${reportedUserID}) ${langJson[settings.lang].socialConsensus.consensus3}(${rules}) ${langJson[settings.lang].socialConsensus.consensus4}(${msgLink}) ([${langJson[settings.lang].socialConsensus.consensus5}](${msgBackup}))?`, msg.chat.is_forum? optsThread: opts) return val}catch{}}); + if (!reportRequestMsg) + return myCache.set([msg.chat.id, msg.reply_to_message.message_id].toString(),`${msg.chat.is_forum? `${msg.message_thread_id}/${reportRequestMsg.message_id}`:''}${reportRequestMsg.message_id}`) ; myCacheGarbageCollectionSlow.set(reportRequestMsg.message_id, msg.chat.id) return; @@ -174,6 +193,8 @@ const reportMsg = async (queue: any, settings: groupSettings, db: any, bot: any, if (!inviteURL){ inviteURL = await queue.add(async () => {try{const val = await bot.exportChatInviteLink(msg.chat.id) return val}catch{}}); + if (!inviteURL) + return setInviteURL(db, 'telegram', String(msg.chat.id), inviteURL); } myCache.set(msg.chat.id, inviteURL) diff --git a/lib/telegram/commands/setChannel.ts b/lib/telegram/commands/setChannel.ts index a1720df..4c8b561 100644 --- a/lib/telegram/commands/setChannel.ts +++ b/lib/telegram/commands/setChannel.ts @@ -30,15 +30,21 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: Teleg if (!newmatch || newmatch.length < 2){ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `/setchannel must be followed by a channel id. [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpnotifications) me if you need more help : )`, {parse_mode: "Markdown", disable_web_page_preview: true}) return val}catch{}}); + if(!resp) + return myCache.set(resp.message_id, msg.chat.id) return; } try{ const channel = await queue.add(async () => {try{const val = await bot.getChat(newmatch[1]) return val}catch{}}); + if(!channel) + return if(channel.type !== "channel"){ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, '/setchannel must be followed by a valid channel.') return val}catch{}}); + if(!resp) + return myCache.set(resp.message_id, msg.chat.id) return; } @@ -46,6 +52,8 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: Teleg try{ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${newmatch[1]} is not a valid channel.`) return val}catch{}}); + if(!resp) + return myCache.set(resp.message_id, msg.chat.id) } catch(e){ console.log(e) @@ -54,28 +62,40 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: Teleg } const channelUser = await queue.add(async () => {try{const val = await bot.getChatMember(newmatch[1], String(msg.from.id)) return val}catch{}}); + if(!channelUser) + return if(channelUser.status !== "administrator" && channelUser.status !== "creator"){ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, 'You are not an authorized admin of the channel.') return val}catch{}}); + if(!resp) + return myCache.set(resp.message_id, msg.chat.id) return; } const channelUserSusie = await queue.add(async () => {try{const val = await bot.getChatMember(newmatch[1], botId) return val}catch{}}); + if(!channelUserSusie) + return if (channelUserSusie.status !== "administrator"){ const resp = await queue.add(async () => {try{const val = await bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {caption: langJson[settings.lang].errorAdminRights}) return val}catch{}}); + if(!resp) + return myCache.set(resp.message_id, msg.chat.id) return; } if(!channelUserSusie.can_invite_users){ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, 'Susie must be able to invite users to the channel.') return val}catch{}}); + if(!resp) + return myCache.set(resp.message_id, msg.chat.id) return; } const invite_url_channel = await queue.add(async () => {try{const val = await bot.exportChatInviteLink(newmatch[1]) return val}catch{}}); + if(!invite_url_channel) + return setInviteURLChannel(db, 'telegram', String(msg.chat.id), invite_url_channel); setChannelID(db, 'telegram', String(msg.chat.id), newmatch[1]); queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `Moderation notifications will now be sent to this [channel](${invite_url_channel}).`, {parse_mode: "Markdown", disable_web_page_preview: true})}catch{}}); diff --git a/lib/telegram/commands/setChannelFed.ts b/lib/telegram/commands/setChannelFed.ts index 8cf06ca..abec3e4 100644 --- a/lib/telegram/commands/setChannelFed.ts +++ b/lib/telegram/commands/setChannelFed.ts @@ -27,6 +27,8 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, if (!name){ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `No federation found. Please first create a federation with \`/newfed\``,msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown', disable_web_page_preview: true} : {parse_mode: 'Markdown', disable_web_page_preview: true}) return val}catch{}}); + if(!resp) + return myCache.set(resp.message_id, msg.chat.id) return; } @@ -35,15 +37,21 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, console.log(msg) const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `/setchannelfed must be followed by a channel id. [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpnotifications) me if you need more help : )`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown', disable_web_page_preview: true} : {parse_mode: 'Markdown', disable_web_page_preview: true}) return val}catch{}}); + if(!resp) + return myCache.set(resp.message_id, msg.chat.id) return; } try{ const channel = await queue.add(async () => {try{const val = await bot.getChat(newmatch[1]) return val}catch{}}); + if(!channel) + return if(channel.type !== "channel"){ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, '/setchannelfed must be followed by a valid channel.', msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) return val}catch{}}); + if(!resp) + return myCache.set(resp.message_id, msg.chat.id) return; } @@ -51,6 +59,8 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, try{ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${newmatch[1]} is not a valid channel.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) return val}catch{}}); + if(!resp) + return myCache.set(resp.message_id, msg.chat.id) } catch(e){ console.log(e) @@ -59,29 +69,40 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, } const channelUser = await queue.add(async () => {try{const val = await bot.getChatMember(newmatch[1], String(msg.from.id)) return val}catch{}}); - console.log(channelUser) + if(!channelUser) + return if(channelUser.status !== "administrator" && channelUser.status !== "creator"){ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, 'You are not an authorized admin of the channel.',msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) return val}catch{}}); + if(!resp) + return myCache.set(resp.message_id, msg.chat.id) return; } const channelUserSusie = await queue.add(async () => {try{const val = await bot.getChatMember(newmatch[1], botId) return val}catch{}}); + if(!channelUserSusie) + return if (channelUserSusie.status !== "administrator"){ const resp = await queue.add(async () => {try{const val = await bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {caption: langJson[settings.lang].errorAdminRights},msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) return val}catch{}}); + if(!resp) + return myCache.set(resp.message_id, msg.chat.id) return; } if(!channelUserSusie.can_invite_users){ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, 'Susie must be able to invite users to the channel.',msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) return val}catch{}}); + if(!resp) + return myCache.set(resp.message_id, msg.chat.id) return; } const invite_url_channel = await queue.add(async () => {try{const val = await bot.exportChatInviteLink(newmatch[1]) return val}catch{}}); + if(!invite_url_channel) + return setFederationInviteURLChannel(db, 'telegram', String(msg.from.id), invite_url_channel); setFederationChannelID(db, 'telegram', String(msg.from.id), newmatch[1]); queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `Moderation notifications for the federation will now be sent to this [channel](${invite_url_channel}).`, {parse_mode: "Markdown"})}catch{}}); diff --git a/lib/telegram/commands/setLanguage.ts b/lib/telegram/commands/setLanguage.ts index 55c5c51..8e281cb 100644 --- a/lib/telegram/commands/setLanguage.ts +++ b/lib/telegram/commands/setLanguage.ts @@ -56,8 +56,12 @@ const setLanguageConfirm = async (queue: any, db: any, bot: any, settings: group if (msg.chat.is_forum){ const msgDefaultRules = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[langCode].defaultRulesMsg1}(${langJson[langCode].defaultRules}). ${langJson[langCode].defaultRulesMsg2}.`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: settings.thread_id_rules}: {}) return val}catch{}}) + if(!msgDefaultRules) + return const msgRules = await queue.add(async () => {try{const val = await bot.forwardMessage(msg.chat.id, msg.chat.id, msgDefaultRules.message_id, {message_thread_id: settings.thread_id_rules}) return val}catch{}}); + if(!msgRules) + return queue.add(async () => {try{await bot.pinChatMessage(msg.chat.id, msgRules.message_id, {message_thread_id: settings.thread_id_rules})}catch{}}) } } catch(e){ diff --git a/lib/telegram/commands/setRules.ts b/lib/telegram/commands/setRules.ts index f51725c..9c3d471 100644 --- a/lib/telegram/commands/setRules.ts +++ b/lib/telegram/commands/setRules.ts @@ -28,6 +28,8 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, if(msg.chat.is_forum){ const msgRules = await queue.add(async () => {try{const val = await bot.forwardMessage(msg.chat.id, msg.chat.id, msg.reply_to_message.message_id, {message_thread_id: settings.thread_id_rules}) return val}catch{}}); + if(!msgRules) + return queue.add(async () => {try{await bot.pinChatMessage(msg.chat.id, msgRules.message_id, {message_thread_id: settings.thread_id_rules})}catch{}}) } } else if (validateUrl(match[1])) { @@ -35,6 +37,8 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, if(msg.chat.is_forum){ const msgRules = await queue.add(async () => {try{const val = await bot.forwardMessage(msg.chat.id, msg.chat.id, msg.message_id, {message_thread_id: settings.thread_id_rules}) return val}catch{}}); + if(!msgRules) + return queue.add(async () => {try{await bot.pinChatMessage(msg.chat.id, msgRules.message_id, {message_thread_id: settings.thread_id_rules})}catch{}}) } queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[settings.lang].rulesUpdated, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules}: {})}catch{}}); diff --git a/lib/telegram/commands/start.ts b/lib/telegram/commands/start.ts index 17799b5..09b927f 100644 --- a/lib/telegram/commands/start.ts +++ b/lib/telegram/commands/start.ts @@ -56,6 +56,8 @@ const callback = async (queue:any, db: any, settings: groupSettings, bot: any, b } const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `My native language is English. I am learning new languages, starting with [Spanish](https://linguo.kleros.io/home). Please reach out to @SusieSupport to let me know which language I should learn next.\n\nTo continue, please understand that I can currently only effectively moderate communities in English.`, opts) return val}catch{}}) + if(!resp) + return myCache.set(msg.chat.id,resp.message_id) return; } @@ -85,6 +87,8 @@ Join my news channel @KlerosModerateNews to get information on all the latest up const botUser = await queue.add(async () => {try{const val = await bot.getChatMember(msg.chat.id, botID) return val}catch{}}) + if(!botUser) + return if(botUser.status !== "administrator" || !botUser.can_restrict_members){ const video = msg.chat.is_forum? 'QmSdP3SDoHCdW739xLDBKM3gnLeeZug77RgwgxBJSchvYV/guide_topics.mp4' : 'QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4' queue.add(async () => {try{await bot.sendVideo(msg.chat.id, `https://ipfs.kleros.io/ipfs/${video}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, caption: "Please give Susie full admin rights.\n\nThen try to /start community moderation again."} : {caption: "Please give Susie full admin rights.\n\nThen try to /start community moderation again."})}catch{}}); @@ -129,7 +133,8 @@ const topicMode = async (queue: any, db:any, bot: any, settings: groupSettings, // tg bugging, won't display icon_color if set const topicRules = await queue.add(async () => {try{const val = await bot.createForumTopic(chat.id, 'Rules', {icon_custom_emoji_id: '4929691942553387009'})}catch{}}); const topicModeration = await queue.add(async () => {try{const val = await bot.createForumTopic(chat.id, 'Moderation Notifications', {icon_custom_emoji_id: '4929336692923432961'})}catch{}}); - + if(!topicRules || !topicModerationxw) + return queue.add(async () => {try{await bot.sendMessage(chat.id, `Please follow the community [rules](${settings.rules}). Misbehavior can be reported with /report.`, {parse_mode: "Markdown", message_thread_id: topicRules.message_thread_id})}catch{}}); //bot.sendMessage(chat_id, `${langJson[settings.lang].greeting2}(${settings.rules}). ${langJson[settings.lang].greeting3}`, {parse_mode: "Markdown", message_thread_id: topicRules.message_thread_id}); queue.add(async () => {try{await bot.sendMessage(chat.id, `${langJson[settings.lang].greeting1}[Kleros Moderate](https://kleros.io/moderate/).`, {parse_mode: "Markdown", message_thread_id: topicModeration.message_thread_id})}catch{}}); diff --git a/lib/telegram/commands/toggleWelcome.ts b/lib/telegram/commands/toggleWelcome.ts index b38b74d..b8dadd0 100644 --- a/lib/telegram/commands/toggleWelcome.ts +++ b/lib/telegram/commands/toggleWelcome.ts @@ -23,8 +23,12 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, const createWelcomeThread = async (queue:any, db: any, settings: groupSettings, bot: any, msg: any) => { const topicWelcome = await queue.add(async () => {try{const val = await bot.createForumTopic(msg.chat.id, 'Welcome', {icon_custom_emoji_id: '4929292553544531969'}) return val}catch{}}); + if(!topicWelcome) + return const msg1: TelegramBot.Message = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].greeting1}[Kleros Moderate](https://kleros.io/moderate/).\n\nPlease treat this group with the same respect you would a public park. We, too, are a shared community resource — a place to share..`, {parse_mode: "Markdown", message_thread_id: topicWelcome.message_thread_id}) return val}catch{}}); + if(!msg1) + return queue.add(async () => {try{await bot.pinChatMessage(msg.chat.id, msg1.message_id, {message_thread_id: topicWelcome.message_thread_id})}catch{}}) setThreadIDWelcome(db, 'telegram', String(msg.chat.id), String(topicWelcome.message_thread_id)) } diff --git a/lib/telegram/index.ts b/lib/telegram/index.ts index 15a0733..0833ed7 100644 --- a/lib/telegram/index.ts +++ b/lib/telegram/index.ts @@ -229,6 +229,8 @@ bot.on('callback_query', async function onCallbackQuery(callbackQuery: TelegramB } else if (Number(calldata[0]) === 6){ const member = await queue.add(async () => {try{const val = await bot.getChatMember(callbackQuery.message.chat.id, callbackQuery.from.id) return val}catch{}}) + if(!member) + return if (member.status === "admin" || member.status === "creator"){ queue.add(async () => {try{await bot.deleteMessage(callbackQuery.message.chat.id, callbackQuery.message.message_id)}catch{}}) start.callback(queue, db, settings,bot,String(botId),callbackQuery.message,[],batchedSend, true) @@ -302,6 +304,8 @@ commands.forEach((command) => { try{ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, "Susie is already moderating this community.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id} : {}) return val}catch{}}); + if(!resp) + return myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return } catch(e){ @@ -328,6 +332,8 @@ commands.forEach((command) => { try{ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[groupSettings.lang].errorAdminOnly, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) return val}catch{}}) + if(!resp) + return myCacheGarbageCollection.set(resp.message_id, msg.chat.id) } catch(e){ console.log(e) From efaca35a8efb6e50392d9b4da2ce524956b640db Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Thu, 22 Dec 2022 18:00:02 -0700 Subject: [PATCH 017/111] chore: change help message --- .env.dist | 8 ++++++-- lib/telegram/commands/getLeaderboard.ts | 2 +- lib/telegram/commands/help.ts | 6 +++--- lib/telegram/commands/start.ts | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.env.dist b/.env.dist index 43ab279..fef1771 100644 --- a/.env.dist +++ b/.env.dist @@ -4,5 +4,9 @@ REALITIO_ARBITRATOR= TEMPLATE_ID= WEB3_PROVIDER_URL= NTBA_FIX_319=1 -BOT_TOKEN= -NTBA_FIX_319=1 +CHAIN_ID = +MODERATE_SUBGRAPH=https://api.thegraph.com/subgraphs/name/shotaronowhere/kleros-moderate-goerli +TRANSACTION_BATCHER_CONTRACT_ADDRESS= +JUSTICE_LEAGUE= +PRIVATE_KEY= +BOT_USERNAME= \ No newline at end of file diff --git a/lib/telegram/commands/getLeaderboard.ts b/lib/telegram/commands/getLeaderboard.ts index 3d37768..2109c57 100644 --- a/lib/telegram/commands/getLeaderboard.ts +++ b/lib/telegram/commands/getLeaderboard.ts @@ -32,7 +32,7 @@ boy who cried wolf (>2/3 answered !yes, >10 reports) const callback = async (db: any, settings: groupSettings, bot: any, botid: number, msg: any) => { try{ - const reports = await getLeaderboard(msg.chat.id); + const reports = await getLeaderboard(msg.chat.id, String(botid)); if (reports.length == 0){ bot.sendMessage(msg.chat.id, "No active leaderboard", msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}:{parse_mode: "Markdown"}); return; diff --git a/lib/telegram/commands/help.ts b/lib/telegram/commands/help.ts index eb7429b..6e92511 100644 --- a/lib/telegram/commands/help.ts +++ b/lib/telegram/commands/help.ts @@ -258,7 +258,7 @@ How to enable notification channels: 4. Use that channel ID to set notifications with /setchannel in the original group *User commands*: -- \'/notifications\': Returns current notification channel +- \`/notifications\`: Returns current notification channel *Admin commands*: - \`/setchannel\` : Sets the notification channel to the specified channel id - \`/setfedchannel\` : Sets the notification channel for your federation to the specified channel id` @@ -322,12 +322,12 @@ If you would like to offer your services as a lawyer or solicit services, please case 'open': { queue.add(async () => {try{await bot.editMessageText(`🕵️ *Privacy* 🕵️ -Effective moderation requires understsanding the full context and nuance of messages. To achieve this goal, Susie can: +To facillitate effective moderation, requiring full context and nuance of messages, Susie can: - save messages to submit as evidence on behalf of users. - create open invitations for moderators or jurors to join the group and investigate reports. -When you invite Susie to your group, have a similar expectation of privacy as a conversation in a public town square. Susie enforces the rules protecting members from harassment, but free speech and sharing of unpopular opinions are also protected with a fair dispute resolution process. +When you invite Susie to your group, have a similar expectation of privacy as a conversation in a public town square. ` ,optsResponse)}catch{}}) break; diff --git a/lib/telegram/commands/start.ts b/lib/telegram/commands/start.ts index 09b927f..2e25c72 100644 --- a/lib/telegram/commands/start.ts +++ b/lib/telegram/commands/start.ts @@ -133,7 +133,7 @@ const topicMode = async (queue: any, db:any, bot: any, settings: groupSettings, // tg bugging, won't display icon_color if set const topicRules = await queue.add(async () => {try{const val = await bot.createForumTopic(chat.id, 'Rules', {icon_custom_emoji_id: '4929691942553387009'})}catch{}}); const topicModeration = await queue.add(async () => {try{const val = await bot.createForumTopic(chat.id, 'Moderation Notifications', {icon_custom_emoji_id: '4929336692923432961'})}catch{}}); - if(!topicRules || !topicModerationxw) + if(!topicRules || !topicModeration) return queue.add(async () => {try{await bot.sendMessage(chat.id, `Please follow the community [rules](${settings.rules}). Misbehavior can be reported with /report.`, {parse_mode: "Markdown", message_thread_id: topicRules.message_thread_id})}catch{}}); //bot.sendMessage(chat_id, `${langJson[settings.lang].greeting2}(${settings.rules}). ${langJson[settings.lang].greeting3}`, {parse_mode: "Markdown", message_thread_id: topicRules.message_thread_id}); From e1c803a478871bd5eb12f6f759ca5b1ec10cf827 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Thu, 22 Dec 2022 18:00:33 -0700 Subject: [PATCH 018/111] fix: refactor --- lib/graph.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/graph.ts b/lib/graph.ts index ad09f5a..e211d24 100644 --- a/lib/graph.ts +++ b/lib/graph.ts @@ -38,9 +38,9 @@ const getAllowance = async (botAddress: string, platform: string, groupId: strin } } -const getLeaderboard = async (group_id: string) => { +const getLeaderboard = async (group_id: string, botAddress: string) => { const query = `{ - userHistories(first: 10, orderBy: countReportsMadeAndRespondedYes, orderDirection: desc, where:{group_:{botAddress: "${process.env.BOT_ACCOUNT}", groupID: "${group_id}", platform: "Telegram"}}) { + userHistories(first: 10, orderBy: countReportsMadeAndRespondedYes, orderDirection: desc, where:{group_:{botAddress: "${botAddress}", groupID: "${group_id}", platform: "Telegram"}}) { status countReportsMadeAndRespondedYes user{ From eaba1137e71f87aace42409dea34f06c2fe38543 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Tue, 10 Jan 2023 01:26:14 +0100 Subject: [PATCH 019/111] feat(privacy): masked usernames for private groups --- lib/bot-core.ts | 37 ++++++++++---------- lib/cron.ts | 7 ++-- lib/db.ts | 9 ++--- lib/realitioReporting.ts | 4 ++- lib/telegram/commands/help.ts | 11 +++--- lib/telegram/commands/report.ts | 47 ++++++++++++-------------- lib/telegram/commands/setRules.ts | 4 ++- lib/telegram/commands/start.ts | 19 ++++++----- lib/telegram/commands/toggleWelcome.ts | 2 +- lib/telegram/index.ts | 6 +++- package.json | 7 ++-- 11 files changed, 81 insertions(+), 72 deletions(-) diff --git a/lib/bot-core.ts b/lib/bot-core.ts index 6bd387d..f1ebf01 100644 --- a/lib/bot-core.ts +++ b/lib/bot-core.ts @@ -3,6 +3,7 @@ import {getRealityETHV30} from "./ethers"; const _contract = require('./abi/RealityETH_v3_0.json') const Web3 = require('web3') const web3 = new Web3(process.env.WEB3_PROVIDER_URL) +const ob = require('urbit-ob') const contract = new web3.eth.Contract( _contract, @@ -14,21 +15,22 @@ interface RealityBanResult { questionUrl: string } -export const reportUser = async (batchedSend:any, lang: string, hasBanningPermission: boolean, fromUsername: string, UserID: string, platform: string, group: string, inviteURL: string, groupID: string, rules: string, message: string, messageBackup: string, reportedBy: string): Promise => { - const minBond = utils.parseUnits('5', 18); // 5 DAI +export const reportUser = async (batchedSend:any, lang: string, hasBanningPermission: boolean, fromUsername: string, UserID: string, platform: string, group: string, inviteURL: string, groupID: string, rules: string, message: string, messageBackup: string, reportedBy: string, isPrivate: boolean): Promise => { + const minBond = utils.parseUnits('5', 12); // 5 DAI + var fromUsernameUrbit; + if(isPrivate){ + // private group + const hashedUserID = web3.utils.sha3(UserID+process.env.secret); + fromUsernameUrbit = ob.patp(hashedUserID.substring(0,8)) + } + const delim = '\u241f'; + const question = isPrivate? fromUsernameUrbit+delim+rules+delim+messageBackup+delim+reportedBy : fromUsername+delim+UserID+delim+platform+delim+group+delim+inviteURL+delim+groupID+delim+rules+delim+message+delim+messageBackup+delim+reportedBy ; + const template_id = Number(isPrivate? process.env.TEMPLATE_ID_PRIVATE: process.env.TEMPLATE_ID) + const questionId = await askQuestionWithMinBond( batchedSend, - lang, - fromUsername, - UserID, - platform, - group, - inviteURL, - groupID, - rules, - message, - messageBackup, - reportedBy, + question, + template_id, minBond ); @@ -39,21 +41,18 @@ export const reportUser = async (batchedSend:any, lang: string, hasBanningPermis } -async function askQuestionWithMinBond(batchedSend: any, lang: string, fromUsername: string, UserID: string, platform: string, group: string, inviteURL: string, groupID: string, rulesUrl: string|BigNumber, message: string, messageBackup: string, reportedBy: string, minBond: number|BigNumber): Promise { +async function askQuestionWithMinBond(batchedSend: any, question: string, template_id: number, minBond: number|BigNumber): Promise { // A question is automatically created in Realitio with an answer in favor of banning the user. //const realityETHV30 = getRealityETHV30(process.env.REALITY_ETH_V30, process.env.PRIVATE_KEY); - const delim = '\u241f'; const openingTs = Math.floor(new Date().getTime()/1000); - const question = fromUsername+delim+UserID+delim+platform+delim+group+delim+inviteURL+delim+groupID+delim+rulesUrl+delim+message+delim+messageBackup+delim+reportedBy; const arbitrator = process.env.REALITIO_ARBITRATOR; - const templateId = process.env.TEMPLATE_ID; const timeout = 86400; const reality = process.env.REALITY_ETH_V30; const txnBatchSender = process.env.TRANSACTION_BATCHER_CONTRACT_ADDRESS; const nonce = 0; const contentHash = web3.utils.soliditySha3( - { type: 'uint256', value: templateId }, + { type: 'uint256', value: template_id }, { type: 'uint32', value: openingTs }, { type: 'string', value: question }); @@ -68,7 +67,7 @@ async function askQuestionWithMinBond(batchedSend: any, lang: string, fromUserna await batchedSend({ args: [ - templateId, + template_id, question, arbitrator, timeout, // 1 day diff --git a/lib/cron.ts b/lib/cron.ts index 1870a88..0f14b81 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -27,8 +27,9 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo const privateKey = process.env.PRIVATE_KEY const account = web3.eth.accounts.privateKeyToAccount(privateKey) web3.eth.accounts.wallet.add(account) - const currentTime = Math.floor(Date.now()/1000) - const currentBlock = await web3.eth.getBlockNumber() + const currentTime = Math.min(Math.floor(Date.now()/1000), history.last_timestamp + 5000) + const block = await web3.eth.getBlockNumber() + const currentBlock = Math.min(block+1000,block) if (!history) history = { last_timestamp: currentTime, @@ -268,6 +269,7 @@ const validate = (chatId: string): groupSettings=> { greeting_mode: false, captcha: false, admin_reportable: false, + privacy_mode: true, thread_id_rules: '', thread_id_welcome: '', thread_id_notifications: '', @@ -284,6 +286,7 @@ const validate = (chatId: string): groupSettings=> { greeting_mode: groupSettings?.greeting_mode ?? defaultSettings.greeting_mode, admin_reportable: groupSettings?.admin_reportable ?? defaultSettings.admin_reportable, captcha: groupSettings?.captcha ?? defaultSettings.captcha, + privacy_mode: groupSettings?.privacy_mode ?? defaultSettings.privacy_mode, thread_id_rules: groupSettings?.thread_id_rules ?? defaultSettings.thread_id_rules, thread_id_welcome: groupSettings?.thread_id_welcome ?? defaultSettings.thread_id_rules, thread_id_notifications: groupSettings?.thread_id_notifications ?? defaultSettings.thread_id_notifications, diff --git a/lib/db.ts b/lib/db.ts index 20497db..825b542 100644 --- a/lib/db.ts +++ b/lib/db.ts @@ -391,6 +391,7 @@ const getGroupSettings = (db: any, platform: string, groupId: string): groupSett greeting_mode: result?.greeting_mode, captcha: result?.captcha, admin_reportable: result?.admins_reportable, + privacy_mode: result?.privacy_mode, federation_id: result?.federation_id, federation_id_following: result?.federation_id_following, } @@ -434,7 +435,7 @@ const getReportsUserInfoFederation = (db:any, platform: string, userId: string, const getReportsUserInfoActive = (db:any, platform: string, groupId: string, userId: string) => { try{ - const stmt = db.prepare('SELECT question_id, active,msgBackup, msg_id, evidenceIndex, timestamp_msg, finalized FROM reports WHERE user_id = ? AND group_id = ? AND platform = ? AND NOT finalized = 1'); + const stmt = db.prepare('SELECT question_id, active,msgBackup, msg_id, evidenceIndex, timestamp_msg, finalized FROM reports WHERE user_id = ? AND group_id = ? AND platform = ? AND (NOT finalized = 1 OR finalized IS NULL)'); return stmt.all(userId, groupId, platform); } catch(err){ console.log("db error: getReportsUserInfoActive, "+err); @@ -505,9 +506,9 @@ const setReport = (db: any, questionId: string, active: boolean, answered: boole } } -const getActiveEvidenceGroupId = (db: any, platform: string, groupId: string, evidenceIndex: number) => { +const getActiveEvidenceGroupId = (db: any, platform: string, groupId: string, evidenceIndex: string) => { try{ - const stmt = db.prepare( `SELECT question_id FROM reports WHERE platform = ? AND group_id = ? AND evidenceIndex = ? AND NOT finalized = 1`); + const stmt = db.prepare( `SELECT question_id FROM reports WHERE platform = ? AND group_id = ? AND evidenceIndex = ? AND (NOT finalized = 1 OR finalized IS NULL)`); return stmt.get(platform, groupId, evidenceIndex)?.question_id; } catch(err) { console.log("db error: getActiveEvidenceGroupId" + err); @@ -743,7 +744,7 @@ const getFederatedBanHistory = (db: any, platform: string, userId: string, feder const getUsersWithQuestionsNotFinalized = (db: any, platform: string, groupId: string) => { try{ - const stmt = db.prepare( `SELECT DISTINCT user_id, username FROM reports WHERE platform = ? AND group_id = ? AND NOT finalized = 1`); + const stmt = db.prepare( `SELECT DISTINCT user_id, username FROM reports WHERE platform = ? AND group_id = ? AND (NOT finalized = 1 OR finalized IS NULL)`); return stmt.all(platform, groupId); } catch(err) { console.log("db error: getActiveEvidenceGroupId"); diff --git a/lib/realitioReporting.ts b/lib/realitioReporting.ts index 7ce3af5..b8d10f4 100644 --- a/lib/realitioReporting.ts +++ b/lib/realitioReporting.ts @@ -11,10 +11,12 @@ module.exports = async (web3, lastBlock, realitioAddress, proxyAddress) => { _proxy.abi, proxyAddress ) + const block = await web3.eth.getBlockNumber() + // console.log(lastBlock) const ruleEvents = await proxyInstance.getPastEvents('Ruling', { fromBlock: lastBlock, - toBlock: 'latest' + toBlock: lastBlock < block - 1000 ? lastBlock + 1000:'latest' }) // A Ruling was made diff --git a/lib/telegram/commands/help.ts b/lib/telegram/commands/help.ts index 6e92511..c05b7e6 100644 --- a/lib/telegram/commands/help.ts +++ b/lib/telegram/commands/help.ts @@ -322,13 +322,10 @@ If you would like to offer your services as a lawyer or solicit services, please case 'open': { queue.add(async () => {try{await bot.editMessageText(`🕵️ *Privacy* 🕵️ -To facillitate effective moderation, requiring full context and nuance of messages, Susie can: +Effective moderation depends on access to the full context of a reported message. To provide context, users can request Susie to save messages to submit as evidence on their behalf. Susie manages moderation private and public groups differently, -- save messages to submit as evidence on behalf of users. -- create open invitations for moderators or jurors to join the group and investigate reports. - -When you invite Susie to your group, have a similar expectation of privacy as a conversation in a public town square. -` +- In *private* groups, reports are created using psuedonyms for users involved. +- In *public* groups, reports are created using original usernames. Susie also creates open invitations for moderators to join the group and investigate reports.` ,optsResponse)}catch{}}) break; //Susie is [open source](https://github.com/kleros/kleros-moderate). Feel free to make an issue, feature request, bug report, comments, suggests, PRs, forks, etc : ) @@ -351,7 +348,7 @@ Helpful commands: - /start: Starts me. You've probably already used this. - /help: Sends this message and I'll tell you more about myself. -Select a feature to learn more. My [documentation](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator) is also helpful, or ask a question in @SusieSupport.`; +Select a feature to learn more. My [documentation](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator) is also helpful, or ask a question in @SusieSupport. You can follow news and updates in @KlerosModerateNews.`; //Important: I moderate groups by crowd-sourcing community input with Gnosis Chain. Make sure you or some community members get DAI on Gnosis Chain to participate actively. diff --git a/lib/telegram/commands/report.ts b/lib/telegram/commands/report.ts index 955481f..0d2bf65 100644 --- a/lib/telegram/commands/report.ts +++ b/lib/telegram/commands/report.ts @@ -4,10 +4,13 @@ import { groupSettings } from "../../../types"; import {upload} from "./addEvidence" import {reportUser} from "../../bot-core"; import langJson from "../assets/lang.json"; +const Web3 = require('web3') +const web3 = new Web3(process.env.WEB3_PROVIDER_URL) /* * /report */ +const ob = require('urbit-ob') const regexp = /\/report\s?(.+)?/ // cacheIndex => groupID,reported message id => [pending report message id] const NodeCache = require( "node-cache" ); @@ -115,11 +118,14 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b return; } - - const evidencepath = await upload(queue, bot, settings.lang, msg); + const chatobj = await queue.add(async () => {try{const val = await bot.getChat(msg.chat.id) + return val}catch{}}); + if (!chatobj) + return + const isPrivate = !chatobj.active_usernames; + const evidencepath = await upload(queue, bot, settings.lang, msg, isPrivate); const msgBackup = 'https://ipfs.kleros.io'+evidencepath; // TODO report - const reportAllowance = getAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id)); const reporter = await queue.add(async () => {try{const val = await bot.getChatMember(msg.chat.id,msg.from.id) return val}catch{}}) @@ -145,6 +151,7 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b const opts = { parse_mode: 'Markdown', reply_to_message_id: msg.reply_to_message.message_id, + ...(msg.chat.is_topic_message && {message_thread_id: msg.message_thread_id}), disable_web_page_preview: true, reply_markup: { inline_keyboard: [ @@ -157,25 +164,9 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b ] } }; - const optsThread = { - parse_mode: 'Markdown', - reply_to_message_id: msg.reply_to_message.message_id, - message_thread_id: msg.message_thread_id, - disable_web_page_preview: true, - reply_markup: { - inline_keyboard: [ - [ - { - text: langJson[settings.lang].socialConsensus.confirm + ' (1/3)', - callback_data: "2|"+String(msg.reply_to_message.from.id)+'|'+String(msg.reply_to_message.message_id)+'|'+String(msg.from.id) - } - ] - ] - } - }; - const msgLink = `https://t.me/c/${String(msg.chat.id).substring(4)}/${msg.chat.is_forum? `${msg.message_thread_id}/`:''}${msg.reply_to_message.message_id}`; - const reportRequestMsg: TelegramBot.Message = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].socialConsensus.consensus2} [${fromUsername}](tg://user?id=${reportedUserID}) ${langJson[settings.lang].socialConsensus.consensus3}(${rules}) ${langJson[settings.lang].socialConsensus.consensus4}(${msgLink}) ([${langJson[settings.lang].socialConsensus.consensus5}](${msgBackup}))?`, msg.chat.is_forum? optsThread: opts) - return val}catch{}}); + const msgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/'+`${msg.chat.is_forum? msg.is_topic_message? msg.message_thread_id: 1 : ''}/`+msg.reply_to_message.message_id; + const reportRequestMsg: TelegramBot.Message = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].socialConsensus.consensus2} [${fromUsername}](tg://user?id=${reportedUserID}) ${langJson[settings.lang].socialConsensus.consensus3}(${rules}) ${langJson[settings.lang].socialConsensus.consensus4}(${msgLink}) ([${langJson[settings.lang].socialConsensus.consensus5}](${msgBackup}))?`, opts) + return val}catch (e){}}); if (!reportRequestMsg) return myCache.set([msg.chat.id, msg.reply_to_message.message_id].toString(),`${msg.chat.is_forum? `${msg.message_thread_id}/${reportRequestMsg.message_id}`:''}${reportRequestMsg.message_id}`) ; @@ -200,11 +191,16 @@ const reportMsg = async (queue: any, settings: groupSettings, db: any, bot: any, myCache.set(msg.chat.id, inviteURL) } - const msgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + `/${msg.chat.is_forum? `${msg.message_thread_id}/`:''}${msg.reply_to_message.message_id}`; + const msgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/'+`${msg.chat.is_forum? msg.is_topic_message? msg.message_thread_id: 1 : ''}/`+msg.reply_to_message.message_id; const cachedEvidenceIndex = myCache.get("evidence"+msg.chat.id); const evidenceIndex = cachedEvidenceIndex? cachedEvidenceIndex+1:getRecordCount(db, 'telegram', String(msg.chat.id))+1 myCache.set("evidence"+msg.chat.id, evidenceIndex); + const chatobj = await queue.add(async () => {try{const val = await bot.getChat(msg.chat.id) + return val}catch{}}); + if (!chatobj) + return + const isPrivate: boolean = !chatobj.active_usernames; const {questionId, questionUrl: appealUrl} = await reportUser( batchedSend, @@ -219,11 +215,12 @@ const reportMsg = async (queue: any, settings: groupSettings, db: any, bot: any, rules, msgLink, msgBackup, - reportedBy); + reportedBy, + isPrivate); addReport(db, questionId, 'telegram', String(msg.chat.id), reportedUserID, fromUsername , (msg.chat.is_forum? `${msg.message_thread_id}/`:'')+String(msg.reply_to_message.message_id), msg.reply_to_message.date,evidenceIndex, msgBackup); - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `[${fromUsername}](tg://user?id=${reportedUserID})'s conduct due to this [message](${msgLink}) ([backup](${msgBackup})) is reported for breaking the [rules](${rules}).\n\nDid *${fromUsername}* break the rules? The [question](${appealUrl}) can be answered with a minimum bond of 5 DAI. Need assistance answering the question? [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpgnosis) me for help : )\n\nTo save a record, reply to messages you want saved with \`/evidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `[${fromUsername}](tg://user?id=${reportedUserID})'s conduct due to this [message](${msgLink}) ([backup](${msgBackup})) is reported for breaking the [rules](${rules}).\n\nDid *${fromUsername}* break the rules? The [question](${appealUrl}) can be answered with a minimum bond of 5 DAI. Need assistance answering the question? [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpgnosis) me for help : )\n\nTo save a record, reply to messages you want saved with \`/evidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: settings.thread_id_notifications , parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); return questionId; } catch (e) { console.log(e); diff --git a/lib/telegram/commands/setRules.ts b/lib/telegram/commands/setRules.ts index 9c3d471..ed8bce4 100644 --- a/lib/telegram/commands/setRules.ts +++ b/lib/telegram/commands/setRules.ts @@ -39,7 +39,9 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, return val}catch{}}); if(!msgRules) return - queue.add(async () => {try{await bot.pinChatMessage(msg.chat.id, msgRules.message_id, {message_thread_id: settings.thread_id_rules})}catch{}}) + await queue.add(async () => {try{await bot.reopenForumTopic(msg.chat.id, msgRules.message_id)}catch{}}) + await queue.add(async () => {try{await bot.pinChatMessage(msg.chat.id, msgRules.message_id, {message_thread_id: settings.thread_id_rules})}catch{}}) + await queue.add(async () => {try{await bot.closeForumTopic(msg.chat.id, settings.thread_id_rules)}catch{}}) } queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[settings.lang].rulesUpdated, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules}: {})}catch{}}); } else { diff --git a/lib/telegram/commands/start.ts b/lib/telegram/commands/start.ts index 2e25c72..0fad356 100644 --- a/lib/telegram/commands/start.ts +++ b/lib/telegram/commands/start.ts @@ -110,11 +110,12 @@ Join my news channel @KlerosModerateNews to get information on all the latest up console.log(msg.chat.id) //setTitle(db, 'telegram', String(msg.chat.id), msg.chat.title) setRules(db, 'telegram', String(msg.chat.id), langJson[settings.lang].defaultRules, Math.floor(Date.now()/1000)); - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `Hi! My community moderation tools are at your service. [DM](https://t.me/${process.env.BOT_USERNAME}?start=help) me to find out more about how to use me to my full potential : ) + const msg_start = `Hi! My community moderation tools are at your service. [DM](https://t.me/${process.env.BOT_USERNAME}?start=help) me to find out more about how to use me to my full potential : ) -- Use /setrules to change the default [rules](${langJson[settings.lang].defaultRules}). -- User reports are made by replying to a message with /report -- Penalties progress from 1 day to 1 week, and 1 year bans for each violation.`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id, disable_web_page_preview: true}: {parse_mode: "Markdown", disable_web_page_preview: true})}catch{}}) + - Use /setrules to change the default [rules](${langJson[settings.lang].defaultRules}). + - User reports are made by replying to a message with /report + - Penalties progress from 1 day to 1 week, and 1 year bans for each violation.`; + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, msg_start, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id, disable_web_page_preview: true}: {parse_mode: "Markdown", disable_web_page_preview: true})}catch{}}) return; } catch (e){ try{ @@ -131,13 +132,15 @@ Join my news channel @KlerosModerateNews to get information on all the latest up const topicMode = async (queue: any, db:any, bot: any, settings: groupSettings, chat: TelegramBot.Chat): Promise<[string,string]> => { // tg bugging, won't display icon_color if set - const topicRules = await queue.add(async () => {try{const val = await bot.createForumTopic(chat.id, 'Rules', {icon_custom_emoji_id: '4929691942553387009'})}catch{}}); - const topicModeration = await queue.add(async () => {try{const val = await bot.createForumTopic(chat.id, 'Moderation Notifications', {icon_custom_emoji_id: '4929336692923432961'})}catch{}}); + const topicRules = await queue.add(async () => {try{const val = await bot.createForumTopic(chat.id, 'Rules', {icon_custom_emoji_id: '5357193964787081133'}) + return val}catch(e){console.log(e)}}); + const topicModeration = await queue.add(async () => {try{const val = await bot.createForumTopic(chat.id, 'Moderation Notifications', {icon_custom_emoji_id: '5417915203100613993'}) + return val}catch{}}); if(!topicRules || !topicModeration) return - queue.add(async () => {try{await bot.sendMessage(chat.id, `Please follow the community [rules](${settings.rules}). Misbehavior can be reported with /report.`, {parse_mode: "Markdown", message_thread_id: topicRules.message_thread_id})}catch{}}); + await queue.add(async () => {try{await bot.sendMessage(chat.id, `This community is moderated according to these [rules](${settings.rules}).\n\nMisconduct can be reported with \`/report\`.\n\nIf confirmed, penalties escalate from 1 day to 1 week and finally 1 year bans.`, {parse_mode: "Markdown", message_thread_id: topicRules.message_thread_id})}catch{}}); //bot.sendMessage(chat_id, `${langJson[settings.lang].greeting2}(${settings.rules}). ${langJson[settings.lang].greeting3}`, {parse_mode: "Markdown", message_thread_id: topicRules.message_thread_id}); - queue.add(async () => {try{await bot.sendMessage(chat.id, `${langJson[settings.lang].greeting1}[Kleros Moderate](https://kleros.io/moderate/).`, {parse_mode: "Markdown", message_thread_id: topicModeration.message_thread_id})}catch{}}); + await queue.add(async () => {try{await bot.sendMessage(chat.id, `${langJson[settings.lang].greeting1}[Kleros Moderate](https://kleros.io/moderate/).`, {parse_mode: "Markdown", message_thread_id: topicModeration.message_thread_id})}catch{}}); queue.add(async () => {try{await bot.closeForumTopic(chat.id, topicRules.message_thread_id)}catch{}}) setThreadID(db,'telegram',String(chat.id),String(topicRules.message_thread_id), String(topicModeration.message_thread_id)) return [topicRules.message_thread_id, topicModeration.message_thread_id] diff --git a/lib/telegram/commands/toggleWelcome.ts b/lib/telegram/commands/toggleWelcome.ts index b8dadd0..1a07e75 100644 --- a/lib/telegram/commands/toggleWelcome.ts +++ b/lib/telegram/commands/toggleWelcome.ts @@ -25,7 +25,7 @@ const createWelcomeThread = async (queue:any, db: any, settings: groupSettings, return val}catch{}}); if(!topicWelcome) return - const msg1: TelegramBot.Message = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].greeting1}[Kleros Moderate](https://kleros.io/moderate/).\n\nPlease treat this group with the same respect you would a public park. We, too, are a shared community resource — a place to share..`, {parse_mode: "Markdown", message_thread_id: topicWelcome.message_thread_id}) + const msg1: TelegramBot.Message = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].greeting1}[Kleros Moderate](https://kleros.io/moderate/).\n\nPlease treat this group with the same respect you would a public park. We, too, are a shared community resource — a place to share.`, {parse_mode: "Markdown", message_thread_id: topicWelcome.message_thread_id}) return val}catch{}}); if(!msg1) return diff --git a/lib/telegram/index.ts b/lib/telegram/index.ts index 0833ed7..a6a6bd9 100644 --- a/lib/telegram/index.ts +++ b/lib/telegram/index.ts @@ -31,7 +31,7 @@ import { calcPenalty } from "../cron"; const Web3 = require('web3') const {default: PQueue} = require('p-queue'); const queue = new PQueue({intervalCap: 20, interval: 1000,carryoverConcurrencyCount: true}); -const _batchedSend = require('web3-batched-send') +const _batchedSend = require('../batched-send') const web3 = new Web3(process.env.WEB3_PROVIDER_URL) const batchedSend = _batchedSend( web3, @@ -46,6 +46,7 @@ const batchedSend = _batchedSend( greeting_mode: false, captcha: false, admin_reportable: false, + privacy_mode: true, thread_id_rules: '', thread_id_welcome: '', thread_id_notifications: '', @@ -396,6 +397,7 @@ const validate = (chat: any, language_code?: string): groupSettings=> { greeting_mode: groupSettings?.greeting_mode ?? defaultSettings.greeting_mode, admin_reportable: groupSettings?.admin_reportable ?? defaultSettings.admin_reportable, captcha: groupSettings?.captcha ?? defaultSettings.captcha, + privacy_mode: groupSettings?.privacy_mode ?? defaultSettings.privacy_mode, thread_id_rules: groupSettings?.thread_id_rules ?? defaultSettings.thread_id_rules, thread_id_welcome: groupSettings?.thread_id_welcome ?? defaultSettings.thread_id_rules, thread_id_notifications: groupSettings?.thread_id_notifications ?? defaultSettings.thread_id_notifications, @@ -412,6 +414,8 @@ const checkMigration = async (groupSettings: groupSettings, chat: any): Promise< if (chat.is_forum && !groupSettings.thread_id_notifications){ // turn topics on try{ const threads = await start.topicMode(queue, db, bot, groupSettings, chat); + if(!threads) + return; queue.add(async () => {try{await bot.sendMessage(chat.id, "Started topic mode", {messsage_thread_id: groupSettings.thread_id_notifications})}catch{}}) groupSettings.thread_id_rules = threads[0] groupSettings.thread_id_notifications = threads[1] diff --git a/package.json b/package.json index d155ac0..10f89a1 100644 --- a/package.json +++ b/package.json @@ -18,13 +18,14 @@ "markdown-escape": "^1.1.0", "node-cache": "^5.1.2", "node-fetch": "2", - "node-telegram-bot-api": "^0.60.0", + "node-telegram-bot-api": "^0.61.0", + "function-batch": "^1.1.2", "p-queue": "^6.6.2", "pm2": "^5.2.0", "sqlite": "^4.0.23", "sqlite3": "^5.0.2", - "web3": "^1.8.0", - "web3-batched-send": "^1.0.3" + "web3": "^1.8.1", + "urbit-ob": "^5.0.1" }, "devDependencies": { "@typechain/ethers-v5": "^8.0.5", From 98ed533eaa6aebe9ca740b3e5404f7e6ed743df4 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Tue, 10 Jan 2023 01:27:30 +0100 Subject: [PATCH 020/111] feat(txn-batching): msg sender specific --- lib/batched-send.js | 111 ++++++++++++++++++++++++++ lib/create-db.ts | 1 + lib/telegram/commands/addEvidence.ts | 115 ++++++++++++++++++++------- 3 files changed, 197 insertions(+), 30 deletions(-) create mode 100644 lib/batched-send.js diff --git a/lib/batched-send.js b/lib/batched-send.js new file mode 100644 index 0000000..41db464 --- /dev/null +++ b/lib/batched-send.js @@ -0,0 +1,111 @@ +const functionBatch = require('function-batch') + +// ABI for transaction batcher contract. +const ABI = [ + { + constant: false, + inputs: [ + { name: 'targets', type: 'address[]' }, + { name: 'values', type: 'uint256[]' }, + { name: 'datas', type: 'bytes[]' } + ], + name: 'batchSend', + outputs: [], + payable: true, + stateMutability: 'payable', + type: 'function' + } +] + +module.exports = ( + web3, + transactionBatcherContractAddress, + privateKey, + wait // The batch time window. +) => { + // Instantiate the transaction batcher contract. + const transactionBatcher = new web3.eth.Contract( + ABI, + transactionBatcherContractAddress + ) + + // Keep track of batches in the mempool. + let pendingBatches = [] + + // Calls to this function will be debounced into one call with all of the used arguments concatenated into an array. + const batchedSend = functionBatch(async transactions => { + // Keep track of the index of the new batch, if any, so we can reference it in the confirmation handler below. + const batchIndex = + transactions.length > 0 + ? pendingBatches.push(transactions) - 1 + : pendingBatches.length + + // Remove all transactions that would now fail, from pending batches. + const fromAddress = web3.eth.accounts.privateKeyToAccount(privateKey).address + await Promise.all( + pendingBatches.map(p => + Promise.all( + p.map(t => + t + .method(...(t.args ? t.args : [])) + .estimateGas({ from: fromAddress, value: t.value || 0 }) + .then( + gas => ({ ...t, args: t.args || [], gas, value: t.value || 0 }), + _ => undefined + ) + ) + ).then(p => p.filter(t => t)) + ) + ).then(_pendingBatches => (pendingBatches = _pendingBatches)) + // Build data for the batch transaction using all the transactions in the new batch and all the transactions in previous pending batches. + // We do this because if we have pending batches by the time a new batch arrives, it means that their gas prices were too low, so sending a new batch transaction with the same nonce + // that includes the contents of the new batch and previous pending batches remediates this. If for some reason, the latest batch transaction is not the one that finally gets mined, + // we can just slice off the leading part of `pendingBatches` up to the batch whose transaction got mined and send a new batch transaction with all the transactions in the batches that remain. + const batch = [].concat(...pendingBatches).reduce( + (acc, t) => { + acc.datas.push(t.method(...t.args).encodeABI()) + acc.targets.push(t.to) + acc.totalGas += t.gas + acc.totalValue += t.value + acc.values.push(t.value) + return acc + }, + { datas: [], targets: [], totalGas: 0, totalValue: 0, values: [] } + ) + + // Send it if it has at least one item. + if (batch.targets.length > 0) { + const batchSend = transactionBatcher.methods.batchSend( + batch.targets, + batch.values, + batch.datas + ) + + web3.eth + .sendSignedTransaction( + (await web3.eth.accounts.signTransaction( + { + data: batchSend.encodeABI(), + gas: + (await batchSend.estimateGas({ from: fromAddress, value: batch.totalValue })) + + batch.totalGas, + to: transactionBatcher.options.address, + value: batch.totalValue + }, + privateKey + )).rawTransaction + ) + .on('receipt', receipt => { + console.info('Batch receipt: ', receipt) + // Remove all batches whose transactions were mined by using the `batchIndex` we have a closure over. + pendingBatches = pendingBatches.slice(batchIndex + 1) + if (pendingBatches.length > 0) batchedSend([]) // If some batches remain, send a new batch transaction with all of their transactions. + }) + .on('error', err => { + console.error('Batch error: ', err) + // We ignore errors, because lost transactions will just get sent in a future batch. + }) + } + }, wait) + return batchedSend +} diff --git a/lib/create-db.ts b/lib/create-db.ts index aec6e61..a9e4a08 100644 --- a/lib/create-db.ts +++ b/lib/create-db.ts @@ -27,6 +27,7 @@ const Database = require('better-sqlite3'); greeting_mode BIT, admins_reportable BIT, captcha BIT, + privacy_mode BIT, lang TEXT, rules TEXT, PRIMARY KEY (platform, group_id))` diff --git a/lib/telegram/commands/addEvidence.ts b/lib/telegram/commands/addEvidence.ts index 00b608c..7a2f3df 100644 --- a/lib/telegram/commands/addEvidence.ts +++ b/lib/telegram/commands/addEvidence.ts @@ -10,6 +10,8 @@ import langJson from "../assets/lang.json"; const _contract = require('../../abi/Realitio_v2_1_ArbitratorWithAppeals.json') const Web3 = require('web3') const web3 = new Web3(process.env.WEB3_PROVIDER_URL) +const ob = require('urbit-ob') + const contract = new web3.eth.Contract( _contract, process.env.REALITIO_ARBITRATOR @@ -24,14 +26,17 @@ myCache.on("expired",function(key,value){ }); const processCommand = async (queue: any, bot: any, settings: groupSettings, msg: any, questionId: number|string, batchedSend: any ): Promise => { - if (!myBot) - myBot = bot - if (!myQueue) - myQueue = queue - const evidencePath = await upload(queue, bot, settings.lang, msg); - const evidenceJsonPath = await uploadEvidenceJson(settings.lang, msg, evidencePath); + const chatobj = await queue.add(async () => {try{const val = await bot.getChat(msg.chat.id) + return val}catch{}}); + if (!chatobj) + return + const isPrivate = !chatobj.active_usernames; + const evidencePath = await upload(queue, bot, settings.lang, msg,isPrivate); + const evidenceJsonPath = await uploadEvidenceJson(settings.lang, msg, evidencePath,isPrivate); try{ - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].addevidence.submitted}(https://ipfs.kleros.io${evidencePath}).`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"})}catch{}}); + queue.add(async () => {try{ + const resp = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].addevidence.submitted}(https://ipfs.kleros.io${evidencePath}).`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}) + return resp.message_id}catch{}}); } catch(e){ console.log(e) } @@ -40,13 +45,14 @@ const processCommand = async (queue: any, bot: any, settings: groupSettings, msg return evidenceJsonPath; } -const upload = async (queue:any, bot: TelegramBot, lang: string, msg: TelegramBot.Message): Promise => { +const upload = async (queue:any, bot: TelegramBot, lang: string, msg: TelegramBot.Message, isPrivate: boolean): Promise => { + if (msg.reply_to_message.text){ - return await uploadTextEvidence(lang, msg); + return await uploadTextEvidence(lang, msg,isPrivate); } else if (msg.reply_to_message.location){ - return await uploadLocationEvidence(lang, msg); + return await uploadLocationEvidence(lang, msg,isPrivate); } else if (msg.reply_to_message.poll){ - return await uploadPollEvidence(lang, msg); + return await uploadPollEvidence(lang, msg,isPrivate); } else { var file: TelegramBot.File; if (msg.reply_to_message.sticker){ @@ -102,41 +108,81 @@ const uploadFileEvidence = async (filePath: string, fileName: string): Promise => { +const uploadLocationEvidence = async (lang: string, msg: TelegramBot.Message, isPrivate: boolean): Promise => { const enc = new TextEncoder(); - const author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' ID:'+msg.reply_to_message.from.id ; - const fileName = `${langJson[lang]["addevidence"].location}.txt`; - const chatHistory = `${langJson[lang].addevidence.Chat}: ${msg.chat.title} (${String(msg.chat.id)}) + var author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' ID:'+msg.reply_to_message.from.id ; + var chatmsg = `${msg.chat.title} (${langJson[lang].addevidence.Chat} ID: ${msg.chat.id})` + if(isPrivate){ + const hashedUserID = web3.utils.sha3(String(msg.from.id)+process.env.secret); + author = ob.patp(hashedUserID.substring(0,8)) + chatmsg = `Private Telegram Group` + } const fileName = `${langJson[lang]["addevidence"].location}.txt`; + var chatHistory = `${chatmsg} ${langJson[lang].addevidence.Author}: ${author} (${(new Date(msg.reply_to_message.date*1000)).toISOString()}) ${langJson[lang].addevidence.Message} (${langJson[lang].addevidence.location}): ${langJson[lang].addevidence.latitude} - ${msg.reply_to_message.location.latitude}, ${langJson[lang].addevidence.longitude} - ${msg.reply_to_message.location.longitude}`; +var textReason = '' +const match = msg.text.match(regexpFull); +if (match){ + var remainderMatch = match[1].split(' ') + remainderMatch.shift(); + const reason = remainderMatch.join(' ') + textReason = reason.length > 0? `Evidence Submitted with explanation: ${reason}` : '' +} + +chatHistory += `\n\n${textReason}`; const evidencePath = await ipfsPublish(`${fileName}`, enc.encode(chatHistory)); return evidencePath; } -const uploadPollEvidence = async (lang: string, msg: TelegramBot.Message): Promise => { +const uploadPollEvidence = async (lang: string, msg: TelegramBot.Message, isPrivate: boolean): Promise => { + var author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' ID:'+msg.reply_to_message.from.id ; + var chatmsg = `${msg.chat.title} (${langJson[lang].addevidence.Chat} ID: ${msg.chat.id})` + if(isPrivate){ + const hashedUserID = web3.utils.sha3(String(msg.from.id)+process.env.secret); + author = ob.patp(hashedUserID.substring(0,8)) + chatmsg = `Private Telegram Group` + } const enc = new TextEncoder(); - const author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' ID:'+msg.reply_to_message.from.id ; const fileName = `${langJson[lang].addevidence.Poll}.txt`; - var chatHistory = `${langJson[lang].addevidence.Chat}: ${msg.chat.title} (${String(msg.chat.id)}) + var chatHistory = `${chatmsg} -${langJson[lang].addevidence.Author}: ${author} (${(new Date(msg.reply_to_message.date*1000)).toISOString()}) +${langJson[lang].addevidence.Author}: ${author} (${(new Date(msg.reply_to_message.date*1000)).toUTCString()}) ${langJson[lang].addevidence.Message} (${langJson[lang].addevidence.Poll}): \n ${langJson[lang].addevidence.Question} - ${msg.reply_to_message.poll.question} \n`; msg.reply_to_message.poll.options.forEach(option => { - chatHistory += ` ${langJson[lang].addevidence.Option}:'+option.text+'\n`; + chatHistory += ` ${langJson[lang].addevidence.Option}:'+${option.text}+'\n`; }); + var textReason = '' + const match = msg.text.match(regexpFull); + if (match){ + var remainderMatch = match[1].split(' ') + remainderMatch.shift(); + const reason = remainderMatch.join(' ') + textReason = reason.length > 0? `Evidence Submitted with explanation: ${reason}` : '' + } + + chatHistory += `\n\n${textReason}`; + const evidencePath = await ipfsPublish(`${fileName}`, enc.encode(chatHistory)); return evidencePath; } -const uploadTextEvidence = async (lang: string, msg: TelegramBot.Message): Promise => { +const uploadTextEvidence = async (lang: string, msg: TelegramBot.Message, isPrivate: boolean): Promise => { + var author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' ID:'+msg.reply_to_message.from.id ; + var chatmsg = `${msg.chat.title} (${langJson[lang].addevidence.Chat} ID: ${msg.chat.id})` + if(isPrivate){ + const hashedUserID = web3.utils.sha3(String(msg.from.id)+process.env.secret); + author = ob.patp(hashedUserID.substring(0,8)) + chatmsg = `Private Telegram Group` + } + const enc = new TextEncoder(); const match = msg.text.match(regexpFull); var textReason = '' @@ -146,11 +192,10 @@ const uploadTextEvidence = async (lang: string, msg: TelegramBot.Message): Promi const reason = remainderMatch.join(' ') textReason = reason.length > 0? `Evidence Submitted with explanation: ${reason}` : '' } - const author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' ID:'+msg.reply_to_message.from.id ; const fileName = `${langJson[lang].addevidence.Message}.txt`; - const chatHistory = `${langJson[lang].addevidence.Chat}: ${msg.chat.title} (${String(msg.chat.id)}) + const chatHistory = `${chatmsg} -${langJson[lang].addevidence.Author}: ${author} (${(new Date(msg.reply_to_message.date*1000)).toISOString()}) +${langJson[lang].addevidence.Author}: ${author} (${(new Date(msg.reply_to_message.date*1000)).toUTCString()}) ${langJson[lang].addevidence.Message}: ${msg.reply_to_message.text} @@ -161,7 +206,14 @@ ${textReason}`; return evidencePath; } -const uploadEvidenceJson = async (lang: string, msg: TelegramBot.Message, evidenceItem: string): Promise => { +const uploadEvidenceJson = async (lang: string, msg: TelegramBot.Message, evidenceItem: string, isPrivate: boolean): Promise => { + var author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' ID:'+msg.reply_to_message.from.id ; + var chatmsg = `${msg.chat.title} (${langJson[lang].addevidence.Chat} ID: ${msg.chat.id})` + if(isPrivate){ + const hashedUserID = web3.utils.sha3(String(msg.from.id)+process.env.secret); + author = ob.patp(hashedUserID.substring(0,8)) + chatmsg = 'Private Telegram Group' + } const _name = `Kleros Moderator Bot: ${langJson[lang].addevidence.Chat} ${langJson[lang].addevidence.History}`; const match = msg.text.match(regexpFull); var remainderMatch = match[1].split(' ') @@ -169,15 +221,14 @@ const uploadEvidenceJson = async (lang: string, msg: TelegramBot.Message, eviden const reason = remainderMatch.join(' ') console.log(reason) const textReason = reason.length > 0? `Evidence Submitted with explanation: ${reason}` : '' - const author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' ID:'+msg.reply_to_message.from.id ; const enc = new TextEncoder(); if (!botAddress) botAddress = process.env.TRANSACTION_BATCHER_CONTRACT_ADDRESS - const _description = `${langJson[lang].addevidence.Desc1} ${botAddress}. + const _description = `${langJson[lang].addevidence.Desc1}. - ${langJson[lang].addevidence.Desc2}: ${msg.chat.title} (${langJson[lang].addevidence.Chat} Id: ${msg.chat.id}), + Chat: ${chatmsg} ${langJson[lang].addevidence.Author}: ${author} - ${langJson[lang].addevidence.Date}: (${(new Date(msg.reply_to_message.date*1000)).toISOString()}). + ${langJson[lang].addevidence.Date}: (${(new Date(msg.reply_to_message.date*1000)).toUTCString()}). ${textReason}`; const evidence = { @@ -209,6 +260,10 @@ const regexpFull = /\/evidence (.+)/ const regexpFullReason = /\/evidence (.+) (.+)/ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botID: number, msg: any, matchh: string[], batchedSend: any) => { + if (!myBot) + myBot = bot + if (!myQueue) + myQueue = queue if (!msg.reply_to_message) { try{ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `/evidence ${langJson[settings.lang].errorReply}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) @@ -268,7 +323,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, return; } const remainderMatch = match[1].split(' ') - const evidenceID = getActiveEvidenceGroupId(db, 'telegram', String(msg.chat.id), Number(remainderMatch[0])); + const evidenceID = getActiveEvidenceGroupId(db, 'telegram', String(msg.chat.id), remainderMatch[0]); if (!evidenceID){ try{ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].addevidence.errorId, opts) From 7765a106db79253209bb84290a86bcd4107be8ab Mon Sep 17 00:00:00 2001 From: shotaro Date: Wed, 11 Jan 2023 12:06:07 +0100 Subject: [PATCH 021/111] Create Community Guidelines.md --- rules/Community Guidelines.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 rules/Community Guidelines.md diff --git a/rules/Community Guidelines.md b/rules/Community Guidelines.md new file mode 100644 index 0000000..cefc4ee --- /dev/null +++ b/rules/Community Guidelines.md @@ -0,0 +1,18 @@ +![image](https://user-images.githubusercontent.com/10378902/211790658-1fe49e14-a800-43c2-bcb4-c5ed97867064.png) + + +Conversations on social media platforms like telegram or discord are sometimes taken over by groups using toxic memes and negative language. Not only does this make many feel alienated from these spaces, but it is detrimental to the ability to have productive debates and collaborate as a community. + +This policy serves one main purpose: + +> *Committing to the principle of openness, and facilitating a free exchange of ideas in an environment of thoughtful discourse.* + +This community is committed to providing a friendly, safe and welcoming environment for all, regardless of gender, sexual orientation, disability, ethnicity, religion, or similar personal characteristic. +The following behaviors violate the code of conduct and will lead to progressive consequences (eg. escalating ban duration) from Kleros Moderated social media platforms: + +1. Threats of violence or violent language. +2. Sexually explicit material or language. +3. Sexist, racist, homophobic, transphobic, ableist or otherwise discriminatory jokes and language. +4. Scamming, spamming. +5. Impersonating another person by copying their avatar, posting content under their email address, intentionally using a deceptively similar username or otherwise posing as someone else. +Doxxing and invasion of privacy: posting other people’s personal information, such as phone numbers, private email addresses, physical addresses, credit card numbers, Social Security/National Identity numbers, or passwords. Depending on the context, such as in the case of intimidation or harassment, other information, such as photos or videos that were taken or distributed without the subject’s consent, may be considered to be an invasion of privacy, especially when such material presents a safety risk to the subject. From 9730390c3d830ae51595cd9dfd2c57807eb5930e Mon Sep 17 00:00:00 2001 From: shotaro Date: Sun, 15 Jan 2023 22:32:58 +0100 Subject: [PATCH 022/111] Create Normas comunitarias.md --- rules/Normas comunitarias.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 rules/Normas comunitarias.md diff --git a/rules/Normas comunitarias.md b/rules/Normas comunitarias.md new file mode 100644 index 0000000..6f215bc --- /dev/null +++ b/rules/Normas comunitarias.md @@ -0,0 +1,17 @@ +![image](https://user-images.githubusercontent.com/10378902/212568319-2f1edf7b-9e49-404e-a1b0-cdaf09377172.png) + +Las conversaciones en plataformas de redes sociales como Telegram o Discord a veces se ven invadidas por grupos que utilizan memes tóxicos y lenguaje negativo. Esto no solo hace que muchos se sientan alienados de estos espacios, sino que va en detrimento de la capacidad de mantener debates productivos y colaborar como comunidad. + +Estas normas comunitarias tienen un objetivo principal: + +> *Comprometerse con el principio de apertura y facilitar el libre intercambio de ideas en un entorno de discurso reflexivo.* + +Esta comunidad se compromete a proporcionar un entorno agradable, seguro y acogedor para todos, independientemente de su sexo, orientación sexual, discapacidad, origen étnico, religión o características personales similares. +Los siguientes comportamientos violan el código de conducta y darán lugar a consecuencias progresivas (por ejemplo, aumento de la duración de la prohibición) de las plataformas de medios sociales de Kleros Moderated: + +1. Amenazas de violencia o lenguaje violento. +2. Material o lenguaje sexualmente explícito. +3. Bromas y lenguaje sexistas, racistas, homófobos, transfóbicos, capazistas o discriminatorios por cualquier otro motivo. +4. Estafa, spam. +5. Hacerse pasar por otra persona copiando su avatar, publicando contenidos con su dirección de correo electrónico, utilizando intencionadamente un nombre de usuario similar o haciéndose pasar por otra persona. +6. Doxxing e invasión de la privacidad: publicación de información personal de otras personas, como números de teléfono, direcciones privadas de correo electrónico, direcciones físicas, números de tarjetas de crédito, números de la Seguridad Social/NIE o contraseñas. Dependiendo del contexto, como en el caso de intimidación o acoso, otra información, como fotos o vídeos tomados o distribuidos sin el consentimiento del sujeto, puede considerarse una invasión de la privacidad, especialmente cuando dicho material presenta un riesgo para la seguridad del sujeto. From 0dbe53205ecc0e8ff095667fef41b0d1989b5557 Mon Sep 17 00:00:00 2001 From: shotaro Date: Sun, 15 Jan 2023 22:39:42 +0100 Subject: [PATCH 023/111] Update Community Guidelines.md --- rules/Community Guidelines.md | 1 + 1 file changed, 1 insertion(+) diff --git a/rules/Community Guidelines.md b/rules/Community Guidelines.md index cefc4ee..15f4196 100644 --- a/rules/Community Guidelines.md +++ b/rules/Community Guidelines.md @@ -16,3 +16,4 @@ The following behaviors violate the code of conduct and will lead to progressive 4. Scamming, spamming. 5. Impersonating another person by copying their avatar, posting content under their email address, intentionally using a deceptively similar username or otherwise posing as someone else. Doxxing and invasion of privacy: posting other people’s personal information, such as phone numbers, private email addresses, physical addresses, credit card numbers, Social Security/National Identity numbers, or passwords. Depending on the context, such as in the case of intimidation or harassment, other information, such as photos or videos that were taken or distributed without the subject’s consent, may be considered to be an invasion of privacy, especially when such material presents a safety risk to the subject. +6. Doxxing and invasion of privacy: posting other people’s personal information, such as phone numbers, private email addresses, physical addresses, credit card numbers, Social Security/National Identity numbers, or passwords. Depending on the context, such as in the case of intimidation or harassment, other information, such as photos or videos that were taken or distributed without the subject’s consent, may be considered to be an invasion of privacy, especially when such material presents a safety risk to the subject. From 38a037ec498f7639607e601f1ed6880a03b94619 Mon Sep 17 00:00:00 2001 From: shotaro Date: Sun, 15 Jan 2023 22:41:53 +0100 Subject: [PATCH 024/111] Add files via upload --- ...01tica de resolucio\314\201n de dudas .pdf" | Bin 0 -> 898618 bytes ...th Oracle - Question Resolution Policy .pdf | Bin 0 -> 890373 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 "rules/Kleros Moderate x Reality.eth Oracle - Poli\314\201tica de resolucio\314\201n de dudas .pdf" create mode 100644 rules/Kleros Moderate x Reality.eth Oracle - Question Resolution Policy .pdf diff --git "a/rules/Kleros Moderate x Reality.eth Oracle - Poli\314\201tica de resolucio\314\201n de dudas .pdf" "b/rules/Kleros Moderate x Reality.eth Oracle - Poli\314\201tica de resolucio\314\201n de dudas .pdf" new file mode 100644 index 0000000000000000000000000000000000000000..8fb38f66feb118b920be4687a2bf67242831168c GIT binary patch literal 898618 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%0AO69rOwp2=^+VyJA!^B z-FTD?%QcEJP6|&;3$}dbDQ?U!y=5WGm%(%ABHYl3;{h=0y`2dKf5zT$!LTz;lj< zL3c+JPME|y0d&cjrj>2HhGsBfu~q_~V(1uU45-`RorGkn7Nr2I|%FMN; zo~d86+N*@&`|L(G3EK@X)8`1=OUNNK)o^rK1fKJ}FZ@Sz!KnEQLl{uROF{_<(Zqp=Li|C|edX7JggA77@ z@KG^VJ~CeP(gGw3i@npf`sE?K_pn^gy2k6ceoSMeaGOFHiIN>gMi-+Uj^+ z%CI=`K2Eg$CiOJ#zh8?aUNiSDsI@(MV(;=K%}fKd6Yf#w74dR5CY!wyG6YW0_5xMNxVn?^U;iZo_cH!SWN2yVB)b$HaN7aMad)Lh z&^H+O=EI_ToA!TSQSSu4@{9Ihhl{yvB|z)O!NzVxr~KhF-M{?fLyK{?G7BYN61j>g za_CUI@Jk&1zrV90?EITT4lIS0?w|j^{N&F9#v#mL8qfO7X`woo0iL7;QWQc;8Gh=h z`(oy$R}m)kVodOSqJli+FO_{mQjaKwU8G`%A@$of!xiXJXybZH70p(@m;H;4gjm3L zuXh@!U5m!q?eI8+EVKeQSNqj~CfY>Jm0{P6gdI<)M?uXBP%sAKiwJ)F+xaFojUKSf zCntvoAP1Y{3%YvboN7Rr0mM{9>qb(aZGmV}6S7iVhVnD+VRM&+Kl%qHC%XCerwe&;)8f$DNt#9G(81|n_}8UhS~FXR2LFI`BG~`l z4>qXpctNnm(xW{s>@z(=U^=<)` z{G3;e#4R~brY_yoXq1G8LTRIutaZ0Hp~F>Q5w{Q`3>!;g=%q~#wlIHvNY=-W1rgw9 zSnh1~tsVBSs)m?YB7vDeflFdB_JUnN0v;A_hNS8)M8RmX!bn7)`7C1C`8N3w+ zg5B&iN4EjyzSoTZv4^hEnda$KFDPq&4{H-E&D?I6eIW1|kGkno&~tD5T4tB5-!%$l z@Vlf!5fgyb4lU#b5Tmu7u9405(~37+*xU!x3m_o$0ht~GYBm5UCYQMrCA`nC#Z892 z>UPHraVR&+ov9z|c`tIjM_xXlN7Fpki&eyMw{@X=OCBBAZpO}G;Xe6vJ(!10isi&e zp%L+c?+OB&R~JVw58cvVl*Yat)&5xvMbR!ZXntLb9$d%^^)9RGnE9(~Dt}{THQtfCD;!fRGc`et#PbD)!AVS8{}qF4WikH=OsI{bih3#H#~@}DrkKsnaAC`je1K;;s-sf-RnuZ$-+K(9z=;hc zu0A%wPMKR#*<9&vY5;-{qDrlJ|C#8s)8B>(pb8sHzw3?8h0%>(k~hU{u2-7oh~z_? zmxs8hN5$5p-;W3BpYKQ2zq}(3TZrULJ4BPP)Kt3o`D!1E7NEHML&FLSUfL9!PJy$o zm%&mcyMjC>Zkor&uGBw$uY$(LE{iRW|6bClT*Au&K8k1&Nbrcw7vAqN2Ly}hxnwg! z$C6y~d!uM>qN6bBd^BnJLmzYTPH{6h!vKNMUsS9z9L%X*vz%N{*5681=99~tQ%TUi zcYf&izSazzl-2M+;xHBjQnYx+IO@(^Y2Lm}jq~UZ+8iLoHXL~41{Drsc0gOHq5Ivu zzt3gMUlvhmzi#kRnI9Ctp1hYr0+%5~f_^*xTgZeEA)N=%N?g@?@uPZezAq4B-;^lN zkbL$#Omlh`uI8dP7xBkr{^5V8o7NjE(mTsyKpL$@%~q9F z!Qq?3KD5Kk;&7sFj@%=46TP3?ni9qIrM4JgwnWA8f~b-!-qUjg6vi4l$r~C2A|j3i z+>BOPKqar{_||}AL@*Z#1RKbycRHM4s(|w@N8mHGwA0xWbfIaFIeE`q#vetHJw#`!Y9*W0hw z`c2L(G-l>autF_+v>F0Glf@k5y$Y9IpQCQ+-fb2L^Xm$Q>V&#w#YY3OG?T5+dosb6j>+S)Ttxz<}uECYomLg-L zotoUU+JS#;$UJ>br9^Q00~VSHB^W29y^ z9e_+Xhun4@8k@g1Whv?bWW#^S7XzxiChG931>w%LF0=pK_1L2KV}e2?Hv6_UV5zpc zx_K`X`gW&<{YcmoNS|qg~~N#jl&M;^x7W-xbJ=$3AxjSKMOG z16{jfE10%*~cD+CGV5@%G1;B zC6|$aa_%UOANy zEA}V#hop0fJSZZ8p8HXg$Npea_3mGO-|u3obTLDrXwL>kRLg-*!EdZBa3+$3PopJ`R`^D5eYDzs^u(Y^Squ8XlbmSia0FU7i zbm|V-5(2MAMMbx3l2eKhpX?pduduVXC-rvQ$*Ta-6Ud+)MZ_Q4LC#PPqnl!==6Z0Y z!||4CZ5Ljw_ISnl9{fMd@eI@>e@(3=0wdMY1!$IIHZs0NqrX zSGOD`H`g*KOb@;O?vvT_VqCqpa?#fMU5iN22@}un>;2$~;G;qbQIM3D?7rt7f!Vi- zpX6RflQU^ayghrys7%CH3Z}NZ0qYbRijipoo(Cv=mR8fc?LU+7h5G5UW3E5esd2V| zVFNv$y6M6Rz2N9*X!%k}|0v073O*3H0!$c>jqCY@d3ZydaqbOg^Bc{Dpr^#f>-bzNv&`AZS4Y`3CSD4RH)Z-kv^A$G977uub_!Exy^Z}Bu(IZ*$ z#ZU!o6%&wjJYIBtO3Js?Zbr*r-_Trt3Uq=8gsKrb+SrDN?<3)_SAQ&5eQyPy1bEro z3tAj5Z$Rimk9J@0>GhsSq!sw4PM7m zZhnPz0lATFuy!Bh+I_B@eqHI~(-9p#M5J8eq5&C|Gh8(ei;cU&%IO_V>sYA+D z_mI00?o~8K0{Y@2NBazy+mqHP;kNe~KAx}*vC?lAT+hxb8-3sJMLg`>9C8aad0yt^ z&7igQGYU4}jkZ2o@&96DsK?i7750Jobi8-KofW%2=KDVIFIRQa`e;k23!P|tp-Lz- zc-#nMF;2IV6#2p-)L}PUx{5@ns4yTZa=tEIuj=ysJ={*6(?C+eB`}L`hegin*b8y zjJq!(L#!J#O6g+K()tYF2jt~VN!8h!_ZG^!`052 zo?cO;dUxl`^BZ)2pCd|}W}j;~5Jhq7H^^A~-334{UyoGhz8C{>aQsb~7zG2I`-a~d zYiJTY8p-{}kfTL!-dAu0zP=#G*U^@s23!jVrgNDAMxV3!E?_cbkVG$C@){O?DE)HN zH6lH!5Ifq=>)ko}h&`xo)BvK|Kfodk-nv_UL{AlXfNskVc72CSUALaf-Ok!g)ngvzH#JfDeb|dgb=Df_Pnqj zoq#;nJI$@?#^;d4J0>~LQ6Vk&P$nx+bv-G7MF@V@5WZ`#Ol@IwYk)H_v}T8 z_t(93BuJ9V4EBn{j#i2Fe2oRNM@La#JGzyUbtfjOzKV~Rlw=3rOF;W_2G^XxDD2LV zT_*h&i)HG)@y8G}|2rrX!s5|rV}NlrHl)qWDlXqYaRbxpGTM{|AX?wmhRKh9k3cWg zJ=`hukoqFOI+a&fd8`=~MnBoeifAppJ@mQdUDx|A)6w*11mnnX*&xJI@7M93A?<_Y z1!>ZQ-<4VA31#|%?k{3m2K$HDAb&9(QwZ}lvZg7L2EIT*Kj58F0g`tS(8%7tE}{4? zd7sT3^9#S6P3D#Ici)s@Y5hJ-nK$2w?>NxTv8;1gZ8GKVzHUBk2L{spY%44caik@D zftD`PC}%7;xr}v8;2_wj;L3kKm$lS*S-O{>En5X=d4-nlg-jF$+s+nTf83jcEaZ)m z2qiDh3fF}+j>{~KPrPlkcQ~b|FV|@S_uNL2=G3nbZNW~3)CuR-$l zxL~u~?Uk+;Wxn8(V;kI84Fc1qfqo6=6Y~;d>Dr&MA z7W`FaX_CX}FE9g0s-W|GJi`x?G=PhKXZ+4z47$BoqS%m{Yj1Z-pu1T8sXlLUL^yeL znzWs}2iRKKwmM^jf&fgszrKW|;AMB$OyE{llU}IOdf7P1o5{&)cv&0RJFb-|04Drt zxajCxZZmxE_RJNgBxw}&>Ud8V`UPUZ_Z|DiT1x=P0Wc$h;h}|9GNgmQIjU^+3=Oi> zd`s5NC`9!!5B}{(B3;;8_0%9et!ZxM%ABykX2aLDalrn{7afpa0yeq<+(RhMEquqN zk1;>PQ6rdwX(#Vp4`4vUhOcz_nM4pYKplKCb5OnCvx{!1uXFc(KCTCBSNDi}@RDvV zDx-GU{N1Fous`@P7UX?X4r<4FX>>Y7E8w#+F{2}BM@K1Hq2a;ILqe1$3g9^8wtK!C zT?R~)^X2>IZ*<}fhyKO}s=Q%~9Zt)`aATO&!g@|0MNaH^z-INgY{!K?$&|4U62NkK)w)$Lo{OEV3OW(3Wjcn zL_4-56bM>CxxJkvdZr#Yq8ma-9^b&C-*N@rm4G6`ybBOX><8nd^D3Hy)2BI-rT@G?Jk73Wu|8cTOi_Ptk(cl|GW>!6p7nmpcZgLI zJ#w_t`DUo_Bsl(1k7q|~M3%um4vvQBQF2@3_5-k~0vdhAhwKt*i0H^U^~Smfdk1pz zDv!-2-MwU?ft{xBJ1qqLo+ej(L&PXHr}5uu!mUEP${mgNu_4SKlBg`V{4RmPoAy75 zh!~lQRr*xytjKkme5O%t$RAAZxHRI+sKB>~0hpwG&H~h|u{3Og&QDW-(IV94$2M>D zgk>VoMRZS#%vPUNRv({j$MzHQhhnmSwEXT!sN3WdU09h5gOgZMn^~8x14#Ui{!dQ8 z+`aHrljusESQ=fn8l=kMiS1(7h?2R5U@z(!#sG5tW&Y3E#rdbzAyH&WjX^kAHki0^ z752L)fL4gZ93k>10dTBkp!R#0dtES?=i>DUnxm-a?g1}Jo4m6@Qt{P@u9vDlQ-Gei zv9x-(kJSJBK#C6kCgTKU?(VVh=clvv-Le%?cGK9~LG7q+DoZw=PpRg%AIbMT?)IQV z$eJ|2T>bjUd zOw9#$m6-T=EUA7QTa8U={67nnSTCnr>;Bshs1ooa#~}SI46!VBOO_e#G2FeRoUVN$ za%ZkuKuA(RVLDPy6LNWdd5*K?;%U0iZ1~yV5TRH1`fzxv0{$)f5&FJ(#twXm(kYV# zN<{a*CA~X&JPpmp0?bvw=KyPZK8a6^g+RWNuYy*PSWnhCT)Yy&cJ<;z{TlXa2c(Jp zX5(hGT=NPM&}A(ZpsnJu`*y|(ZkqOEkcOp$QFH$6i6OA!5m5`pk8EW?l`d;)+rFW3 zSIQ7v9T(tdqb{t?f!`4zmb^s`b#_K?__}^U<9_;Ql}rQhX@CqR=Acf?M;#n1-2v*bE?6ZhC8tpBL`ksb37JM+t+<(Q+a7SH7NsYoGQThtimOfyIrE~>=Bl()*R0q zE2E*1Mko&iCyXZ5e+Yifpi$1t--hz20pi+RSk^^Ha07=4D+^#MuHK!LZGlNkiwP%-e}qXw6P~wq;Dn`-cn- zRke|rqC#mZgu%xD;eHpGEPc9C?SI@f^4XK)wb-#OAX{&)DR?+s*!|_5nXA!PNfX`C zlDS`5IJQ6WCB-X7O4HQXE-^yM@~jV2!<3Zd#^#$`xSLE~1G?gG9PpFVJ;Q)dJv{iA z#>`l_qP4>zpWDS%{i@PMLqS~t75)35Ht;sRl#iAVz0}iGk_(dL?HTGcd+k23Wh|C0 zz|n^N!$&O>_WZXU5DYdMecxV7Sn{!9CL!?FT=KU33^qoelF({6yn@qeCgQUh#`8Y!*fV<8!$Z50z=hWJDfld3a6-)LvKow{ve zDIA^jo-vK4N(H(#=Hd4KGJ>{ATLx1|J`ih=A8vh@$@k;(`^_XD@lb6Z)hooW;BX*u z^yY*gW{A&k1KSMc1_3#!;*b3EH;Ommz8}k~S~CT*pOcStob74aa*6F8fqeSV z_?qsyYF$?VkQy30n4JU7;qv+YnG#FeL4~%XD&VkMYdAto6dTcW0LamqTsRA=7!hj^}vv* zPvatS0!|k z2NL;Ka`Jm=eKommMUIcm+^3#gp81I1Qu zE=bk&j38qn6Q;L>Om-<>M>JM+#8!JNVMczALIDwa zEAtC?wW6fSX()2Jf}eJLhPZjwaSra|@Gw(Ae6!s9`r{?NFIvd{TKb=y&VxFcK$QzC z(;>QRrIrS|({Df;`fWDHd4N4eBNas4=dAjrpj!|b-O$o>4gkvW>a7}q`{Qw_y4q_+ zULCXC^%zLNYh$a3^CM8#9aIjW7_cPJ2w%(FGKo*Xl_MEzj3xuC@6I?rQBztFGve;cN_-^ss+*yM0eRe#6`HL8pprK$xMhR0j zRblBB`xP=Dl=(hMy*zTc*3znn@OPBrpvdC?^NGQP>Uyi4l`X!Z#jA`xpT5HCN1NLz zxr!*nSC;k-X`f5Px2f(+D*C#%7Wcm2=BjhbufE0}SeyQX=y~p0OGwm;$lGzLNR%rc@&Zo?;|_AWE=2#h||ZAkO`|2N^Xd5k1$B4rl)}{)ZSZLRa1rWiqyD+$0K8 ze7ZCyja+QoiG(Q^qx3-W;*+Ij^yO*xN)i^ov#(~OTZf1Ey3RpUTDt|kb0hZVgz)B- zFaTQ8@`+XDtn2YWkfKYo>X=DYsvc;A-qcy*Zq>zXVaXfOFFI$oZ5cs)9)YNo1=u*B$*{gY8Ufnze%uNjY&w|!r= zRJ)7mgXvXqR0=3c;PSEx8OmvPb#}hVQrW1zSYm^0Ynu1;P09m$Mf;ReFKNOSn?7`X?*}9@W)kBv?w|JS815Wdl#BlI7Nleo{LaxXWulX zu@;B!!Zq86=V7fRlm0DMgz5EIPQ|2${6Lzh7z51@k2>Gl`Ii0~SF#T;OixjC53le5 z(5{r#@xD1(ZFTpTHE&&(AF6we%bYd|T|7FuKjgAo_BXm)%gXV-IU*&}jZ4?Ox_FHF z*FXdGow^A2b3{((TGAq4h(xd4vsho<-HV}!PN2Bu;R25b%y&sii5_`haiE}j%1~EW z`7f3IH?kqj-g|vx=Rp@(EX{=Bf1UlqpN1pSWcMqz^69*d%|#8x-+zbz)0q)S%lF^M zcL8TgqW^I>|2l_!vj2$jzt7U5{y!Y@_p2*(KmLQaf3I+g{l8cW`25`+DSPj~X9up# z5336PcO8H~w4V0u|7W-95&peb1dgPZC&T`saE)Rgp^!E_yxfDURyj8b=@hryH*p|m zWv%D<%r!N=>kPI=S%&NWi?7u10p? z+|@5o;@9{!hldwW?OMsjp_S{h;#L3uu8ZIp#+|*#0jF%JhkatS`eCP;iDt(_95+>; ztKH|}$$8%J zJMWjDcjn&Fb_Uz*gMF&Jf`k4C%=f=}>$&OsX9ppDP)*N3_o<{Nx#VmDa2jIZOFCQ> zUm0Cz$gIT$2`H1YLTe+Dygp&nxnNia4l4_3IuB`@O=YG|bEY!mNcX=Re}5I7JB8l= zB4m|9Jr*Q%hZ9fX`?mQi5y}zCmUep*^2T2ss!5P)ZNUrpj3|1<-7k#-ESbJ%95 z?*;x6{mZ0YfP&uvy`WzF4ADV;F_YSi2fJ^91)&U*D~?pFon6`}lDbbS2v zWG<;az4ikpn~0@ekpOy2c$t2s^@8Y?eqN;B8n-&i-1sGW9s`56w!(+vvGuc<_m^|q zeFM#}`*?&VB%Kh$Qi5i&>2dD^qLnVj3HQzE6=N!Ut?JMup1pT^s8N_oE1`%LF`~McU9t9+=V^q4X+kIv|{_{7zHNjg=Q(-A1`0t9-{g%C9 z3`A337Nlm%0DoFJ&xso;#8D^XluFa-7+uZAu>9U6C@)5KNNsisga013Z<`8_(_9M- z3{z=(7~R;{5nFK53L; zIo)BZ01TWGfE(-R6{O_?`m($%^yn$Wbemc4C(}Y3AL5n#qW2|7kRNAIEw$Wqnqdc6 zj9nygd0@RmK*g0{2@A9V$q@j?c-FRB=azE1#BT;_TVdJ}z1Z0ulf-L$fi{+y4%}?a z_`!`?iP>B0is@O)NbVZlLIioIm+v_Rdm@krb>Wac;&n9Dg2Sg1`38EJE@w$>_VrlU z;=&VraNq!)qS6(b_cGFldGRrCUf5p|>PfUrgnrBK>e=oZKh#9ur^+dJ%YdI@baeTf zS738!Cz~@=^#{VsPV3b^179s|S{XagG|eQ`!U}0M$5wqP`vaMRG?d@Z0?xHC8D`js zK(NaQ?tND`!AQKWO;6nGV4oAcOOwwZoLVIL1l>qZ!q9&0x~MEoxC2c{-3$27%l6sL{B>Mvl@iI##@Yh zHKZB?asK=>-6}2_KYvz)(_+0y~BjU!dUD3JxW8J&c%GF^n z-?ED*cyV4<@*$Ic$BeIIse{_|5As#d?^>hguk>lD;&VPYQ>tJ|vx#|gP&{aS zkNknfNohSi7kBlO7bOF(^s4n}_%;bD57W#1d)rl+&d?7}Xh0+&)^$(It3HjD9}28TjmilMXu~6dG5hBd%NY35-w7>5JZ^ z9bqvcrFp0$XSW#|XL&YEX^>d@gBkf?w{Lfb?_OeJ-U}{%)UTTDjkH;r#IDo#9l%QY zMH3)MI>mL2_c93Za^)xInud39@io(bW~ON@D9m(l5ItV%m?OF;O__r{MU*aEm}_Bk zF!z^dgrL`*h!PUn^kAqP;U{bGu(vW&=OdllnTQ4^ZE-S0{s*X@ZZFc|w3Bj`U1Urp zSxj?JwGw_8B7xp?)hET(=&+k)6-7tI#Q(Yb=sRxbJ*FZj_Gx12{pJHVQ8Ysnfuek( z{v3Y#mwy5^m&Jk8odX$NgOxCkuV+S!9NUI4&NW$-`9W3pw|CHliWKYtx+W-)#iy;* zA9-}aJ6O_E>rUc#Fy)q|_E?e_bbZ%4*M16BHu#@j%mW=BT+U$@hoj3#g`VjCsf|dg z#fKTx-PsZLD(8>QGu^!ujTP2LL+7xE!4&H9`SbGrT2Nl1 zMAD33rF;}+3R}J6cVxBSev8U4&n_^z+`SjE;Q@X=}mXD{*5Kzl+74R5m-2u?%A*@;&s@1_<{x z9%gJH^>cT6N5frwIoDYB+C_VvamURHXWRyE3{2pdYtUw|bDzP`SwPV0Z;{C$+a8)W? z(hvsBC<3xe=s$*n26Z1|ky4}p34#@~neTp>1Bi7iCC^X+&PBYkIM3)xsI;4b=s|U{ zT1|ddVzIw>Y9-9kXnPMUNo|5HC_91UTC}bYt<(6zX18!XF6ddhIBc00?rMsg zqb}+dLLmLh%iviZOi9eH&tU$MP;8lo`$CoddNS9Q){SiBRtFMvmZWS?LrRtttEHKYKYip zdbj~u)y?RVwS7+^APZI7OlM+ZwbIO6^jQF#i7l4)r0hS4c~=hil9O#(&RC&Y^5G}x z7T{rvl3@CueVCTZH6>?NCHG|P3o)AI*o|A86tmg-d|D=y-&EN%pP%RnqX3yBihYrX z`14|Meb~N8M%Rq?6a`97mz@nu$>%f1+Z)2Q*$G^?mYQy?9>EH2`gUtVuq z&h)&u^R~W(MiWGwYu^lf&+f{A1+^pd`QZ+~Sfd;m^^Gk-4pqQ5AV{7}l06rsj%m3# zIM)5!>H{%#6kFfXHDpEb8_K=C@CGIrNIi}R$%Out6ZfX@H)J(PQ7zQJ!x*&r2EfI%x0Uc zz2(jF{#8sUw|)8p+NoTCO<}~ve@m-WNcccosW^SC&XEJBv+r$vQ%LVqT)3)!d5c5r zb_@WR*=n}ps>yDpBDPU_!{R-hv_RlIr#)FT!FG%E4_UAn03*h>`sNlCv-S$9n9dt( zWdeOlmfywg39!ST0!=1%+OA)s_W|wu1yNEv&w3<=2hEadXrb8fw+&k!&kI|*;^)Cq zNXtpZ2T;0IvMULC?Rf6XTN>{#UA*w$1mW1LNa>3k!h`~|ia&uT&WfPnpg(epS#ga~ z>TYqfPdM$z-pQuHY_l8J$e<=a%UvQ1DW(8NhJO|rR4*fh3$xk9c2uCbPXwC%T;=z+ zw5>&+Kg6Jo+q3%y(_@$D$Iuf`x!c0rc`CN2WL4IK7ykiCn|Yt!$J7hkr%1zpk|}kP zOy#PT*MEVa3Jc$hisrkm%!$n`NmQzTXfT@l8`#5dO=&MJ87|Z{{4Qjv z%p6tN2&&G37%X8%>l3BxYpC$!acWrZ!}M%-B*Y*CT8@c}t=CFJHpArHhs~Rx9pwiQ z^U`U@Fw&GkrCoEGkrMo2VP6W+OT%7BN#gdP{?K_!?szJjXB;<Y(4L>505 z6ePR&*)gJ28bOG{4t$-Wxy*?jtC>spxm)`U#DJ@Ll|~?`RKE2sWE84QZzIQKe~qB1 zLHm%p-3{6 zOXp0kj$hYCm8Jg;0uc=$98N3DWzN}%zdT&eK2iB5L&_935k`ngK<_1Y(8g|r&1|g@ zj|IEbASo$3<=04x8=;IeW-q#uA+NxkRrGwy79LtIWx`Y=>hs^11t}S(5E2fC#m+zc z%{EG2Iw_U4wm=dJFhx*LB)r;CL+Lt28;lC)AD`CMHU*<2e=RH?ms&Wc=A){*D;CgiA2f1_6jkP5ZUSQ)B6m6z2!tq>*(aI8$T@U{Dqv^2S{!@ce?N(#l& zd+Ay;m`IuZD1i{}EH=TjdP+^f{nq!TH2r$bn(;r<|E&DGuJACM3f|a6I3aMLje^H! z2MH~D$|k-Js^N|O=Cxq$+_B!y$bRHh*JD&;Fg9qPa0S+Ua4m>(hkMkJogpVYpG9hP z936|FZnzPMde<5R+Olfd(zqRvtst}X58wMF``GjLR1N zCGN|z_b%C#x((xk>Q-2-xp}TvX@PzGB7CB*s4VNQMOP46`n|m64{qwuc}Yp#VFTRY z>#)Lf_9@O9_U5J(imJ~pXG-*TM|%DZKz3Z%DWfEHxf+=J)k@*zd&|N>8M%*BcsFxX zZ{3Z7F#`Sbr^yeCnE&NPts5exEKnrd7m>@F_LN&D7+6p_WH)0M5O_fa2fxUs%qPJo zML*l*y*P7wZ&PG%CY^x5sFB_xcDmLn96X}(eG(CcOl&Sd6gAuGtSmXp<^oSD=mKvq z{xQ8Rw}{%mw_31u^+&dM5aoI`paXjL#iYl1>psjh-}kY3z+sl3ahL7c5bCRgy0CQi zg{R_F>z1zAI9bN^nJfwEq&+piB``adJ+xL{Tn@%?Sk?AXPhS)5BS zQ7c7sB109e0|-AuPw{^#k^aO}ZDCV-636OE(P8K6ntKJm&41f$NZ%Hj-*FWt!!uMy zY@bFaX$2oJg4n%TXuXW=xb$YtjvDHs?E#?I{SD5x9xA=)@nB;5(Om}lDYex0fFNe7 z(GE~%^LH3mVL!^UcTNLNYA-sS5%eAgw*S1ehO}lnx zXva+`X_DF2@pmN0?0~wPg2>FYTyAR74=7R%EDZkP-fN-kJL%kbu|FQ1h8_zV(~Lg} zS`}Po$gUe$)wLy8<47iY^8SNvgKM0qdS*t;as8qq;lr{6VB@^T zEp`60MH=PnPECi95e?lNzFT5`}Qt3PLT_qBLOYit#-}E|S>s ztfiQ=>LWgm1XzZ4>*~M*Wa0hgs1H>e=QXy}6JhC*vD>Jz)}U6CA^UY%HdLBvPENNs ze4Ipd_OxZEe2RE-HK+Xo17(=VcDCbpXK!|%WTGDs;{V`Fnu_1CGe>2PU_w!3{4r7p zlm_&0KLP81|7wt0N(gwx;4b2~fB%kzy-9!}e(25R|x^?t}uJ)Uq;- zMP-LXw5C%lev752e@Pmh#KsTF$Mp`P-q%yYoc)j9zjNFbCu7(z3R3Tz>qWiUz)I({?#bL{_JaZ>=FDio z_(z$h9Cr!7WdXcZ+PbnNLixTqEkdG%5ROT^eK7X2LSMn)FuPtKvww~Jp+V|qg{)p1fHTA=) zmtH-6!xZ5*{ls3!*46*fIKrJtqOHSDPyFE?Yxc7T%jSHL6Eibbe2jZV&H32iWV)Z% zw-H1HB%XKk{c-40aE}=o2mAQ*4Uv3)k2C!*%b(o}?)r0)DKdn;9(s_&ms*$?8;KF~ zm=TENfHCWCuQcAl6t|bJ5Y(pm3a5L+AL+{8R6@0!e+eyz?U2-qL&6vi8`6~hEve(Z zi>SKf=P^9dzk1rcb>i>O6Xo6T1_Qvd^)20q$PGqK$0;A!=84pqSZz(fQ}{m#UEJ?h zX)>gfW(d2Rou1^kzusJhkV+|K#Bg$}-Hws^-Duo==et;|j#d^T*$7w}fG8?X^SQ@b#Ds4#cFSG%)0gv6J$m|e3*|OcO7hTQk z-+69GW(->4`fV_h{tw&Qz^yY#Gr0ZDP7UOs{!i9hR|GohoBeIR6j3CC&(E{@?n2S1 z=uvhHY*p6mJrlWAqoXvnuE6b2@NifVLOl*!Z%?w#Gi`Rt9XQo{I>g&%(j*H1C;Po} z0tB+DT^b2a+>?Rk^Y5m36Fx}WMI7Yi_jywG>(gX^&m~1*U{#)ljwzPM#Q5FsJclB+ zBI*0G8WT;kVZGBnLJ3Ovy*@I*9ojY7<&PdOKjOd|g)O{fWuw=zL`}<@RTX zt#xr&<@Tq8eRN@!zO23cQGvpbn&1P!M?6EJRyT3Coz$aYow>*UV8yD)GMZ`E3%kSg zT>&Il3Dvz*9L_~k>Jx>3>x}+tH&4ik>DkSLIITNLv9pS!AxZ*6I1WLK2 zYID@F@~KtZ?z|X0mV~t9U~7=kIF}z(r|AWI{P?lPSbgm7pB<6PNs+?EpXWx$5O2>* zRWN1GX;u4gvcf-Oz6~daXD`E!Hn$3O{Gm!fpOx)f=_8>S<9Xekk6L!r4~ggFTU%kO z_Q0(x-3_VGKPQZeV~H?d;Jq4pjT+z!J>jE0)*zxO#vO1))RIuFa8L#}5Td4!9FTGlAzbrbYiL+?W&+7Vit*Crj z{pd@w&oGRb5s6Ti5XU@(0Uv(CMa$)`qi=m0^Hg3`lNKxD!IXAOTd*h^pVwgbOf`_N zquJ5gu(tWXHg*Qk%|rNh-}J|_*ls@9;|w%rDeuxki63*cG^V-2PyX9s)mN-)64whh z&VS-R4dwTE!XA0h6jC|f?V5Z72Bs_daM-P0zKSU#KxWm}^ItFx1}Nej{tpjr#%oLa zETOF*FS|SbSb^+>H*V#muyE7e)h!Bpr1VO|kQ%COYsM=@ok-@OFuNgB69y~dnBghJ zmwi>{_>kf~rl@-~B4^a`n*2Wz?=|LWc~GZ5EOn~;c<+u}^(*z&Q3jJp_5R_&x3nAE z_Mu{&s|bgQnnVv=;Cd1K7c+98YE;Q_pxRzK-m+XeX*AhgPLO$Q;*!;XH@2G+Kaq5w ztTLT%0_xY$RH!Mmwhff#teoonGdLp?JoI>Rp>eIAPI-Slb|GIjhwnjMD%&Yc(yOzz zeW(>KpX|M%#;Ja6M15xixxn%KhqV_Sqs-`<(!TrI3|jbD&yo(Ob`@i31kN#+MhsDe z?>r4>+dI+B>W=t8Td!sIx@?+n_6IHw&1*^d602K2v#bUwbW@n0UaynLE&tGN!rPC{ zBni1IF9hIxQCAMHLJ_)X5c4a`C1VV?uruc|#9GeJGJ3Yf@fHiVcr;8Xw{uHSMSIdU zfNT^#NGT!I>ZwN(>FbxFGQ+O45DMKgw8PK-wV|luOLkXBx4t!FD>XoKeL5y9l0me> z4=*x}(c!@U9|FEX0lde%_+vxwSio_lY1Gr?nw_q8KG zPi8&m9e3x~hC6QX+`N#|CHd+~7KdtYqSc?2l7z;xddoG95WXB8JRy3z3bS9BUe`id zUYDoj-X+Z5G%w(UMc8n&;SbzTC~dv4*#6wE8&N;np)o(krJ{ zlG{CL$PMrQV!_Iu)-)1L!Qs!2*iE=euv!hiT9hL=3&Z5bwroU2NVJnnqxBpcCH8M{efMEoOIZE%!HUdL zWj0bJ>%~^13Yf;p&Qh8}_4bvD*YYOozq2#9=It49?L91#`Ixj&QE9%_0{4X*L1}j8 zyjQ`2L8U`~vFV~>OO}dLR+6p1`_aXG6X}pemJv5SX7&L*sp1#2Ko8u!%!WUn7P~z| zRp~rQcVq$IE3^nYkR4A=%hPrNn}M#~^}$)@+YD184tKmi#m-#Trk6a3NmH9q$hV|> z$|$+fj`TBk17y28_yBLH4u2Vh3Z^QI25RY*%2V0fSi50@mUU6Se*{WQFcDGAgkHD> zoO!>W%RMN>1Ohobw_>;1k^FIbew>AuBh1oyc+b`^`pW?q znz~UOyd*2Xuv)(4b+QofsTpbo?@?x&gs}ASat|2apd%U4waq%^e}@OF;~n5s)u>#m zc@KYn!F6j8&M#_d75RB!gutU7ZUMu%!!@8ICkOixghLGR*Xne0jb2$(aeV z7S)A#zKMEar5~+bk#ql-`7@-}c=tV)o58&8Qh88FK)T;CmPHcJLEA(7`%{K{yyqe3 z{uhv@^fEZdR|I_Nn3l998K=AT>z_}ZO|P+CBQE4CiDSPBddB6k2ljL-yj=&8uS}vA z$Ey(g{b5DK((hPYNu_%LWhC+Gl%0vu5pOFCq6n%S#Pj-{qlt>q97@&v-kk9|?-r3U z*LO@jMTy4Br8POJ(46IKW1ez-!juzs)TEzYA85G~I-%E^O+xnN^YjkEz?>eSzjeKD z#Tt6eQ8CW_f(3UmS|NP5T5n`^v=mLa@(@Q}u&R6T&39TT`*bnP_*XcM=QS@hHfIVw z2Zs7vYp%1dizE?E^L_qikwM(O8--s%$e|0d7SVUBcR%k2EzVe!QjW3m`q_TZs-u@* z9<=Os?1}XXSlU%2=iOBHdN3JlG^dw&s5U7M%b$BcABe&Svs(pvQwrHNx7eWkMYz_K z7d4RrlZzYnCmJ_hKIy^-PsN)7le&3bSdtOE#bi#;tT5oJ#EasA_6E<5|NX>%{cg%F zNpU0MCdl1&FpGLVu=!AWzYC>IlC2Y$EDU;-3A*$up~c>FgYh}kM1gIYUW%`_8)#3s zzC>u#%WaVr?igPj4<>nH7R9pBbf9NUS6(-wxyQNBjkmz)2&0R1I)6KMrD~0u&}m2& zW5sd8dY-Iyi8bY4JBa^ddTs8}yl39Vgxql30^Eb$n=py!pQt_2P2 zbNLGnr-gb|Uo$8Nv}rN^#${ZgcWfifY#hG4avTVE<0Hv@a}t?FSqRA(LBJ2=)m~k( z{Cg#pYaBNBPzu#C%ai!$4$BQT_X>dK=jnwyMDn|ds`_*e$L$AmzN)`qqCTS|(zZtk z>~IRV-&Uair(f%vq{FRx?K0(0o{b4_LO)N722TWCt$51cGF-lcLa7Kb z4Qgmx>1r^97&ToPdWbFlu&U-VFvC~ua)_2(j$|G%TU33mT=-?^TdvJJ&hc}Z2|)(2 z2V~AIUUm>EoM?3OT=s^zR7xkEbG#^^XwS{0!8!IF)5Dy(A%iW^R=e%O=5L2sQ`N>DCH*8zY{Rk++G#qnSZ$Fix^}@$iWQeXRd}~p z%g=~yq?@Z$q1WxQ`;}BusDPNo_*&c_q5xDkIi%^SJ;(*G*-GiOk_XvwKUpruT8Lg3mHnC^ZvJtA7vqO0%vM+vt`cBz zEAzlaswO=E{;H>4hp$E)KY2NZ;glO_mymrG`(D5xY=_*JsSAedA!6QLeUtyG3|OU2 z+LzRGw4QoIL5t7xM9?w4^mHZs0YSLtsY{FP_to*r$kN6+POG0t93AD^LKTwkma9DxfMyh$V}CsZSZq4 zrpdS2UGCr^#2#7!P6Ux5Zg2`;YU*yzUg&q!@i{ZRN9&=2i#S^HAWDdm zZZ#c*17N9hb;W~Jq!6nnh>(QsI`C1aP0~{^Q_|I7jnnH<; zlfe`VZ4=YkWCje*QF_#y-9xvVwf|NP-{iRo)Y-U*&aRn#*vpr&BkJF3&6-qspJ+7I zKwV(x{-IGBth4148{Z_!gRyp}{+#pfV!GNWv@L*NA;n%#Jz(4&P7mZd^jBGw+l?*% zFz+|AFgXIDX|_}L!Ni}<*uv+r*AqYhN2-6m%^_9Tm~tG|JS|^_fm>VoX9MWta+29e zVsLUO)1khZl#OdXtMvkOi3 zQ67QaIIbf#IF#9`A`R<5@^nt_38ae5E+$J^1Px}dQC(>0pW)tLyIvYx?F-@GHa>Yi zzBTy(U{v>O`S+2N0YDozV=6(EWIYRgq*XCLZ@=w-2~FEZJ|yoLHA~_tJdPQ)53Q$P z-Kcv=Uv4$SadFTKwoI=QpI)*1nD?|4Ab-0CaZhUh%q+dj6*>I~BEc-_o}Fq(l16Pl zcycJ#5DI952H^;rMKcdn-8L?_9{*?(x=>a+M4;xBo`nl^uC`kf)z0ef=J9K z5Z_*MpKNyGSxMZ-Gm7HyVg~$n19j*ys%G_jXha0)m-!cC#rn^jWeec}Vr8uB;Qko< z^!|d!;?uM>360||Z=9VI}>Gr zwpD3>2F|vycSDga$(6okydw)!<4^U?T6vT&zm}l)4cDz4nqXm!Ee-ag%;8&&p0wZ zZ#^9rAIDAX*K?KDgJ~8CqvK8JSaxt;UW2I;O|^lZwv?3%c9WXp-YtMD7?zzv?DWIm zY@>$&&Qf8VDcBvd{Blhw;#bWN{}KeFxsdDl9`v>Z&%+fFs%D(^)bsS6wg*L1$rvBy z3ky>kt7o~C>aaDT3`ra$!0rdUw}8@O=vxt_4U!vcEPSL;0P@FcZH~hlWHygfR!OyZ z!28~;Jc$!-5tv+`q%mm~+NP=GpJ#6^W3KvQjGV zoe_}p5+x3gqY9n`zevc3j>mo#-us1fIUT)AU*y)E~ExZ=l+kGx33CsFY21H*^3Hy z*0|*fl_`J1p5|F7!^15irGi7pg#OzIT5{RV7isqQ(N1AcKrKus~h^1wK~YS4Yn9zZo$`sVEw zkEObMYREO`I}^$$cpS`rW9>Rc%edIf;^RPNRYAbSo90A2&vPeu1akvM+&GG((>_o^ z_ecRZVmW}nCMum8bm^Xvhje1 zAzgCD!t_W}d^`mRyoQ$z$YE3~godN|MwFZ!-#wH)^)u)FrdkJ0vU}7^4qzM8QG1PO zy3l7u8|TL_WLV(uEO4J>IoU^jtW$1LqgEzMMSt3}A^q$^ygSvG;X>z1gx@G;5xL;; z$86(_Nn~7%oWDtqadSFP-B@bB z0Tz2Qxjjj!U@7UC=Euhjf&H4^_WU6pfHJru>TXQ*u;JsZ?TdF8C6u?H{%8sz*x+@O%AsyVR{wfkA*#7oR4TZ>ROyg~t=>3z_NUE=?)v@Dtni zs~v?UxhXz^!?Whb>Y-+D$9XG0>Ff%wO$3_2z_`&b0Rehc1L3yB3?)~BmjRb z#ww(e)`vqTpS2V}a~X>X!nn`U5hYMIGd5Hn{wHoP9DX@b2wbS=z0IAG~PP+M@O zCJ6JwJ^bLZbMg69mR=;JS)VNA)R~dR42`YjYXiLh@xgV$?AtlwIzD1TU8d=RUauyI z1=lsw^@Cd}P?)rglLxuNNj^ zL}0Fyt-GXlL^Qt%HNFlz1v+4_^Xa5}cAIxJ#%IabonSNOu5g> z;A-}Yoc1#$3Jbt{ObJ04(%W4`nHav${pv^Tqz7C3p>{En&U0YK*qazACkgrS2r83? zU|+NE88y&525WQMUkRSrWb>ZmF2(s1==BTOIANoqF!H|>OMDRu<}ExZ$R>gDAp)Mk zUmwu%ff@hvd_*ri`1>skV1)!)o|NUPWA9!lH$$wu^09jwoJ2?EG5rD@R zRtfa)2*{AwN}2y_=*+Dc6_B@-#pxMpX_c+vr`R^x$tK3KHdhS=LsgK^XED=@2%Zf)wkt~=ZKbe%v?$meW&T)*mgw&H$Mczn`y zZBfHFKWaijvdV@mM zI$rKh9-BYK;A#B!=8!c`cX{m}Et#)4Us~p`wpeI*C&IG7-oXaeS|g|^F2_hw z@_3Zc3aCiWR**SkVf;(ibgUZPjDXusRrRNV&avV7mfglg6mXY!B)O%Nf^y2;_^W=c z>1uzA<2ic#k9_^T^5sS-KRznD`IY|L8jfpvt@f(}`T5J3f;xw@Ecwfjcv{bg1NoOh z`0xe&|6|ME6-CaEj+!60BY=9qXcz|c z>aE-;)V5q-t2I#9P-x~AK(%X;ch0*%e`jrTcaYH{?XSA~K)2rhr?8&b|E@~{gLb>qC3w4R`cnSP!a;`4OwNH` z@ql9D4onIp7No@^uuE7Ph8 zxEyuPUixP1P@4(((yt%8<4WeVJ3Q=89)e2dEZAL6cCyK6%JAEOxbpuwgA$brI?eVc zpadXL>L0>$PjVJ5zEEsZvc&Xu-nY;<-Z#5p^ymUE=ng6DarZ6_D1$N3TX4i6S8Typ z4R^l&US{F&+tavqZq5DOTSz;D)9zq!5|D%aorFEiI6`(OC#(I0gmO2}hY~%xum1fG zo$5&c=}m%w2(Sr!)(7I|f=4fX!!j9EACA)~cr=OcQcQ;lNMX*%y7)h#!izc?KiYy>vy2t?suV`{fJ;G--y z6->|4c+q^rznByH``T{?0LT;^qTx%m)LDej;s(DR9cJVD!-fHyybqV)GXhMRl$I0h zrOD*#2A9o~w#Y3cyTuv0q&A$1H|2Wu5sv7H$!OFfo!kBSjt9{6+n2nM&2K??Ri6$V z9~YWq3ObtH@6XEJpMgFvGx0Lc{(6?HPluP=1tIa}x}RdtoiI@T0`*nL2mp;r_3T^~ zH&3@IbY-XUcLZ&+m$^qfwW$n<1X}GbJd%Ywfy&=V6y_{e+@A07BQILJt3QP)(tCQ= zRf0<2o_K@Dc4%nLSMx^`?SZa1X7lCRO)jV1eKbH%fzdHKR@R!luOd?Ij9e_8!Mc5Aivn`J^554HCUc@s?O%Yg0r$^{8GHcJVfCVr- zMZt;NKt+?#2|+jjZ~9|e=;`#`u&Xjt+!d3M!ts4GD5>oS2v&+NZKJeBHn3L}t^=ov z46(c?TP#<9H+*c2MnY=z5-#Y6sri8hwuY=ukbx=g`$Xbq&|xHwx<0rVq%A@&c1on- zIjec+GQwZ+z((c;>fNL}%b;s=e1Q4|V`Bd4pxI*^^FJHr%$ET~gX_}eMdA^hbpGxw z^3JOpZ17mkot+i;4(p|)f%T*p=EuLo39OA5WFEjL#eMloxS_TMY4vv;{mN@9%Kx#P zFPQ(&<`Vq>XG`p+8%&SYjf`8lv-8}Exd#z!!H!Zr-*!sYXJ&|Lv6VLkYhbc~glAj&i8Ab3<6hLwU@s8M@GX%}sgJ29& zY}|^)e?m5+j3}#4dBCLtVi#eNt=RiulRH0|8UB{l@s|$Bz}Ct!iPs5m3j@<+I~ifg zPja%(Hu}nawTYqm1ze~Izo#V-l`CaajUPDi!1C>~4H)+qh7YQG4?&+nkHF`NL1js^ z#4MoMB&5#_q~*wpX&Nd~ZJ+hzz>Kt$Il&w3mMeUvFa@)KNw(0(hj^W>pf+=J9-@J2 zdTyjDalQ<3k{E9M6e14CPI}w%YM&H5|_T!>ygj(g?Ym)6fefVZvfK&cM@-20Jxnvvh8L;x&M(+_`4yLYcNG| zdv{oR5yQwaoT@@{5}%Ux+?7v4^B%)~H)wo6uXK}~J}a>7J?Q7esi?KC;pG3D?IL*;kXo6J@{MJ+QUF|D!gMVE^nG zkg#eup=5mv#t=#nT!qVI-3t1{M7eydhAb5nr5sy$qONmk^FxkgQm{M-OkHPCQQj|J z>ik=4=%~+%42cCP`(sM*nDywM(JAu$OXme;ZeR=aKD5SUo}v~^NQ6QheKYoUMKOc@ zuSaF^Bg>(mT8M@sM(hPbmk(;onJ=$J)moDr@?{_82*Odo>610_Zjzl|q~krM&oLfi zq!fQ#Gc`=iti2m15dY)oGH$qW2J`w6>o)EN{u%cnnLHK!P}=DdU<5YoNlR0@ILO&A z_sf!UhB0+|0nGkn(B$NTN~+>ZakrY$81U(TmfCewlFdb4^D^qTj-t%!bmrB>TiRF$7Lsqg6;_kV=eSA6do zUKqTg%TWu!s?=AC!{lmIQ*wu5^l2f2BDwzc;BB}iq3AqC+oRS#OJtS0X;+lL)`q?+ zX9|70MOFds{rjg}96@9%p@ojwvkp&<#Bp(#!x1T2f4u<`?}@pyTrM ze64r;=wb z%G`xHg-?tUtxd-vGDkWA9SPT85lu1SSpaZD9eX4v@u*x|m zQcfZzq}FW*5tIGTl0VH0Jrb)qMe(1)+edxwq4H<5O=`Sqbvn6keSm^5P@?Qa&WHI4 zF9_k_1P6`N>xs8YEJ66?mXedkt@;c`?G$cz(@zFte(l$9W^C)QTYGPE1NOY*oSVF!`Y$-YX1N4u=4?v=x+^>(kfb@SfHQkBq3{Rvk zZ~8O7(l4nwAgv0&Cc=dDfp6c)9BL8bAxZrq$AQV6hLW5hQ*`6vmsfYSm9xaK6P1~h zwcZ`Q*P)6)99Q%qnTDR6n#_s0t<{`^cv41_Z%QT1%~WIob~iH9O7&*rS1UfZeFIA{ zl02?F?~TJ-<;VuY9fa65FFK<}!x)7y4T0&hYJHbDeiLH-4;heA5a_wfecoEI1F1ev z-e0O`xW2L(pr?ZK?ME#21f>H%c{~^IpwiKhjSEW`YOX6zH^mk;WoV9}f36F~;&UNH z1aSxVlctoLVQ^tkRvoFqt4e5_Uqn2QkyVHpY!(=07||p*`LTyiNL8U(50;rE7Z6c+ zbTs{QNE?4IsANrTZktyIpKg+sTry@0amS)gk5$_~^nE{rb@3yQfTyEyxI%I*IWCVm z8Dsu*dM<%ER%F}asW7RI{bVdPF`*tot>zQfD}_1OYb4;Y2TE?p=%xl@SpLD$WH8@0 zI^F6Y(`nS_@6;V+`M8Q6(E?Tm8Du9`4rvzc#Pq#g@Q4mPB=9+G#HZ^I zR=U5>lw$NA{nn`^2XhTSL=^feYdl*v1X|iIU%c*#On?!#?vDvbWTj?%_`U_-U3COo z%E41KGy)7|?IfqdD=-^^{FDFIxF&AhI48m&V#@%LDja)VK)Dm|5w zAF|N*PEcb#hv6;1Zcumi2#ATyuGjQXOk3yemZ9}!);641$zQ!&Ho=4JCKK&WwK-Z%FH9sMi zd8x1IYxfb-owShZIUu1e1?G-M1iH@91%qjbPn)`Fh$idVY1M90B4Q$qNjxUJCChAz z6oo|p%!}MWqz>mQRNLVDlm8|wtdCDuZ64{rCjXrla6DrUVI?Fxo#BP!nXmcJE;yMhb5u5anTlel#=w%JyM!n#1 z=v87QCFsa>H5A-ZkdvlvWLrn0|B7bJLBa{S$fee<%*jNHwsT6MV1zHd$5%Ax)fo>Ox6h77GUXy9{tU((tn|xZlz-e1%|PayiZG z5M3Sx|2(mo9LT1}LPm*38kOHLu2Mf&RPL95jQ0WxW8Na-@7!L!4#4K&9DMt_{FjDL=z1}XZ0 zf(*3pRYZA2Rsn7ZqazupOp=V7^o13c!YUtd`ooSRXI|lXrRvY&QhI}uy8!ex>>FMI zfBWb{HMl@Y$+^U|{-HEzGYb0W@bFq*3StzrV4viA;WF=~a=y3yMtme@AqgdC5^hXw zsP2`EFJf>Nmxd79DzU)57w+fW@$h3JPFNf7S8=TuLGdm*<8OY%xr@RfxM%!b#)jUR z$-jcEE25PB*1XBK%VSQpiNXi@#N&IZd0ft|3spb_9A|&72%+sU54S!SQn54fxwjP_ z`4D;XB|%yybmD#^ELC8u5?*IVSsOI?6#?3Ze=Yabhj2)zT7k-fOtPxLZ3HY4vi^BM zX_B`+GKn0^+ef#W^ri!3N3V6CSfAG^{OFq{qz1b$>WAgn$b()YLe+9CTc>#i@MI28 z265J8kJ>^Cj4#}#+q0i7^q6;DgQ@8tK zkffCiga1@ewT1zwq$CIe2L&Up3M6;CGWQt4)98bf!bQR05o`8D3#oz`kax|Lko)WM z#|V}RJ2>v(9M2V&`(puQ2>XJM@LvM?Ce4d2g6VZ{JIxjeW|97hl9R1jTEj79iH;8( zA|4(dwpUr>GVQAoLsFp39_cx_w(j8_iV=HW^y)P%BKE~C+y?=CvdmKbe9)Um_Q4vN z8)Jhr)Pt#PdnA4!57HKR5CSD9pBc2H({CB~7KVeogP_%5`U%0%43|!lIDqD`Ae*QWORv=4mL6cE zB|+>AN^A91h7@p-I?!+~G#ZdzPHpKmk9OLRix>ol)#|kFC=0R!{QF6-S|Y zL$>QqFwM9mAhxx66=~&cj*&WU^YB;WFmg9bxcYa4CDJn{rrI(GX!1j!1U7XP-dbNX z*C&Ke0x@2p+R*VeaC8x>BWv!+llZQw-3t-<9lr;dt*O#~&;Ago2C08HjF_)Z|5D6! z*9Izx)sm+6CWoq;XQTRifbLf9h7&CFacC$s_6C7@nH{431wn+uIy)ck8nK!ij>?Mr zEkMeCVpN1eZ&(2uB0d(6v?hOeNNe}-7=ax&`?$yqswoZa@VKmIaZ?enU>w9T#H05# zoQp`g>IG29XcuCqd1gHa@tY?H4mzvj)(Bjgh%30|J4WUPzZ>}fWCx#zrYgGP0bLhF z@?8mx(+kfqKNfD3G~c8jbYD@SMmz>=s|%gRU-0o`=)DO{+J~X?$wsy$?8+Cq>Z25K zLE^uhoMxWsEAZ^!TJwk)7nudyPvt|OM1Dg4d_xHkb&2VZHVX5w!|evp(#Y}dJ+LYI zlwX;ugFIM*>9doaF19c`i_+i0y&8Q61Sugcz_XBh$b2)J%VoK01aXFbDy3!PstrV9 zi#b1=;Ji1qVm0<#QFAVP;%P99EPi5uXB3h!9k?m;6BN9>!8|~7$4@%QUhafmLhvD4 z3xootY+4y!*5hk}2As)V-sewSD7S^{qRDURk4+Q+KZu#CRs2S}I0A0t*7tAVA_FJG zFWWBm*N<)=A-t;tY_W^e25Qdff>=J&1R_^9fI<{od#fiBZ~&YCm9sivGJHe?Goqs} zC>0S!lF6Y!O*FD~)1B+ahEfuOFhb!NwxJ`4?01-Yz z0olr7kQ6wMILVU6^bv$(aiHa*~{vaL6?T-XnTZSPLRbCZ(sh<+(N$20_pGONAm?`h*mrR2z^DTj4#h zD({-`8{)M|PhKMlYUt%6c&7st3(oFNK>MDu`OFj5OhkEq=%Kz7?`L94C35+G?^sq* z>(Gt;FigA^ODq75B*%!L;IWVlv1!Q2p(APrfUqxj1eh-;wtHLhp=kN-+r4Opg2#0w5C_4nJFGoaL#yM8r&v-mY; z{f#R>%@A9V90iWBa3pOzVmo0M6>uT#spybexrRS_bL$LELW8m*hL~D^PP9r721xBYZU7JD6Y4Cio_aQK7tZGdR~2jv^q|@TQ?9S&T@S( z6eBo(guw+Pp05)#sHmp+Lx>-2D4Og8#Ou7@zvqS>o&N|zM^vOCvUt9g^ZjQ?XDwCh$U{v*fF@HkUntDM&~!kMq3+lNH0k(W92)oJGXx_L{#y4RM+v3+I zn`>czvBB^_y)l^Tdj7#*M3ob1=o1#Yo$mk#Ct_*jk8D8_L{U)Gyv#I}S~qo9V6G#i zaVxGo`m$;XS%fGCCJjjk!Me5@3V5E3@ZHb=4{4Nw+2gi_GBJv8ED&03k3&WXB5Jv^ z8bTuv8;V0sFL{; zLUCm|nPP)B_;PT(H&#y{<7KgD7jpJ*KT7`zN_%dWsA&+2!GWc7Wn`(2pm-;us>WGlA^87q+~StC$s{zPTCU^Z9cL9Jni_J7OT23x*$K0);=NyL|zTa zJA!tMo>m$@vMTAI5xd|+rjYBHY``4g!*{yIwo^Qiemhk1gRkBG#}(@q6ks45=7TM z!AJ{LeoO>^jMagzHD}Z47Wzzp(SkQcCR1xrexYeRnU!Hts8-v;)vMQk zD{k@OmK65{lSDK^Ae&RlgA+M}c|1xfSGkk|3dC0h41S*n3BLYOoC4R!x0DUjm-`@8 zgkU03#S$dv(!f-UH4d4K$(SAOZ3Aap)oy|PbQK6HL!erSTHVX4wXS#d#GOKW8YOjw zl{JNpiW-bA2IUQ&A_)JiPRrq6R@^&-+zjjuuMM?~Rd?)7rLOW$fHgsmw2N;S)%T_| zAuQac84Ljnk7SLyu~b++K2?qp%&9`JD9#*?EhDOnS%{`{zez&8(MJ7Cf59_+vZrZ% zdgCw!Y=C3=*ETrjq6G1KN=~a8`c;t4XK_u2xFa~{jXh{S7=;P-PNKj}7&_zlP1$PJ4|hr=L}w7t$g~Fz5@{L8(mwyg@{|TjK9hhpr74pE()R#FpCQ)c>S1M81Fdf0cys|94dBf6MRq|2*_1P%Y}S`k$C$<)6^%30dW9T|m<=u+1J{ z5-~qfGC$EiXp!E>k7CY`0h~?GK+hH+V?nCD+lv_QVvhg65HlE%VZ-T9W_T4xv`@4K zw)u?=o#oVylhtC;VW%VqlR>N9X1kwmb$+%)MK+zc#z=b~=t6RYOVLMR1SCCtm!@6( zf@=K?W`+89mmsnEdGoWGAZ_cUh0S&Ku4n3SSqZt_Ah};&{NYq8v|6062Qob09>>zS z9PPCmtkyrucX+(^=h3LNKi-|Fh((+puJE zXH{25NPe%dN^N!M$&b;_0Om(t_|WEhPr&VT0rbi$FE1bPeDNW%2KtlzzCU08J>0p* zpwZaqDr>ZS68#lIsU+koXd}xd50#k{LGw? zkfbaOOzcI6%DR^sm8n?CV9KH$8AFN@ft3Sn^V|uqcG)x+fy6 z+3FcdrsBd8AulvD4|hjxO%GX z(eD1tI{4TlhIIS$?P^vfBJ%#RX?z}a6;rj%gM1{bM~s|V28bJXD)9a==*kc&x(wc< zo=p{vssHF~Ks?;DDp&lJGK6!bFNNuN+g1Gsf~%#;>R|5p z6zCwLr#SN|L0RuqE*W3B|Ml;T7OM4`m@9JnxS@Oo8?V**k+ zRksOkZ(>Q(A8IL!NGw$#?1!KKx-gmE-Duw)zeiP(Sxhi^ybK4+7=%cVoWe?${3!qV zzUsJtzSi`-(e+whE;gQSkCbvhch370k?$CK{F(CU_4)pMrRjR33qtM{2=U|dzRbp& zSoHXO!G4MOiZ%ENL7r9F%#pU1yYkP`hUu02yY21NVRva1^L7W@!^me}K3{s%_)%m` zLj`@pjTa#-@BrVM-FAci(OGk=bGGp--7j@q7)47I)osn=wr*}aw|cbo^m5}?I?oSY zF}`_bbG1DNQ`sY6Dj-TGPp8=31e!9=1fc_ghWcYWFb38spm;K!(3Qmq^fQYHISm-b}NtyFuh5v?COB4pnHi zx$OQy|9XABKTgPDyR%TGr`gP4eYMyXRZsZUjwkOcu5m|qHm~2kn@py6HzzD zL&9{M8*#7RzTSeLobmLuTF38h9$H^#8rsmXF*ly8<;x|;8#_8z^z}QhWD-HNhxUSp zDKGIz(%#X<#P4-h$k`_U8F70xXQ!kZ$`1^E-g~2HQG^72e%0cMYE&Wzgzj;W2@g2btHm} zItn}DS^mLHcxp=XZz{zOaDfu^c-rgrt$M588xQhs{v0s%NxqK8f?6iqcn`fJ<%#;| z=*2A}MBnOI>~5lpPeYw-FYFY}?n|foyO*$&^vKC~e#EhjQk9w@05NIB$m+b1^}v&> zBPzJ$eM>AJ9Skh{4DhcTLW>lwZVCfCk111PZ2ECBA7&Yfo=bCe>Q&@g<%(Fg1{Fh& zjc8XFC)%fGmJrI%n=o&*EKVocT~|+7v_okNPmSWaYj; ze!W07ay)RTKIzHba5Ks(v0sm)A`cJb7jw)zX>;7)zz0@9dE8HmTjjg)s9VD+>f?HdKf< z{7Ta$gFbC)Vi+%!DXuZ3j+RCjKv)RNl7x!bBq`msb6Z|sfi~jkBr&hrJjCrCV^8J1W9!@gVn1_ z@Bg8y$cC>piw8Qee>XSZ-6NcC*IlO(!DM{sm&*Fo`Ppm(Ml#oj4I}VIO;@q}4C6tW z4TtF0RoJ5~Q`>@2@`WfECd5TL#8-c6Mg*h`VJ|@7UlKY|l2zH^>C)I+boPRul7{)T zJt>)aRSIjpklJIrFIlEB*v8c6n?Yhf)MDCH61^=2hbK0AL%*T6kwib(+O>Cgb1|E& z)RIk_ole&Azsya6-GXf`(6F0Di5Ro7f%f0h>cjr3zc=d(c! zXYldT4vwo{SxwsiMcP|M#l1yO!UTc@O>mbG2=49#8h3XK5?q73OMu|+8r)q1gy0R0 z25BT%tT?!Eu{X3f0LTD*iO(tXa}Rkio2vN}B-pH2|)1r?OGq zA}g(-ogLJ*R?PI6h>+LT!fNREK$O?#2i{n`ECZAbFzlL5Sb1nUjbU4xJHf3tXqGEK1+LYsyp+T?dXsOL+sZDAn z$)j9r1CGT9>(t4qV_lnej~|Pp?y}-Y(A77%$)y@&zqc}*=HE#D4!XiHMHSiMZsz5kxFE3Pvu4T-1&t<;%p?$qz-?@0W$Jg^jB{3Fp_-eCd%oswSPJ=#*X@_H=A z@?f`OSD8I$+0Mh=C%#a9o5A5rr0nwRn4FmWP^Xfr2DsyCTTWg+nME#qJwgV|1Y!+c zBYm^t7L$j&QIgS#R;Ie8-t4C771_sfHa6dm<{X!4oiT*U!aa_Hg?RLFXX0^kk6Gy*8=Cc)vXoOpS5U#hET3>G znaMy2S;3o8Xq-%9e63*KHMV8DBP*?(u{p9N5dB%WxzUrY{7G7&@gnkH)Ecx=tAHzc z%?C*boiEA)z-(e>P?3igS%J_68H!kiS*14NumuVwIk$Lh`!YOsJ?;)Pvvv5n$C2~> zPc3O>Y=RjIU)Fk8%r;5IIz6HWOD9V#+R=SJ(jl!_2$a3)O4fO5AhOI7iCFFv-8ftx z^R@52f_!b+b^nClA4-_1z#U3ctiK#A6oR#!yRuRQGigzAPRhX85+xQS5VvM-VGZs0 z-uUX-oXxlfo4_(r&$oHr?g0LaYfLp-6;`!-TSFRM2U=9_?Ld)+>qlL3ogcNV=BPC+ z%~~!v;qyluMtzMuBO3}7IzJcO#f4cOh=dRz6~7tW41LXE zcSxBWhWx~+lv!<=a&1)bcc&0 zU?shj|Ltg5Yz=Fbb#-35?{T<Hj_5OOTwV|QvEq0&3n6cJRXYL;3n?#kk=y$Z zh^e`v?wK=nGBP$_WZoCQ%}vMR@3@y9AOVL?YDqLWSvXv2Og)??AePP_BRr?Z{6nFh zUWqLIVjxLr7SyRvsSH?-_PbYgQ?cMgc5Kg}_AO808keK5m|^UACGn-|YyAbfrfxgC zr(Bz%nN87bN8KP4N80e|^SP}aqdxxW_KsOf^U`kwh1Ee;hU(%CU}b>^^PTvlc)@f- zzNNRdpU+RHoI>EgN{imlpTqm|V zzmAk@RCM<>wJF1jPm1&M#|CyUejm+Wx1a~QFZp)sb~|Mz%y--UcO}S*v=-Y$s z5DY^ZX%P3^S;c_J{Yhqh{}KLPktBO!SU7_*oh)FLmq~&X%*;sC8?L3gxX$dIlG*@imD1nCtzFt zu_;{k!1Ev}t2t*Z-$cbiMn&`A6OKs}h!2wLh@{47@+V`TM(H zitYqA>Fx?hK@nfzGvgwk7Rf00-=3YBQR_M!`)M`WmLmQlI zb<9M%zTQd|rz+5YmCqI~&C>wK*^!`KlNo18JJ?#n?)V)Wy!k_;X3m`^ zvyu3lxYZ5%u;#CvsS&hWeIyCW=BP408aC`(uy=2@4FnNZ+2KDo9twp38MUJyzv9k= zoh~Ru)*ajb)mg>aZsp{ydRy>(#36`sF}a&Au?Xeowx9rBjTXr-c0_sVx&{k8LY3dB zJi8+&=c!@JxZS4szW5i6wp6-fFx zVk7If#dlc^LtI))y0?J*INIOS*0c{qtpiV8j*Fz@y_tx8?-yfU9{qR68)F!Avoo&# z_RXcS=6=u7H|l}A#K!7<-rXJ(T+0!inrd78{S`sFC8g|-h0W7d=nh41XMX1?Xw81c zM^`}dHNe7+I((ZO%UF{RTb?%jZ0s3F zUr->Cqlh5={m49O-r+T+F#c^;k2s@|85z;91P0>5i7n=fF?W7KdwdcolIP( zeiRpG@D!S)U9ulvco4G`(p3?-2U~HSpuqFPjVyF=!Pvqqq*I6sS>f+{^_E_T!ce*4 zlmrQ0S?Vgj3Sonbqj9=~GDSP>d(fKVg-*?}Ij3vOpW#uk-RFoo$W`=CJ(6#RvwZbY zJDHYoHI1M!=GFU)Ic`1F43jmF40`}vgc;_ynbhGg6a2|tM9Q3~^9cPNlox9?%eXJs zDGiZ;-*d-Ieb5#=`#B!LHu8c<$a9_eS3$*XZbfz~urR^dTo2NrTlh`#DUxe>Y}r?_ z6MAQu56cz{Fp`X19OVHn6Q#v1UImjJ(JQOI4ZK)Q;b@1sc7tRgcyGnEL-UWMDMSIcd%nl*P@$;>4qvJ=sqUT>3} zA%h}F(1s?alobiGbfimhKbgEGOnbuW4)|xRFf96OP1`M30f#V6m-n-^yI14y`H-c9 zg6n_^*mlzHoRTpI*M~md_xvJdg_cW&i?+QA!_{ibZ3n>2!A(L<>8r(9FhI@7x&}5R z)|QwlE4$iz?Arr0^!ybMM1h?qaRaq`u%VB53Wbm-+|r6ZB(L{&a>j?3!ubC0M#h!0 zx@T^u}HxEUud`z zF2#HJNHnEfk(ucwTJ2toms8QODk2RV*tJqNoUyZBm$Pd#02NFO@bw8~q8r8ktd_xo zo~3Ni{6AG$Dt1o%n9xGj%5co6)rBBMIfWn$V~=S^vsBVs3bYT~%84hwdP*_Bd_KT% zPrC_5ic$M({k!&|`z0Flxk{I3=J`Qsj8$81%tf603d?Z68rBdEUz$@?;rCwk()Qu% zLZGRWK!TgfgUwak7d;f~6yZZZ1}bb`hV69kigIM%f^#F%;j9P_^+zV};Ld^KDKwCE z7ZjQ?p83Tuah41hH<|Et76slb-QMPLZ%~>xex_L0sb3kLYcbHb5DNMVxc~N}o9YD{ zLGA{M{`mKpJby3!z-pKWuUW7&7#ec_i9ZFy;w`S&2gDBWn^WE?W+@XsJ|bSNrR*j6 zXfPTUm06dCh{oG!t9n;cd>hk zd*(airIRD$7igW76~QunGV;%|5NQb2DBD^C96SZg0Qw?6ti@kdu&Tn7HM1PLNDo|) z7I*yRfeXV<gR zyJs~z*GTPT3&$aUIT0c%P-FqoLOx-OOJ*W#b~$6s<6@;PN~VHU!gNb;IOS*?++Lsv zc@)HnI_wtWPLI-_4Q&7NnJnMHLQYV)W0ff`1G8|5G#A(i%^x$b>{9eN?hgehug48p z_s`slDrAM-`*Hj>+Xb+vmMN2l6sgAy;9Q{D>TL)D379f0!#}cx8cYtS)H}6mW2`fA;of%Yl{y5|yuw&8rrq9i&pZ-=JmMK;sb`IY1PGb6luRD3;SG zoPGV)Q^n08pF*<+o)fp2=BEX1^;b*Ap2$zsCR7eI^2$<`I_0M{YK5r^ivgGh=Mo! zQTl5dWDG6l%-=DX5r3p>VZrGrFqD6aaa`aZ@jUnmNovA(iopI}R#&NxTJ{^~An#{f z%%*sUB>eEA80Rs*x1Uwq{B`R1INy*iUvF8q89{UqHIXK04}7zRKFNGasVqRxhvgqL zS!w%ilAtC}wP$kYiB~HM(lUOW`~KtbA(h`?5&33+_Z{#s1KPh7NCW84S&r%U4-@Wf z`94%|>ciJ(^&%aZpAaI&jTrBvc}hc)HkNrV${I>)p4m?cgiF1YEOj@B`N9CHtaE(F zK7Q@egv>}Ul;Ou(MafA1PO@G>h)4@5{J4cNOTzT;VduX80mCg-u|L=&ers#Fi|DRc zV~V2t3Fr28X#7&WIsqnz>|2IrKWyL)D#Z+!)#GJJkn>`oqee&Pixa1yvdp|#Ye1$E zMB=ZMHJKkkeuA;gs0 zxy!TaH43;qN?60R3vfFAm9*y2>-i&Vt8m7HL-%PhiE+0!htKKwwB}^KDO*S9Y%Z~0 zx@AJpY5hX8Y@xQ(_jn}-7%_gLfAZr_H6c)L$BobyxFM`A~I02EIs9iCmEoFC%RqtM4`4JmKz4iEm8QJrq>=gEHXB<7N*4&jw)_r z-~p(YZTXV_Bb!+3b`k#oBtv){c^p6U6CX!Sd?ASwjk(ueT-Xv>3}1n`l%TD!X{F8$G%BE2MdqQl;;B^=Ph{9Hb;9l(yUz4LI#66WjD_W3DM^W0+zr{M{veJ)G z`IXIzRR%Ll;F}l92ePvA{RF01ZBlx<%B`-Ul42E9#vD}AwlkcNlGZ{A4+#ULKFm<0 zu1K~oM3Ka^Xl0+Md~nIs8do}J?_u6D5%8}vi_m5>AN5U@aAu$gMpROksVYLA7-H|8 zd_-|`gqXPmy3P0h+Se16SYobnH0L}`O#$MLIHcO(NnLtDe2R=sNS)x@n1cOE(Twz@ zUgJv#1OvZ6qC7=8rJPQ1M#X_ji?GLIr0gY71Hx-n;UfuDubBi)ZB%woM( z#53e?g*Un^OIhTgn;033vy}Rb5s}Z7wT& zaff*FQX0pkyl00|)VvPRF68r6YCXgX!5`jk?=H z^;E6Ba_Kl_)v_%FDj_?w`1ZRTe4pMC#kkIhR~)e(sZQp-C(-{g6)BbuD} z_4~4HjnD0lM7k=v=~P5Hh%OF34rMm0=Kkhw39)`B+l5`}GJtaO^JX?rIW@&RhBFaR zO%e>{@SEyL4e7eKs`Ii~g7aNMLcVqej9H|F-M2GVv`?UG-|$ixejox#zMFkVs-u_w zYPDRKgUk+Rbh7DdVE?72TT40td7IG!O()|+u|@k^T((29f)hLNQ7Fflt<;#U{A`SVK^AFE01$d} zeVLzStynt0l)Z{{mRu!doSni{OFw_Ci+)Bh`$QI9qc&0g(KQvbI*7CcL{zaDtK#=0 zNzh#gJo#!B<7Ci3@PxdxV^vnQ5qiTLR~_LWx)9&+W7KYwlrG9fiP~%27C4`bnnQp< zsoTUY)c&)7WN4L%xz&vK&)YAof=PHCf?awfQIse74zGGLc__;58hug+A{sCvOZ75mULGZ$Y4>%*M-sC0x zX`#l@=k(UJ)|$mzJ|HK-KkM?J6_LM#V?T5e?NoayqQJPptWg|^3TX<+^2k^psek*V z>X5COwA;R+qZsIW!Z>_f zIXz+9c916JZ^}?NG)9zHKhMNMEK(3Do1}>4Rc(S7e`E3$Ey+C<%*H%@lLpVo1+ z6EzrRqyeRPode9k!RfoKEg3GkP4(Q-V!3b=v3b_!wmqFjq?%M8{4ga`9hMrQ^pP>ZgEhQg z?8OFOaWg#pdj!ph#@jA2ML;*^usg!IZQwPIKD{|0Vk@j_FY2%mH$D2cvY!gMIyz#! zjvZ!6tFYgQeJ@gm4Njf))6$vIv#M&+@z#gCD&W_Kg1 zd+JXmB~c}nQ-82Ud^fCKV3)ENJbh*Rv!G=_fqe5>ADATf&H3cMwmEnv2Wbo3hYm=) z%54bZ2{Tj^1_Nu(sQTz5v^!dpMh`Tk?2Q+}OxY12e>V^T{RDjfXTT>zsy6{`v7%(s zMyWp_SM=^`L|K|5Ti@qpxd^LQ_-^YVM!BOSS2O@M^$FYa?sR==OmJEG#qCgGL3!=z z@@Ub|H4Z=hXjsdx;&g?r)9j!g+}P^ye7`l)xXWtHOy>9e5VKkz=s-y}>hy4ZG;ZOoL3rf%$ z)sq$HXdAQEy*Ky1_Fqc2wN2vto@l!T3frZhU3y!4kq`8hJW%TYx<1!XDCe@yf^$Zm z8N_f&jvYx^NKVB4iN0v|UBOuuAGfEIMSTb@X*1HRVYqvGTGi#Lho+kg+aFP0TcIl0 zGKfQBM4Zp3MYv3V5f%G0P+u!{c#`(V%hNRRISip!zaLULl*yEX2^a;x=x6q8sHJ|a zWZWE-4E`?RTE7BSwB(NFkWNGvg&>BLzWK-ohs|YeJH=a7%tY|mbyF0RZ#OE-{hfPO zkG%lC5TQ*WJymAjg(Fm>J(C0%#oc~dL_8q2swK3Tl0E1)cyp7wlJ2_}?v%pBR}#C# z0Me<6D#~y0Bia*r@C%Gt75Rz^mP&8GMM7$K!|K9F@GI5wuMwXyvE_$gv z-}Ud?I1>Z~LXng8q8a}$bn=(p7VnKsF{eei_+G8tPITU)qQwWkqeio7WTd^Jr4PuC zDnaw@-)H5V@3;+(MOPd>NVq0<+dOp;r`ObbpT-FJ6~N~xC876-iH->OPp|{ZQty&`UfEOxL4+WEL$Oot>%`wP0CLMAFFJIK3;(E?`M?^j0eSuw}|c=%1GY4iHFSGxs_zI1Y* zzsyTNiB_t8OPioyc6HiZ%&Ud^uUsjx?yz=Rb-D$Je>vS6!J$K-^BxKY1#S41>0Bb8 z3Pb65y+*r~3ST=KeI8Cr(nWRj>F8!b3@Z3;z!rLz>hoYUj!k@8l0VhGoAPfv=JS%$_|TQ$&97CejVCcN3;Az<%nt@zbHg^BUTu@r68*Pey}K7*DCmRO zG`ZL2a#i793(6_P`TCr5=&RI|`|=DM39(hKrSQCkX09o*9(L3{^hFu=k}Y|i3_nMt zv5K_2o-7s(-8ifn&bE2j4Ud-Qlf_6K-B$Pw-60BEg;&X2Rii)kTA04H3Muy3eA~Sz zy6bdj5p}+Mtd>^J?O``i-suqXy?u-8H0-Z} z6hqPhcJy>J9hkXbr10zB>I<^Cxv73Q8jc&-Axh1Pa!wdT=cTs z$nEsGA$ziWSV`!NnP?rtT73HyP-zyyq^!wAw%O~Zw^wS<829Y-JXB_=Ooa;5b-RDO zo2jW`QMn9>h}VeEV_UDjQO(!?Q(n3dgM1gWpl#6Pke_S zXx5*NBgY2!UKa5c@UK^rh?1bUphUCR2~}c6TkDSpZj7HLt$q_-c69VCgKieBPMSS@ zDto?K=J;9SGv)8{EAwyj(G33Wz1DeS@4SF18_(ivuzbEO@jVhaKEP7&eVH;&lG;bV zs~)0XGr@JIg#Yb?Q{57SJZ{b$9UPF@{eAFq=-i3OJ^BA!e97Ow7n8qJSt#0gK2At@ zb?pC*y6B1Wl=^T8VPc{3oa3)Hxq&r#{US>RWx?&>Kiq*r^#e4w)v&50& zQ+2E%hH~vk&EqW1b;j@9KBM%@FMQ_LlW%bfQl9Y>_8_1m<<8$|c5TtC)6<~ z|6{x*-otNP1k3FSvbVQ~LZO>sEWdKHLb^k`nV$|j`c`)m`c@Z;9B)J^$cRWtHXi5J zUMl!M9!ut*@!<5}Db3c6LutsapdkYT0|)~H-F^r;lMh)34|#J~T%u%O{FXE|^_yOn z9A++z)LkuKsAu*mAV|Gc+<1EJ-tK=>4v7otp2$EEp3|I4iue2fdbR*kJMXS7F7&el zoHhh`jqcv|?e<2WHiBQZAL~KHeO`RrrK`J^?}Qf%3}rX^W*DYJ@c^3XYmP9)naH4jKJRGn1COKc(>*Up)ctX*xR(6ilZ+DV>)Im)G3?&q8O{;#jH(ZG+P(pK!-8g56Izc9xi z-rIBMfQPH+>&hoG3k2bKDQRTsAtdQFyEwjU?<&W23qJ`9_v!FhaVa!XYx(Twgr=Du zI>x4&58Zp$i@VKXIasyLqVyH~EwE{u_LE*@y82fS zEFaeUEFknpa7B}I*3+zx%D#N>QDs3`#jOxEr%nIz$~Jhl2VC)Sp>Q&k_0Re`e-@Fs zAdOd)g3;EYei`q=ZWu3~WGjJGOAbb7=iF)Z11rC~x{{aj;=Ku~kNfZ0H> zY9hQ1Gdp{1TWq#qXC1@tjJ|Hk(L4JvUd1HFus;31m_Od=+aSLli;Ihk2?LF3RpZ*I5o$%`)^U1O!h3j@CPJi-E(laRO(VIrvU=_mOV#q07NsdSy)b^tL}}=#E{PWk|H!zp9<> z2bHrkDE|*=mtMDW8@yE|Fyl!}Gr=nunfsY@yByLR!6$!$YV7<767=!(Y^$xUZEkLE zZ|DDVr&kfWq77D+oB$uLOB8kEsbMmH^y}*-OCG_5`>)g7$pfthnWR{rp_F{A>t$VB zS$T4Oef_pkguj;8BP#CO<*c?=HcE`KJwBW9;+XogMLgu^}$8lSIxYm@^Qy*^*;vA-Fxm{@>kHE4*l)2Ns5fLI>i&u1`jRp zXm)eO#~mfny~}{4qtX+7n-svsqpheO4asY9W(EQ|Ti+OXg4Abv?-+|p*Ayafu#ku@ znpEVc2Ns8;jHTA>vRJ|-AWk1-Z7)!jqY>0SWz29DKfcK-!Brfx)>w>RMxoDSs}3>W zwR@+*wnM|YCOE2`C6!7$vOiF;$Aw6a{RHI)o0Owe>YT{~u8H%~r|ddrr5994RESBv zeu)3Qlk#`(QG=ABMOPeTNRlahv9`XO4Rfohh)2J=xvDp=6C@TS85P_IH?Jw}x3%=r zI1V*tU*)9DUm6%*G?@EM&c#B*Nb-zV{hj`B1eJDEQbM=<@7{B^TtSbi=)Cjo2 z;ICDAMPD7i97#N>i3Mi+;}=qT!jp4v)I6yn9v=9urfEjcE6<62#)}gcy{Y?~tAbQ< zL32@5YxWlwd@dh4$C#8Ylqgbs#RXFQf)mCa)bvSb(Le`+>+*dB^FJrYE!JH|JhFAX zd={gYj+Sc&ZEbBwM^>GCY0%!vF7dnC`h}vRT4bpqZ)xccqnm}^V+ImiSrWfGpK{;5 zb-bGmp^G2|E#(G-3-OYj&-fGkXj$Ns;~wt@CvC9QggRIqyrdv|rmheLb?#~3Ks@_7 zy|Hn8T+`Ar59}W2jEhhgRb6$~I4W1c%u`eD8#F45$asbxs-`=bla}qKeX7+3zqSwr z{!pTpS6bnhmD6{ztlJ9`@QQz%SoNIu$p1W|9M&afVfszhEoZtvWPO>UwV-@bBfV4l z^OdZUr`id5@E7`}Mz@wN{jx4LbVlk*y*Oi;-L%6m3k{(WyB9c6Y`D$ktjZhYGc17(KT!j7u;{n{pwXnd_ATJ$Hb7^Vhtcjh}PT#+J z_gT|v3H9tww>=9*enr&X10jbS&+~oS%He;wLnh^oxU*qBjh&62vhp>?L!dSASWG9& z5sZ0+1zoTa!Z#3-z0Zh8EW&yWzS`GjjZ(dT@L3jI(qCQzXHR@}zj}wCa%bq8EdxRP zf_@RUUbu6H;bPQTo*8GJ+MGRv*-aK^0&S>S2F{Ks-*(>Pi3M^nM+XP^fH`R?dFSZG zS9kdJ8$`sW#~iTe577g-V5V+`7PpQ?(R?!u9j55wiB8vpZNb>E7Bf4S~=iuAP-*n6`EB^D#l;6g4p zkMoVpOLAd+&j97nT$I*n@4Mi>gamDb?g_t1M(@1s8=-N3-Okz@r7y-7qw5399v8>i z=$+(^P3y4I*~$zn0YN<^WaJ0r`^CeW`Ih-}{gh?*aM|JdQncvj8h)jGSl4@w>Ba?p zvLiMW=Aym!V2t2PRC?mE4u`o_Px4h+wIw0=OKV(R6%SP$MSaGmh)d8mu3<+Wu+DULR^cyUFpa2i zRH*nS)yx2L#DRP`?Gt;mn&57r$hBGITMlD;tE;9133b?-$iW>~(iw~<49>gmDO4{* zjZV;HGGXB|)D~fO&n$r zYVony1U*Mg{!Jz5R7o{&gz^0ok4to5F)b5WvAn_oB@*eJQ>g#??)v<0dF?1yOaSVc zj1Ds`esp>Q3af7Lhe~7#866hvRuo*$^B~oAYSufIbr#_dRV_@JU`2E{#PMA32I&8i3 z!F&x;_SPJPf~4CF9fJv$-A7>^%c$S3HFSRQViU~m9w9S^r&BS^fg;>m4GYVc18Sxa z)sP~QSDWXpVu&9U@URKKPkU=aOex=`Hcvl(8CIl(n;|q)m(xuxe_oiVi$hMl@E=9=>J4d&@&*=RGoaTS^v3i$_}L3ZkH*}C#^>5@=QETx4- z?>FyTg{F~o(SOyFzI7z@o)KzUb-xkeC*2ZMpdCacBABTya{om84eq)7TtX1QIx`;RfxYrPF3_u;(S3v2CzmvfsN$36po)zlIpD=|k! zMG~KjLVli}vSm$#8?0{>NiWo{)ww&pE0%o<`saSC%eu*C(WJ^A&C|0s@#Lntu2EH- zNF~l?iEF=x<}iE^H_*^#gRD5=bCHDNWNUp@Ej(Klgd64u*`_8B*g&h(?52(PPC5!; z1S4!&lZ@{bRU5VSGtHcDGmM5co42jkTcvy)Gf2x3)bYMUb_uN5?bCqoj4(Wf{$Xg; z=VX3a6-A`#kU~0fCZZS)7btA3uqJS7Ox3ov-a!KsR&(G!qvuh0`XIU=mv+wUqSF2G zzj$7?J5~k|aW~C0GVT~ZyM(Fo_8nZ&5K!V=fHuU6O+#mF`rGva?4;+_IeIYg8j)R$ z_Wg%S(Hht^%K>7_#GG~xTU-b7lER!b)pJO2bXc}_`5XlE(^3c~ zUofdvy#poSD+=l!n6hDv6KAW##dpRCFR&PW;R*ptQO8GMY)5g+I^_hK)?Y2 zM!4H=j&?;K^_udaq2iY{)PLdZ*5oOmmPE8UCR>`A;b6C%^bJIik&&%Lr?KkaTNz16 zmfVjeB>2Z=xYqRIC^L~Aot&H;(>^|)Z4Lo8t`ldMI7u3R?<6#baMoDl45qGE5QA+< zb#0q&;#OP6C{st#%sy1%Uqm%VcBAgexfQkl#SbbB&&5@g?&v}0tFuref${zk1o_d@ zu@KUix0MGGlnF`Tg1J|)TCti0f{z zw9L2}T6??xVt%C8!(6YNu|Cg-X-Vfv;QwsG#Ma^|vk^RS=(HnW_^IcfEUlt3{!7`` zJ{9uJP*HQiHCl!Tr7I+LL7p-ksLRUlVMB%flwZBz1x2KC344UM_m)Sof(C+Wb}`TN z%iMy`5_RW83s1UioZDo5{pn&k00hAj$%$XKjn&JyArR5@y`@QN9{Bx?J-q0Z_rTqV+?oTxB}~6 zf8cKB%?=ricnlkFz}8^H=e$xk%tm2^D^TMiMJ#Sw-wnha@mwRL0wn?6gp-ho1F+Y! zB-E>b;h{33i@u(5CrYp&^<_Hfic+@?Mcn@vm^_w0z5*fNf_^DhlWk(rXlpMtHMO`f zKV5)Wag2;9NJ#vj+-<*tHQiuk01N8u>}+nvYY5Ed+y%_uK`GxiY5YuI1}53-3zexk z!?t3J$+Rn9)7n&vj&-Noxt}J0=j8$9kzIjjeQN&Jn!WMvZ)#BDHKSOIeS9}ZjF(K} zG=4G!;bW8Rk%q44cOQ}+4JstUHqfIwaHT`>COr9k644kl%aO}MtVSO~L$E`XiKU_3 zOX_{70`Ir$qA|~Fk0cYP|7sZHgt3@(5mzds(i7smQ#0?g<|imo21pKJ=|xXD?7p)G zsK3$sKIKTX=|dts=!{7hOV!wKd23+mh=YiD3grS|fD1(0cy(H=&++VaQ~uV#kXCUE z`EGmK3Q}XdZ3mjhFgN9cr(iU$tR6BpK0A&vpZ2I%&UL9lOsG@{l;)Eht-`_JR0_x! z;WZow78=SJ${Vz%g1yc&RCzJcx}|(rMGW>2fkqPxg=3i{K?sd0(U+Wa z(s7DJY7|YdUm4_?I0VYu_Vsy6Y{lgr6KxfO;ZRtoEykbD{X&WFT7h>V0~e=$M@iNH z5tbg_=k!7Z-+r?Sz3`}rM8~z7*J;Oxhp$zEd-(E{s)SpPL&Ng9c0)l0c+d`D=a$ma z(xIy>0v3GFJ4BS}4=>{&$Q!&I)L>-P32L!C)N49$;XymY#4?r=T5v^U_xC~`93dbQ zsur>;m^xygIzpBzTg_t)l{~vkpk+3t^>RFFFxNe)&f8Es=9$VQ2^t8k}YC3`pP1p3dSoYqHnTm|m|mXWo<|;1F=<+IF>m zvNgnaL+cUFsTpq4SE9TBE8!-A^#w^Z7JLmaqrVFNgxV8YG7ojv?YG<;ipCscIp~-W zs>yBskRcNcgs}IxErajQQD6ec`TvHx49AaAXt|O5GeiONNnV{68^7n0{b2i!YKh6I&vX7_2&3bE)m^;T85Bo+^aJiq8Oa2m>0)DQN#+nY zq4a!Ul?$#PCtXKFKoy%+gak~|9c(#vD+OgHSToQjz{S&GQ`2`Izx?Tkc*17ZD;dr8 zr;}|=ZuXZp_;cB69OL?y&DcyNi3SnFnhK@y6Fj+41FZx(tl9!s$z3r&n; zk4G=C(hqCz5u%kK8HkI~BhSQyGVWmfVj2)(5_T0cn^}c_Z z-cg8}cTj}8ueuJ-Y=pa|hu{+PnE(B8a^jApY5DV&&$ zPj2+NtoEHxAX+syXKwl-Zg0V8O?Vth#mArJeT41$r8*y)gAb-LR)}`c?BZ{TrRPR{ zBGj64#P<5onX!p6Zj#YtY~T~G`%D`18?brg#ZSZ`G)x3RPnm;nseuYDIcpUhK@yr8 z6d62|s5x%k(P*(_htGQxu}ZjuHW$J<@%f;cH-~`p46*w$JR0+Ul(m561PAl%kL9H+ zUJg!Tw}lIdPK}%xDQG64ViQ#zDHb^+V%u9iCifKm9Md@l4xn>ve$CtT=Bdm8Oty z6nu5r3l0s@8RbEpK%MmJ02BD4aAYm*KCa@%0QyIS(dG zY>ErDphP!K`mJUB6`sj(M0DQV81M2?3qsJV={BUyD1d?MN7RZ>mKa9Fg?MX7X|h?~ zxnIda$qrfa1as|(gd(?Kl_}%lhA|;Yg`&gz6FZN=MFuHr5NV~mMmUDKh%r^wUGJa) z#n)N-zrc=X#9P{E@PPCN4dk`t2aV=feB@e@j1+Z`7k}j4xz*Lx`T6z( z@3`5uK2}({AVGbtKas77pOi!O;d+-fH=fg!S>SAn6rdF0564aiVs>hR)#{z!uC*9$ zk2ljakVOHZjuB`hdYBPn@EHALvDXWMpGXc_!d#=u;Muu<)=yxHASEpM;BY6uNJF+v$R zT&I?Oz{9n-0%~&OtrXuoHM|*}zxVuGe2#d23D@^_>6s{JPVY0~@%)H2bFI5y;~LUX z8c9x&n}tZq{`LZ*+|6JU0wpu=3sfC_s6GfjDts+$3eS^EoK`!1!x?KESX8zBgH4+J zmB9EXups)cT%Cbrg6{?}yHOe!(uB2}Q{De`lapA-VwfYPYR0r&ruT0iSD{_R+GSF* zEGLEsg|n-~(S6|B9f*&$N3TwuULHezN-TIUSPX=Gx$Kw0Q(mvem=3cwo6xNlyo`bz z4M0L?aV!9D{#C@>oC7EpeRBYfh|+(p_SFD!8zTz&KM%ShaWW004Cjd+Fo20FyFvJT!r93m)T@_klGhRK+F=c6!5JKc4_mQFl&l z_9q#ptPV5K5~v#O`1DIv_^^05f}Z)~akdW;lnax#E`KaF=3_igFkb``{`B_}`Lit* zC?cVeQ0Rbl4faBZIZl#?#XF^@C-8>8+Q-ZY&i}@8Il^WPcY&CxNo|t@|5)BqkUWd!3?irE0@m5B}H(NosDAU&A4KVk{GE49 z22Ez$9TWQQp~vXZMn)kUZO^Ui@2AaKEy&e6o7)5?{H`qx;jhA|9zLGD$q9_Y^CNxR zZ>^!LWP!M;&P$@UdicZv(MgVX&n3pQF=d(ypur!kxwoD%-& zkvrvXnTy9lhEtg6z0`N5VurRbw14NQFAR^M=x4*Tl>fRXKmgVd{{IZSbHo1~xwH1a zqwW4*el6NvsQzJlZo=M*{s+nT^28JJzaL{N4>DL#4E{g%-ZD6jZP^+WGc#Ju%*@Qp z%q&^V%w)-8CX3M`i@^emnVFdxESS3YocF$%`8)G-A`~5^j;`*iUAZ$?u3UTP<>lU# zl;!nx;9IB4e{CD+4DtB3A2TUeq%+|bEhm4Q*`qD`?ctK7A)`9oNEop0arBkGqS?-3 z*gV;UeoX{q_+g0cT|t8WekMS<`V zWx#y1go(aMvd-rprIW@cj#WYzANjX1){Q{>szv+iCZb|P!GKT2rL-liAmC~vp@3-6 z$dh-MqwjB@yAGCK9TKqa|Mnn%0U@5T{-t+0l>_l2R{#s57Dl%lOOgGT8%nY|Sbk)! ze%Iky_Oc4aej)C?lOx}lV;Z#F5CjyMc}jEV8`cS~-dqM;a(B=_1o7||EbS{c=DYf% z4r)YPdGT&%&_OzU%-QLeTJ7eUnL)F?#av_}fr|3Vk*=?8Z6&D_mlajMi5V%RGuV;RTk*z{$7TnwN{$U&k7C=cnVd_1Qk$H-?e|)Ox1UM@Iwqi4CzxHPT1I z;U4wp;vE}>3jtp%Pp+#M&q}+P+O*{fmohn8C3DP{c9 zEmLsaO&dFI^UUn<1q$IZ|N+lVRD+1~c@I zfGz(;L`scKcxDIV+7(Z2M|$*z3Q@_(&7GsAX_>n{ONZwV6{V1!?IjToV2CgRFf%29 zKIotPIk6`ba3N)`7+obL46Kxf2VxTG4+gFKk|z`BI#$%X4S%p6>!YReP?uVqI$HnY zWv@j_iU;e~>Gy=MeHchAaWyBaPX|FQa5MupjfO-N9~a%>)^?0qFJsocLC++MP|Pz6diew%T5U`IoX8#aZ(j>0JjlX`sQ)x0;PL$$`X2`Hs_&BfrkgB^qSQH zhtJ@mDHK!bv8u?+_)Y_zg~k6sx{ur!^jZ- zRh$3kA3v@Cv#Y1)|7rL7|NYy8Q$LQ$Q7NPQau})q^hKKoY$;B0*Fei>x{x`5ODwK_8>rfL|U zPcN7$H=uNYS#W#(dBgsDW{{3^NBXVshb&%1GS5F!f<&VHe32Ou!Iu$JmYYaqsJ3f5wp_hbbcWnd8E7107AWXrf=iXb2WWSI zQQF&|OfM|Fw|0|oUEO{hKZo_xyrjbcdzsEJZS~Ocs~QaL=RT&`h=a^eC5W;UGx`VC zg31SrALSN6PZE%*2Q+xO+3z-=aTOs^UdKxNF~cGJ&OAR#3u#pLBfSGl6Ki+wDpp^c zww(=h{`XPfsoyKnz9NvYn5a}FaAd~@ML_@$SU6#aT0;L3Jf2AFK5pDTa>a1HH*VsB z%xpK{{b8w!qU2KWyWSbLUJ2Vjwsm&G zrlpkGcDy|jkpN0MC8WN;pA@4`dxgW3oLjvXcpj5p;UPA~>{V_6Kf1-)JEm<_)^vH6RYIA! z0uWC^!+m8!50|R3z$yxbe|>(H23UX;-{1msJ-UF#?Q?J%PuM}mjyPTj?bV~My*@ju z>;LrSJ}1u^j+{UgQsV05#Kzv9H`jG?(4n@wJ~jL4O>M=>q?B3t<^jLOQA>1ncNa8` zQ7kpFCF{iH(4LVVQXZ?X)dNt1M<#5${oB4eQ3#p#wIjySTJTP$UrkwIdd3@6?svPA zWv-0u*iUyCjYa0=2Da+vnws`QM(&F&L_J_=TbezCaz*pm!Uj06VEh;7*H{d(sZs0dvN1_v?O&nC}J%yv(Ed-^>$PVM?{-xqRE@uHyBdA>Sd zKPG-1#$LAP)aH6_>(1PGher1GG1OGoyjmgJJL+L)Cxt_J0oFk3d4^SNG;p#1CuW%n69)y+{ zwQ7R|Fjf_Dxc=gcTU*@BOZW8ND7_fdbO=(x!^bCaP*I)>ReO{e1O$Sje<%1nrr@=) z2(z`-e31{o{hNRMYeNdv1bn=_*;#r?bKlnZI_N6!gEGe&-K^!k0R|EPtP>0j+kag7 z-+`HL#oMtJcwOGsb|5{<5`YS;eBbeOTAP|?bDRx7Q^G^RnBQ%HG4SDGv9NOIogNco zceU_)sJr`P0l!6uul4x_`ZtORAR+>ShUOCY#LXcsZx}WnDg%HV zq?6IoEnXn$2?+?sxib&ghvX#2jun9lGkOyIW$76p#=7R><|)QZ`vs8g0SC6Q+FTl< zhQeX6&Pjvj=tyNL8}tc6ZYi`RLsD3tcZSOomZ7Ita2w!k9ITC@I-v_fUe6F|)+XDx zot?4Fs84P1*7A@z(yE3)s%C1Z$M-)@DF3KT^&a2ifNs$q&Ch72>xiK?aMf$q4T-uv zB+JlT-cRR+0c8WQiV>Sk6I7MF?hkpLw8*KDyS5j9e}Cg8Y(|WnQNe6iMr3{uW8-aA z6PD;c2nnVhcfLEfU#$dZ$tH1huZ^XL!0a3Pmfsohqp7BgP_VCn_s`;MDW{%i1i%+_ zaB_-(R_{IB6bG%uHP5=;`Xh*J3ci8roUz-2;&7 zB*zsXVVt2$V#avJAB`J*jk$sJMqeV*kD?=0+>iKeU2=v%S+ z4LFyCym_Y;RNAVdnp!io2EJVhE$o)VFdR}cy1V<#>c%4zjIm5cePEC^a9hnWpU?#A zKqlt@RKVu+Jg?rS;saEZ$PC~LGA{(v`O2d*05C^K{dzM_pU?*178Ag~*HqHQcJ(&~ z>32ULHE%o(QIq||_VrgaS2@51IrR?*k5HCaX6W)ck|ceX9VSE=KmXIO-4-BsvElna zlto}305;ml%Pc~+Eb}K))s>IXErXbqurVO%Hu3!v)p*fLiXDZEm=DyOeyiZBj`Bum zj%hhTVEgNDq2Qul5w*Sn(GK~Gp!36ZYKm6qmtM;qWLydbXB&$z0i!@CyeAKpY2EhX zzPxwnwKcxe(=Qoold7sqMos1xc6z?@>m&}~uF`bI7?oi;)iG&JMeW22Nma-3@$tkX z7brlY1F$Wy-z68({CZBe=10X&P0{!5ISww=v|M~)GIxaaxxys${r#Z8S zB+`)RMUHrjEyxOP-u>gpnffG;6gJZ{jDZSH0}#MsY<<8;cY)Oci9K!}9(^i`I0(`X zeUF6JHV*z(#~8;sdJ=ad8+iXhG1zBs4FC7T+!Bj}sjRH0p@9hl6!WwF)AK`DYM$mt z!;P+X=vu?O5{!AkDc!=yAQ1`tGMy;ZsokVoa%|TzbpHJPXeS5P9BrONvs@ zIQvzcwt9j1KVmZk# zYgt`S&0LNHi3t!G=MwT&7uf-gNwfktKR z9evPiLZGL7FZ+iCdZ`D-&0ww9Z|vJfi<8#E{AQQFx*zY6zN4XF{fo?r0<*lghJi>{ z%C~y=$F}v+tkpBF(bnvIfWsIc9&h;R3gD5oA#YcmkbhtWobxn(W z0c2EBT~L-f-5v>GBjgb!2hu~=5o{?C(?MmK3nDTd{)=fT=g9QXsC1% zNiJjw%b*Kst_Q$hq;yA%7qr^t0xHlYsqC39^j0lxi3#f!wUAYjP$=eRW^>OPZq9%o zeiGHz8-_f$YEybu`iGgjHM_Z^=B)#f80$41x`a_4%|6(!0WxIUTP940)pj|9wUmxv z9s|{xeyadg-9HQX7Q`i7j+=^#WA}GPl+wxj6f*4hx(;%0QTl%S_Q=&$oAPlr-7stNUd8U!dxp`qnXO!XF1#^T$uDH$C$3~jCjSQ z<4P=WIz3z`+xUOlG4BImq|o;VW)vJcY;BR4AxM@#BiHBX0)F`5Qj+Q%Hlyw&VM=e; zR>ZAsyE%(ak)dwT<1fS;H$?y?0KO=U0De@qO0a-Ll7|bSt-obbtceB;Q=WWcabcNcp7A}Al*CISl1_~9opA$_^@#RX$)q_ zVnh%`gHd(2fb!jg8;M@4!+M*j;AXH|wQ@bVi@xQ6SYJU)hBJkWmq_5a|QMdBYu-~&detmw0V+6HHUg3)!Z(xD6Qf zdmf~tQ2z(ZfNz%sN&BBG4Nz&fL%|hJ5%*h=1T6qgc zE8u%MSXr6b1O0ChZEITE$8QGeq%mDu z=a~495imvKCAvRRAuuFBS!i?i3bO+Pw=xlj(6bH>{avr#5%V8pu9>Z-Htp&js*f@= zyQFeo%5+%+=ZhZdplrmfbykLo}~rbF$KOosb|}-!n5i z>zc8Wf{b_GMJtvnlK6Jl^(tgfu5#=9a8-Zfv{{9z^_kz2@^pIK3UQd_{keDr_REG< zKXAzN6FQ4Ohd{+2BS+;tFsh{F^F{HU<{;GkisMto=T7iKEykW`Rysa#6Y~=Z9K?vS z3&0ct=etB#ai*U_I18K~581^+v*jG0^~sz57|oy4-#N~>YV;co?d%qv)(@NiE|0Kr ziIEuspu1*Iz4!VrazYMwv)xv3dNj@8!c*A3CulHN%hkH)VUE*xXk}F)YgXKo*Z~Y( zk@cB*U-v&dW`e%R1l^cEOfR{oMET!7FC;N`HZzXuO!tha$UkptR$uJmbUL1hWd{&u z&@l0h^p7b^i=iMR>$JNT%~s&9_Na^~0-t?DbE16eCOfx%HQWwgYfuXQ66J?5;hjD_ zwT5l&?E>F**KvA9Ha-9{`un88Ej$9;w;1ma!_ZzO4O`cpe`K_mU; z+J_rUpRW^%U%ORVBeuUPUbw#Y?Ugy(uzrA8e^1C~z1}_l=(kQ(2r|4SvPmd1b6STh z)Jm^|V%09tlf#s5;rp%>01wMlOQW2E#P(qF^d;r1q@=id6dS7~)R!0T)z8S=68j1;AvpRza7 zg%BE{_ZF@1}d`pOWi)7_HXt5fkk+YQ?z%S7UE!%wfeT>U{~O zp0DSFPoG*Tx1U--hU~jeWw%#5u3;#Vu@oFPmfmQZcTnm#j5#DVxS!XW*kvw8iG`Ar zTlpfsN?Ecm82G*4gb9uNc8g*cDQ{S}o5pqF*Z7#0i)sE*fG1zw*8c0}FpWzm@$JN{uS2*d<%39eH@mv|ym3IFl zClXY0nsP4zYOlYOUF6uG5TL!#f;2g0_?!;G?;$(eWq#gASNS1YBUjtf%;-L<&#S1$ z5BDo{)|?VyUj)6-z#WSN-sDyk6w)i#ejK;rw}@4o^gu>R4GJo~oR#n(d7<4^e}#mF z?fHB@VGBOp-Nlqry{&}~e>Uh4`CSr&**ZGJ@`j#3f(YicUYZ9Lx#jyxUl-D^I0SJQ zEoq1v6^J^69tCJP&p1)ouEO%)bj+)Tf1*XN9W*|2;jTnzxd}B+WP9VG6Y_S2or|QD zOcU}21CPs*zrC*YmvXOlyLu*5DvYJjsI|MDu)YW#jA=2mv!BnGtc|bS!H~Bzy(aiB zIjyf($Spx3;;kcfXc6RwR>|ic+S=<+EqZ))rb&C|ROzc$piCv=#;uozIT=~|Jwtph^@BqaNYZQ|G#rt*`xRGGw79B`g`3VzwbkfwYGD| z{&PhmquCIb!(vVrB$z9yuM`y-*^e{^J(WrB^Xc#C6M9Y6%7uMOLhr@N&j(eSHLIlt ze`)6QmGZlaCEDtQI37A&jfJT>AmJN6ZKL3aiw_)-*T++VMpnQuEz zc0!7s6aIZ{!DC-`JiW&)K=dO1_Pf`L^r&~otnqM?h<_kpHpM2p#z#P8OH)l zq{ZUzWOQ;FFQThQE|1mLZ?XaH?-bfO8(iD3Io^&N?b&3;Gdf;*ywdOpo!o0pgLLG( z0hN@=d#L(r9_PDm_oJK6)b$D!{;%iF$H>dAmhY79D*9?;nzbeDY;P1}nrUDE(1+?dumnW3M*%)36+=;SO+MV|D#V&vD=xoW!*klEr z^oEO8*)s4WL;{meWA+eU;x3XXkY3|7a<(M!;~?FrDIeI%&onPRaq=fd>C}9abDf|+ zXf5(*M66BB`(Ffc0dLkSwX=i+*^*S+RNZ9+MD@@b!7qGSnD6XLZaF-u8%vsGAG~X9 z?-S56b>UL`c>?+V``X_Eg)ireEg%biCfo z)t%B3fAX_f%+8;r{1SjhO7*_e9qeywA* z0O_Js$PV7Y=W_7J%BL23xoeT(bYRf#F==dWzNne@ZTC^|fl)|?oF){!WV4&(hb}AJ zqf#s#0On3MF-^x5HYX}fOaGO_R+r~3yVhE8XxUUw*HZykgJ^&Y<<-wf6&8$!K1}o9 zqzOQN4L2f|DJ&4a>D}u8)D4SHg-pZ($KycSw=RrHt-qFf4S=u#R~V3KWSF}p%d3f$~SI$M#*&71P`53p}yglGu~zAwEu`o z{+yEe_dz3y@vY{%Ft}E~1zxx+ZnM$I1cbY5mJtI^PH^9QW+DMgeiwYfAF)j`fqt!+ z9_f}Qgzq&__ZL_?!)B22$-$q!jyKW$c% zE@m{C_?FB6gnZhp<+KUjS;RJHH5n7-_m-ga8ynHXphpB8VG_CcjY06cBPK-`ECla5hTJvI+ z!w&C;@9V@e{G7Wk05udViZ}$iM%5|46_yg+3yQo=NA4n^eM9j|&kDGa?agpTKV7UD zYTch%*e@pJbI&|GROD+4+#jeA^#41Txtn!rxd<+E_UkK4lvW=uO@%q!#t%(WU1uZ* zyrmke)pC|H&Pt6~b+~rIh>lDCC>Pf!>xFiP9|7MpZWU<%2F4l6EqA*z`P5vs9CHvT zLbfz|Hl44~onL}?KU~e(CFK9P5b(mO?ArZr|+Jlb2YbY){phk{BPGFLJE? zq}`v2mnCvMi;r1#Gj^_6Rs$*2LTa0V?E!RUBCZ_J_*|+ED@hN>&b9eQ-}a2-12{Ao z#1@#LC$!+SXQBJ-IeP!B7f~@kA9hhvbK3(RzrpYfpTODZxVfS>$?ylQ`{}yIJRiyr z|G!A?XNzTq>~@=et#`wT*ME0+l6z>Ri{V27czn9qPmsdxIisXi7cKXFxCscNA^YxU zOVBI$Ss7qt&`3l}x73oJkDX3swHv34Ra#YwgerT~>!Fd{>#c-oNn301-9RrzLZj9Y zcBdIM1rb6Fh1`z)$PX|x8r^2QIaPx>$@qu_99ZMhL!*PxQ?X~~QuQ9&MfSA7)#fW^ z_jWt+ee{c5?tC>Xsc(1&bphaHKUUR+Pf^2dGVY@8x&y%4akoRMSW=jU(RfAt>m04E z&DE<+#L#8^mb;)^@otXU=i9>IqNw${ZELvq4yu+UTjNSO(B~u(@iNrs%I+71qv_qA zo&_H7)F_16;UJ{|=a~YkS*6(}sX*2`v3S9^fOhe+N{c*{!EKRsUWFH-Iz_=M78(k* zwt)~WEggV;caEuwVG52bO!8rs7X!@UY_>E8t<4#m<&#Ei7H;ypW|s+{XUxe8%^KbG zOG`I-pRX#(z@`GQb7HAyf>b)a-Q`O-c)*@9ZrmR_JBZ;@SM7G@_br4gN8zX;c;H|*e>XPug0RkO}vc$^zSWC zd%(jjUa*_99ET|SyrFq6^7XvjWa5o;`7I<9-uXn>*pI=CD&V6Xw9wLb89gR@+)VNa z`JkI@IYFm6+xYXG0*xqRw_ic8bNh_|Dj2$?>+yW4>)TVfT94X07TV=D_k63PLH8NE z{Xj9zoK*Z5sc48xc?EotVIqkkfxt|+$6d^%je&s_T~3cTa@&~PP;@E^{R)g-NrroT z<2vnnG~Vz@KxA~m>XYL~IPx_rx1XX1gk-VSphrSwTg-UWyLc?crWQan#qGwXycVbT zkt+4!L}}OhZFn5C{8#n%gW2;5P3T@^UW2F2iv79pIL&AX;>$>Q{1D$I$d$5LVv|54 z$mD=4lPd&bAyMyUy_wY&nIHj*8{hpB#TYeX`vo^Q;@R9(Wm4X~*-9hw4Q%;j9$!!I ziSi{OpGT3|>+7q$xV;}KT>7%{uum#oc4oFx7Qg$>E(L*PVOa>syfrVB`@^aN!C)ub z-*E5>h`&VTOWOuU6-&mD0E)6-s}&&eeAk32zXco%H!g|y?R~fz)s(UP)^l`nMIOWj z`w}jIlF;(y&R|4I2mGgYvy$#tcS}U;x>WC1KRM;(M;^4ZZ$hgTDwovV&r44n{?Lhu@qeuhcfO+7qyw4O!^lPJqq|l?x%_&~Frqtt(_a zZ?)fP=*J7!4R$@d-mb?5c;G=}Pqf9ZINxjqrr|HSt_Mu~Bq;dZu4^ryRT0ixrA<=f z%;w&*Ni>*GU&FCk)}U-o!7jnonP7p-krGxcga7a%x59+xf=oDJ>sa}RWJ0$bdwe7= z@WrAF%27&O@Qbm7*VnfC5 zBxd0_>eJFbiqDh;^~ol1rLuWr+(*5pa;hRBpSLcT?3>8gxU1_?r*sg|-m`TwON{1Z zzCPKKmCp~r*E~o!uQK|0S}bJ`BwcDl^kxK z*YDgs;Y(T+2RAIF^`B~B z7PCct=(3%-7Q^>fb@>bg+Uj9iC1dLko%jqdd?(H)aB)?8VatBP%ax!DJ?oagH^4(Ryr9!R->J?WJyZzY9DN&fY2Gh~{;$2ZKc z8r3|z89>_l@g=<%ghY3og9O9*lOvH`Thrwq`Y^0GVnIG~~XzgyU)x43CO{m5z@ z)66~`$>aIsVrB&I=;O9vVN8j+-|{{m)|Ns=9V0g|6C?wr$1wVL;()XZmCzADL!!~( zO)BDA;YXQ-aWs@M#nf^P(L=MWdlE}cHfy!{3m{&`x)JIHv2%7lsa4zw1O^4Dlko0! z1|5o-tQL|9+1JFhn(H(GU{eeW%Go#jp73p3gVuQMkq~5U;fym03!wd|zbRz5{IKX1 zD=X};gU~OdB(;jOUAVMeG@JV9H~r4-81{QsOq_s&^h2Xzsn-7xE6rjoEmzQ$b55Md zuv0Np(2VnfcvrL9@aeD%$`e%InA^?&?iZmv#K|2!umL5g4bUIZbA}0|3#k7YQq=Tj z+AbiBrZau^BMZTFQ7#Gy_~yQmKep9|Zw2xPe&?G_SZ&(YLheHY6K**P4KF!B%~ykf z7UXfA#QrXU*xcx8I%*v=0?F*2O-lC5`(h_UGCqq@d;f-)A~hKO4sudjuzfN^VMw~% zq2rPC*9jZDEtiF)JHT)qfBW25MkBmraPu^Q%*~kqskir$4(Gbod$dT|`@Pqu2hlTha zZ}#DQkPb}s7!&kST#|glyif~*VQ89&H3b7bJ*nGL1UK?xxw*%6=@Q}s;2?U=stLyR z)=}{jgn~8y&`oQ=TT7gBoD^PiT@gtQ&6rR^M*Ro}lY6=KL&Kgr4_diK=N)(ZN_+s7 z6*gr9k#O@ON28Y?8*Fz*NG)wqriGAs;{x|>Nw8d==mu(wA}D|OIdmj9u-_XO%!)kJ zaqK~q7J_2*R6YKlfQcKIARvE-xhZU4h@0eMj83B@@>{uV&Ue}uQO4=#m^<5i*F!o# z(Xd#J{3M}U$X04sb>VKgttKjk@BE(x15ibfvo5{pJj7;sUAy}C`Sp86*td9ZSH?OC zKU~U~#(i0THfCDBpH{nCH8ACj2|Dxpo~2bg=5lBRPWmdke2lu?DDO7+=DhnhdR~mT zd$IhTNnW>Na_zq|Z(&J>80(QOQOHYkesNKpUDMAjL0@iTnR2-j8i#F5CL~CEzjj6f zqtbb`%VR`$AjSVt1e|xU4l{y;FxicpHKAolc^EV3>=Lps_#yBV<(anhSS|Lq(JcR{ zXnXVR``>L9q{qK=>tW<4;%{F(xc+W}+fd|Q>cHU)K|}2m2<62)=%*iW%d6=I5HxjH z_`D9p`FAuv6Cmf@j|4o6>&E?ICcBgogNffx&RO=d2`Z}ScyiUM9j!K$!V4Iitn@|Z zzA8gpV|$P-DRk|~usgo4GPilyx(n0S?dSd*tA%jEM5=hmV`aNg>9A5Y)h6fd=^;C9 zhosn_DB8XvetNO)3$mzCShx=Ila$<=7E}b4P)a*sj)SOM5kzgm!2z1XcD>bfFs5kW z?35$s`DIK?0iOe`84B?i)%gi|_=4*J-o5VL9|bH1LsEh2Tf;_=4NBq7pOOj~aDyRN zNsvGO#Gz}cozx7cq}nZ#(Pgna1W;`M87ubGm6QGuwv{enW3jjraT4ptYl7k{a#YP4 zsmN?RQXNaQ?06(Zsp{ueS#degYqD<(*t4wn!E>-X+8#!UK=Q<*b44b)D~y<}TDe;n zB_*|i8^#fGcJbHcVma_SNjmr5+Vp?bSXjDRZ_a*-R&xs);dR+fX_HWbpohc*gIWz5 z4y*`5>7!z?|xr;#zJ zb0b}X>~|MW?=xMqIGjY72LzNLAY!U-<+Q42HND%jo;hngw*pdWPe_szUUU54DKX0d zg&LMKSY5$zUWbW^G3 zGf#798%4l?f-=!OBWZhN+aQoAZ(uQg;qW04ZIbSibms9s>_hQ|E~ZVXuxZ4Sb~;o! z=4iUU$8G$YwKu&3VLp~tGjj!u;rycVcT>SKrd|`DduFGZO3b71?cX*xuCQbq0N+yS z`h7@sL#neJ5=96AOmTAbW+rLKggn8VR;t8JUmIbQOV<%Pe*7&aIyl_k*>lS_-RP8n z$6pg6*H!-N70`Ex@_6hl&BW8-e8&k;LsAL2O3`$ek8?+0>3IsbwR%0U;S%NZHB<%^ zrQlz+PJbMSwoV1G-6N^HPNVR3&R4qQM+Bh{lf6y}0~E*+kh)nakR8^FhQ}b{X8|na zp_ocKth;jThv$XuVnHzMc$y!Kl?ZaS_TKOgj5kC=`(`_~7WP+5>6zKc*z z>BmI}DyX&l#AAUVE|WoX*{n9{A+xcbC2etleyD%`pqe7ag<3{%GipHC|9;86)hb~1 z0e1AAv4_#%m)X+?haDH|(&1s+JG8c|yzsWdtT=|+2}@ZR`KlF$LA!_3Y&Gr*yZ30* zgdrbUzW8UMER$+oFlSG=I57c`YW|K|8~X^3`_?JRgJw+bd&YS&K2CqlY)?dh(p9pK zo){Hd*q^f@ke1hR9O+c}9mvR7g-^krks;y zSCH^R(u+)GSCzqpdJ+Fa))2uU*SvmEc2TA|B@l9{tX~vSM?v-(pX``XSxw|B(Mkx( zQIFg3fPhe`b9eZeQ5*EagvE>MRH#zqe4RgTsz2tZiVuA3~ zKAA%%v~0Xy>3%j_B4_uIrTiWuW_w|~tzequF>KKn+9`=aTuW0yr&&iq@e)%kzFEl~ zXS+OIj2hB(T#D0tS8fXx@l7muh7HXN%N^%#wnHg!_Hn6X?6C;KT1T8ge$`89BYnUl&+lU&_a^5EufuM28a7I2G+HP$qv{$> z72#oy{7B9dt=ox-&u)>k=vyz6Nv6zg_sAAlx=1n#a?C*&%9)=up?(Mb4Pq-SIbFu| zS_9Gbr#gJYJB&6mO<4-(iaNc1Q_63^oz|TNU~!F4it_cB=#`KBUv=8rm`a&XVo>2A zR-u!aje`(blyq6ljZNPFFoaQ~Wspjf_2)j^M)`gh+XHHSWCSPCmOGvD`wO&F<2y)M zc^mAHoJ3kamM&?#_jvwt-c0eRcXwl%>>PVW4Tg43wLG4hXra4G%gM+3>i9<&PA~O( zz8VRWmCj_Wi#3yQoq3*~Ow7zyqbcK+P?fADsuT3=Q4LE@f^Bt^7@Nmz(xH_STAOY8 z9iE;@TZ34W6a0R}dR5P1sLA8>&+;NBMG`WvfLky)@p=E#?+SSUiznYHgCA(&R|G;R zt9boJ56-YI2~}2 z#ABY@9)0!Cb5K+u*K! zftvO+GYv(mC{td2KC3&_%IR5PuBc=_F1NcBfn;9NPlQ7E>_>p0EV@fBRg}sCeLyZU z9a!b+hObIr6v0^ld&PmtLhWpGhI!+HELlRHkPcG;H9fvu4K8mMJvoKC7=pGka=pq5BadYx`B zUC^_#U8GfS(&_c9wE1s_;Zb6pVsR&LH9tH0;%TlHhzq;B1ts9-Rma$`)(_|`4-c=g z5*75j-dc2>eH3z)da0wzX>E}Tq{zt#u3=-6bVsEBgY5$&BABAtA+W;|PkL>l=63H_ zD;keEhF0C zVG4_As(U6TRDK00dVESNwouX-}E()v)5xM6JB9qG)*Ln=K-C%G0Zc8 z7K$+jy>PW=4e#_SQQ%v>+eto8DZsQgWaG+9`*fJUj9vqv=QVZ|Iq9-dS{g%DUAlbxYfiaTpfAe_M>D z{y6Y?IOF3+l4t<5091(?g#54}Dkg<=5JCq@O$T&|=mW+-B;#M~4rn!oVFY)6GOT&V z%IPiDZsD;xiryVE6af1)-&^O;6+UIR*z-8{iCc@Abb0J~z_cPhv)jxfOrfM%p90c_ zf_3)6f#^~kZgXU7NO)u70dR0DEdI2blsvs!l~85!XPZJ>4gc+0%?n--vp_n0_J;2& z4uT|;zo`}dkC$OtqI>&F84O_@NIOkSWQE?Y`=^BD)Pkr($rx_0i{Jku|EM5*eO(Zb z%%pi!QuieiqHz#)d2YSv6?r)2DsZxfqb%>-_XF<~7XdAe(W8QqWr4^F=jlgo&JRpB zR2$0{Iu|%rNY`z$hpfja>%jDZMpPt9Y%zHv!ZgeSKcH;FSvqgKYi>c?AEMe-9`foi zD`NyPn7&ZHuZzDR4w3Tp&z_Hp@)Ohg{n845py-FD z1@_fCaenR#R9>$o4c0tT7A6r|{Q!v0T$xees~Lwe$Zw{5-R~CIqyhoE7#V)Zu5vta zYCMF^Ny;QMllrYWfu1s~GUc3(1N3s?&52g!ojJn;#VSHopu4APCTY^;a~c4FhJ%_c zfk--+e83w;O-xn}qfU2EEFMz-qmdX2!<5u$-Z`YqGe2N_6$nJKl(X%n3wB|4jaUrP zykL1o;)}}IeFq1~Z|OEAakpB4HgUse{w3G<2@pO|r6nQ93itMm#LJ79 zG^Nonr^~hLN!^oY3l{7&9v)~I#W8*uj}EKhL4OgulI0SMS=bHbl?fClEaB7w2MUu~~1eaC=x-PeM{IEWkqjKC2Pl=YvQIZY{0# z=UU~*pEuFC86v;tt7+6-shpI15>aYDfN&|8Qpe34Y%(r>17DCoblj>>w+4OU4kBSo zFo*7vI9ABv$8@@egj#F#Byx?-dz)M@3>~0VJhgu~jhGcvQ^;m1BrK--b{gv+1AtUO z1q{-hoL|Ta*`Wf23vU`_x2MGjUEq^IHq-r}auq57c@qgORb4Sk!*;P*yHv(nTFsbovrZ*|(VHTo4zS}^0-_%)3=J$+&h}WR#-<`_UX z*x^+Ee2t%XXs?vdu6pUZO|XH|DA^iP95dz~FJDQqFV5&#&S2=~cThu4&XMtP!gD z@3zV1ejBcCdPLZM0l`q4CHqwYYh_Ktaj8xNHQAfurcP7DIu5rr%nchr6<_2b8`Ui} z)%&a;vCE^~f8q6mun?UEd;0R;K7g*lI^kaG=;lB3%!sMES~qJ)CHYh!0C~TA{oTjv!3UW#C@)I7+`-!89Rk!RP?@&5%%^g-D=e+T4UJ3 z6*{co6-e(O#~@q{I1%)DhiJwy6gc)rAQA&3fL^TDprzh^#l^g7t#5Gk?9V=jE$UCw zmEexnFmZ#W=&EnZOi6?o`~aorP@Y!zpn@Sx3y_b_GfpHsLHy>=KFTnkow#^6^ny1R z&=WwhsQ^8(P!W{=W64QmxKM0XE2M;~p|~vhqy6a++ItJUl7G0M=Js~a%4QaF8IR*P zg)L~4?CQ>&2Trf3K8xR5McNfvLC`Z53~YhOTQ{am_k!%Aoztcri1`QH2h;OHC~FI# zQ-f39@OdD1LI_?isGhGd8xN#X%nJEoZx1Ev94Jcu_9pio!0F^P>>-Omj;#VWZI&03 zvSrhDiF%fq6~W31`79kh3n24w$%?{oU1IHpWyF{ay1&T5qW5Kz%TyZ*ziNV4E9G`+ zuSyHqdwzC6`=pJM9u7ZyM+(KN?R5!t(Hg6pRZ7Z zZU<9vSZUy}8K&}zNGaP^#U1$_+x?LuL~?+Dh^Vk1djdi7A`M?!8h_Fc5JAPW>o4%n z$%$xQ*@=HJ3I0$i`)>uEH31G?o*?U+w@D|8(4Wc3dpKRu5bUI{4p!!$*Qd+}!qjhkx?v$-uQm-74p(GwSY z^$Q@08DPNoVlt1QDTS0FO{E)R3aLp=Z;{zQf4-2|&DJyVw3^JU(@^Es;ZN?p@>8uh zrDzZSCfPn)1%OKyj{saD=Z4lBkx}M76zLE3iCz$*U3C6&ed(z-_sa%Aae?t}o*5g{ z*qa7R(wo`Vv3;hr>^l2)b9?cpRYD%OM=TWdj+6;rYKY=|B{0J&I46L$80Iffe$GK3 z`Q!dlA+?L*;un=jwYsAVEQrR|q>u+)&D=2>?};VJ)8Tc|_kjb$Zg*mlnIoXWP8>P#w~50Ce})vYfk8ufhK*9J@h{ZHnjH zy10A+7hK8H(#Yy~c9ThbSa}C5%9pNJZ(ZpZdufzFXmz{!iWcXIR*I(2f2>erwO{Rv zBSp?v=bB5)KwIr=HP)o6@Uc>LTQnGOCbiAL70a+K6TAzz>S^!G zbI-@>{-ue47wQx?fZ(O+>m*PE>dF~F6$QTehSu!Sh?mE)P8J%ZFoxQEC*U295nCv= z4I=TUJO)&7-Mj58U6+HzV=P?SIXB{oDz44|-+c9H(gOR@JA7B_Blps2dx%HRH2tVd zUXPpkV~4dyYrlRGvlOC|Jdi=%W?m~fd1(Ei0T`AN8$#y*ex&|Yc>~3L#xKCi4U%K` z%j{h|0CsZ2&e7i5)b?Ca%38{c=Titz8<@&nMEZfLtOesQHNRu3Q#ll|21zKyoK zBZQWE=l&Kn0wt(~T=O%H)9pnzm906*@hXw_c@z(>nLrbw|cg{WM%3 zGVlZvW|@5%aAy9q07Lh{YvGl}7r(F88p629OCTeT}n)rM$;F($W zFfeJSA2!An?Xj{(FX}Zp2rM~}_x0c~Jy@hU0gp?)*O!Fk?=)F4>BS{rtpm=OIFhLH zwze4^aFq27sboa?_L~O{spZyfy^zgiV5bxFdt>bun5#s;mW>aTb8Ki^O*)M^IVmsk zXp+}vG=2TPo`nBQ1{>~r@y-1_h#{2BQefBKh#imij%)j&frEiWr+M8qd%~r~ zV+%R}d0J|ED_qJXr?*g_Rk`L~oDEboPR!S9E$MK%H&ZhU!;aK-Q>x%3OTjN{ah>Pc zO=}t!J8x!pq8wyI9@cg>6Lu{{oc{#{zsN?53NJgs5Da}>dUCG0!9YDLD@<+9~Zo6W?9 z#twik$6u??*sX|y(~iFMM*qXM?uK|q31V0GyzqHTYMzrcl(vuajN{+1`Ogq<$y0}; zjggdy7Z81n$1HI@75L<2FN2nV${>**sJGi7h?rbyfOT^ECO&%=&zxMY8LypZY|v)P zQNmHB|GO%)?V*ej8}kzqZW?cvgZ{w-d>X*@KyB%K0Vpk4EZ^hfQ{tnk&zJuuhKK*{ z*i)S+H9^rR@CHzl=(wbx*ssI!epGhx{!z~Orx!c$e6Um5GOd1ULn_(9Zdf_QNA;yQ zL2-?vk%-kvOMqL?26d=bNREUAdj#fn%;yhYR(hM-!HT=hqyaqO_%qA9IJsi!h}(3~ zn0)H4(a$K5^M=XxUa5TXl*bXh?@fr=bYc~Gwjj{;ES8JXXj3*TgLvC`3Ie&AJyz#a~l_-R;S|1eZTIqoZ1XnxYdTEzmMNZO}sQ!Qv?8b34Sp@ zsAn2yZpRhnT?xHb*YioXYDtPwmTewezV12RlRq`yJ)!c})|d4F{VO5kP3y5M;XA0D z=Dp{xBe|alh{^DikbL`C-nBpGxI;$ReuWQ{uQYf@hnN5PUcKxBjWppl_|3rIg34Wp1+WwqAszU6@i&4jha4u@t{>v~Uc zk~2SuE%N!sp%*2G+V$$kF^f5sTyD2iMHx~JJomaKPRad!&Htq@7Y(Kqok~?3)Z_7@ zs~ai92ERmFeBSnj1~V>d*z%5dJE<mAof))|}~ut<&C z@MoLl<_M&vCC;+z5mD)A0bRU65e(4`Gfn+j1d7|#<-JL@rWgsEWA_6SP7wTn)0Ma4 zow*&Cqg{d_2 zV0Y26+L2=^vB92P^E1P!w%25?sI zAVen`JxW#_z#aEGUTK@Ed4r{or~`y|4S$rA>3qt$4#1IYr$Tu^ZU%2e+YDnIZLKou z3sog1Lxd|3M<3bM)mkl~PtV}CI@wqkD#GPoM@e)%J&Yu#`=YT4yNM#DfxBq$Jyu}N zGFmTdWHxJgr*p^N5QspLfE!?Oc_eA&Y;?~)D=;*QUck{G%~#)`(_tSD#Y0Nx$Qj;@JIrAU5z(il;BYHew}n~Ibcf^|inV-x{@2VhQK2byg4cR;6rXj}Z19+jUtmr=!Rh60 zRqQ=1Rr+wja?B-JIsrB@uA7d1er?MzE_Wby@~@ z0bH*wkPWs1dX53$8L%zTmtcaSp*FKve;~k%?{6V>BqpSwKqS%MN%S__u5B)TdWz4k zL59YTh%17?reNWTvqKU~Y-mfzKnjAHoDLz5Lhnn2q^>Y|<(hI+o3^wlY^6pUML#H) zbY1FU!?Fl?ez1ot@=0&?Kt@LuMUIn2xi<)GqfUW8l0i}$3?6B@Hz+ptz!HRB_l`p& z$xj^$MpORtw~ULBTqLGUjz@ndAyn~)2@2NiL1=~`Y4}PbUN3El{*^@jPvuQ-x6qTj zzq?JBO4rBC4L`J7XRX9=-p>;r8_|vD3*Kk>*8-!$s^jCYe}R+t%)=2-2?iLzp^ysw z9ysy~ZY^LfYW07*1bhnI5j1?CHt{-X`;`+hD@vlK^km@qyz$I1ZRM%3nIBo0+tIsy zTN>VYE+85^!Q_d}Gs|+qH97>y0&s@FrL|~ea^rQxY@Y`H-zn*@%O1?Tj}`@O0oOQg z96S+Q1e$-KnJJ8d-CeqPfD#WL*MO$w5eESVe^U)H96YXyWU3%~z*00mkJ!*p1E_u)e3W1Kz~4lmfV>B|EtKLj!f?=p(%mm;WLh}496C%q3_&GN-+ zbf7J-`ObZLgIej!g?3Frl2&N!bDn7K0L=#u5lVA-nq=ICh&R?r020jxZJ1Np2V@06 z?mO`o^X|Ng_9EbqIS9hQI^n{>=72M+SjvT2he~AX1`ytLSxE^Q)S%Yj`JMWKoU#0#%^{Ut;dxrc@RmJ&UhsjU@};X;z=+${ej0V( zHpypxMticvn%zYdfMv7HZgr&;V}6CDaO(ew4hN?F?ae;Q<=Rb$Z5O2-p#}39h!&l% zo$|Y$xpu$uZXhC{$f!o5%5k>Jy!C&flFwX;aRqNxNM(+8alaIyz3{+hH6!d9+ZV4f z+Y=EXeIoWezbK@|oEy}XNV71L&!I5!gCF@F7TVo~H@ovls_w(@eiC&6t$nPszgN;4 z`C~poT|t6HF^e7B0dV=44bzW?W~P7?8MJthHH9&&x9L2VGx9GgiEx(y(yStk_?A`_ za=ZRwR4{}Mf7BkHkhzUG*ZwM6Gu-EmG)^ZlTg@A@aPhb(N@ol}{?G}gS zFuoAT7|_U%ES|R+w|}(9Jy@EJuH0(pt!NTC(*RjDiuaHTvbl16+2V-5&u?II-W2P7 z&5lCOL(PspArgy))_;>L*XqfKVb@k7xpeQ){4&@llFQ`r{!5Ade>k$ulxm)*NXEw& z{)^Tv17zBrKq%rzKUKl4aupH0=Isu0^mtxy9tx*4x;Qk!H$!y^T=F+AJ3QSrB=09) zoKPqj=)mQAcmqs5KxUubIAUD2wkyrl12B*L&u!LQDaYO>g*^irqZGN%1drw6phUnHwauk2@nvlycStOu^NaAEg}G*0nKNyh`1X zDL=5(2`=x?Hd3D#7VNu^7P>RFAitquk>RZ)@!Vj4D7-wLiukeSu-YQbNp2}B687}a zj_#7{T;tr2%o)s#LEjNTeH*#?y1H~ZyB2rlwOiSsI8=DV`vW|;Rj$%@Ixl}&8@xm7 zy1YFN6AKx%W94&QwK zH5BirJf%2Xy!OfQP2pH+u6)U2kvpDKc>)Fq zgVbJ1A5^VmG*ML46(1bMSL`>nz&=<$o@O&|87Q1vGi`);<-`%XQVzLk9k4iO5;Jkx zv<4NKU4rBU^#Aw}aPf6Sd3(13&M;`W%{b5~((Cy!M@W}J+nQNFzQxjf@k3}O64y#6 z;~(*QZ6tlS2+fVyg=UlB#IjeOYwM$Ji@mmWqvIDjJx-Huht*;t$Q6j{mV2cE-obli#b3`r7}OR3r-~6@oXGByrJ*m%D(LT{-HwhcwqN?* z7KM*W2R$VdLsBXj-y>S%0Bs#q0E|bB+pC(y^VOgGDs>0rUJvx&KRwWpSo3eu zXeJS}0diTm-*yg%C5=jUEEmuDXk!@gR_568nV3uod6&&seTT;%NB1&eS@F>?{EGm{LR+w7_jMsh?W$~Nl$t*(+Ummn? z`wXW0ZIu=s($c?3ul>P*Xix}*wkU{g8HhP?6adJZEeln|b|@4@RhI-vt=HyU?qly| zIpH6}Uo7#PK1|QMY7=$6rsPFLl{7)AWv3_g_m}DUMTb?Krag^#&uA)$@n9nf#y1=y zX<+ge$%IWX@j}=58;JjxJB20=P(xdG{gbI1Yf35n6U<6EZ3cklyVMhcjP?@o>kfVY zZLXTVYL!u)BepVkjMwP83?k0u2>txXFBGmv`aw|z5h$(&S_?`f4n?61Y<*;<85J`#a)srA63y#NC46s{lWG%izWcVWX3{?AXI$&xSWdAmEz4%mQ+tJjcif^ zTr&EyW&GiB-yw`jie@n@jrR0K6Ms=NQN0O!mbK=SJBe-e!$f^K;=;t#u(LP1T94kB z%@^u{DxJ4~o*__2wSwE+jTU~d=)cYN@SNC0rvb3U4N|;4K=p@kCPx|`KNl$0=3Euv zU*Vh9{9P2pi!r66^AM1Gbi(C=s8AD(nBcy<|95wgl!B96%(LTQVj509u=!N%ZWbBL zKyYRhRhE_{L|cIYla$e@6)B1d2;BWy3}*OX!PvsuocesT6gk)Lf<>y1ZyZd%yq!gH zg3`L;yY8|(_uR_RCtF-Dh`P8aOsC}q?AsHjrh?>~ zF1;R)70gHky|Wktt1eevt{Nuax!w){ndVw>)Dr0|`(~!f@D+%9wndS^E=a0&2US)& zgbT5sUe7f{Wa49hv050M3yuzazA$a%vq5ET)hOT=Knt4M+^o@OMta42TVD21>P>Mh zhYi!rQcS-fGkV?A-S{{`+)f$ZP{#iy#-vtR@No|GlvkOqoGp$u@}X6X{nz0HZ#%0o zd9iBL_F&6HZd&ViI=L|()(6UBsWbvWCZ$Iy`ex6ku=r}|ZQL!4Pb4U%iF%lQ3EJJ% zB1jd021OuU+|BRUn{GU(BA;$k>C$&j?nezGqRP#PL8xIK%}@3tq~%uOLEjXh#Sb(HZ2YgBoCvBM@Rw%frXhVKCxCJI1C#*Vzih1>QT&=x z7R3Z?H)xr*?KT5wrQ|97>6lgHFRTvYW6jlty*sgx$eQAFFXk5Pf#9g+)2jIuxhJeQ z*?`q}hJgFJ@fQZ`+o`JmGDh6^uX#a#7wK;LBmn{nMCDD2Xx17}~*EUB5V%Fw%P^7kB$C0qrV z5s6>~ojM3SzqISmL?-YH0LrS=1NjSt&fJ%Ucm>UA2;gTxiYbq_vnbERUbg+6F_o>Q zFsKWP87VQ*X-S(~VsmAQW!}1SZRwm}a|JV_6K?LuYR)SDs>^+yQ?(RPb-5Hn@jTxT zW~9{3;BqM3tfoF~sTez$oWfK(Z!H%Wzj4=)wAg6QaoI6=_@}@J1eIYQ5AKpvC-X6h zrESC|T-3kLn$9j#Y_1^h3q9C#YZCJ&V57xxeE*Tdc*6CxH?h|8UBgAYV))yp4*wrh zpZj(X{9W?F>aca)=MwI^k6)MI>~%UFDPb^%IQ6mKrCxnHtg#4EXIZp~>F#~@%h^q}Kcc5nRl$)Aa} zqxNQZWXV47yZd5TD)(~%I4_wc%`#27RS)*P+X;w_ zVqjMTwh4f2cf3AedPdKD8M&;gB{0!13_+ieP%bj;Ipx9wAZT#Kc(bBt%VJbI`dUa$ zw$Zq0d%&xrZbevErCk|jUrKkmyT8v@0qP<0@ZPWbPEd<19-U${Ts6R`Ppukm2mD$xH-E>v-CxoAJ zTVZ5M4&xVGRj=nc&~YPbu-QyRlz6)Zj{ZrHkAr}^mp_O%=BewvTkK4(pQ zqu{pE6WKb4?*9PJs5?RH~885RSw5K-K+&?n!ZHG zN5G3_%a3rik|Q9X&+FmBUZ)TySnlWFhV~yr@&{vsR@)aoq1{kqng-9m)9>&DWV=l% zr4zcKP9}X|4_le~X~0rXEBIbJVof=$r_Sg9B9cct)={-3AH*m=%ugAc^~Iu9qvD+df$b`FNVpwXaaZkuJaZXzK^aXn9EQ^8a> zEf`VqF2sh56E{M)-0a0oV@lKFN<_CJB3tF`FH!lYm;dz1@m6J2K=MP%h7I1Ykq^)B z_K`TJ7fu6$yWW`3Uj$tD1}jy`lDu_mzXiKbK<}(JgauClXdTiUzDjUE00E}HbWQ#R&L9R#&(t?~==y`$b#NdA-nT<( z_+LyA`tzzUcD8jpA{pT)p`^3^kx}hd#Jqhqoch@i>2C`x4EoQ86#_2%fKY*lGho8h zz{?@E1DMuxn5Lv|IuxzPo(Jbf`bkUElyAP z<0r?u{a9-`hCOW$u)O|1{z;Lw+dRvg3~lznd*q~s7|+@#Db!#P!IZw73Yg_Js}2Ew zM67IsAT`N zvjx7kRx(raVrk2&gZsgyiVNn}{)J$c;e&B4=V?Bl7xn9Xra>;IZs50KV!_cQ`E&F4 z>yCB`q}RMjpI5Qfl@Ff`*I3*0hzf28;SW{%uU$!Yo4txfxuS%cQ!j4mgMa9+VeE2m zS4w;q-&a=PL!B9$`Zt5{BJKOi|n9}cm@%C%jjn=O)39%nBv@7Rt}kJ%>8 z`h>Y2-JRS)Vjg3U(y>$1oyP*l=Ox{F>!vZs4JWed_2L7Z2K~Pk4!0uDOev#Jcb~sq zZ#pRRxJyf$jnYW7IUUKIBaf2a{61batoz|(_2cy`hTxp_IK^*3^qKp&wpF$iCMQ1W z>Bl6;=DWKO^4>Z+zIDQY1xC0-LJX1615keR|G5LFw#-60nZ_maNB~ifj7%{ze_@rk z0_-(p3f+-QlRm53&ZYkr+!Lu){zW0Z0gX#F^fCsubLY>y#lU+IaURcQ4M3$0z-J<# zSw0x>Y*YrCt}6Fs&1g8RHhRTB!O%J`PY2Blc)t~0D3G%lU0=>FAlXnXQCx^{b5@W8 z5qz_xDpZZRx@!{X0&9>k5*kL%ow8Jp`d?(EGQ@gt?Z0%q(Ge}?OTrt)phF*!dgL*= z&$OX8GM!mF84TnxAiYmle&J4{(oq_Sz&6bUngiBo6|gyvt9K}c_eDM>&hsplt-l%I zs^78FOIK?An_yy;O8))lwwcbC*Xu+66@}P-p-O1o^6vb~tG5FQ7K)pdbsH;*qw+sY z0g0{fP~a!&({5|Y=O4hdtAd4&#pm(Qfzx5mTY4bjW#p#%>GC*@OhYlzTT3%{+i^K& z^n9l~d0a#2;5DH)?QT zLx`QB$=0j7d=J??UarybcrLNkuw6I|QPMv~DrC?F?WB}11q2yU?)Bp^d$jx+AvtDG z>1Db|s@$lSi%>Z(wvBIlAW9Ro)I)Va{PlMlU6Oa*8Q2i&|GsvfnbRoK{LVG9-+<|4 z5>(Xz8D8DXu*^B=s7hdB>TT99L@ts=3>_h5nTO93>S#Ft>6P3s8k~{eI?KZqx@^P3&p!V2EM42Z9(ni@vGj zW_F_~3^K`l5*7wsO3M<1R#Pr>9T4y+NCe+#&QYJshZ+sNM&4_0P-XSMe*D#xQ&B8l zR}#pKmym(pUCr!OsUMv4*q^Id^wV^`AOS>f6_F)B~D?I1I%^N9xmI}B&@kb z%RjMt&toiIz%+quV!_BLdX4%?8b!c#PJ>i|4%RxI|Wz1~A6H7iO( z=NdiF8K=)iI1Z20HNU+XUxL1nSGBqFP%`%HPpr9PU8o#w$i9iVJhbx<&L-Qvfds0c zBXKBI5dLd|K;hlL{U+=sg&k*vqCT|jw)kIU-sq-n5FCoc#7GnrFR=R0YpY~wGUw4@ z;}6rQOMfXF7B2cM)e>nLl02&qZQjz+8n8-VZ;WY!{Nbq%0At#XMb+=>l;_)E4YHCV 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 z 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

N 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

2;Zc}fdliDT+rK1lSavgub&0m}z} z`4R6PsIdw{*xyeYC_0k~NC~cs$RQEXvRHXwkuG0xS209qsSYXD;DRnrftf%w{V?HK z1FpX3yPH1a!?OW~;)%UO!HHp{fya(P5S2qroK^jkAua8=KhYrCNuo9v#wXAyjPDITlqq&zKb_EKS_K^m{Z$KZe*j0w4%7J8{ z@G|73C;BDkU9z7<4zJTsk#ruFY=da@uWFLiO_nQ-nsvqhWpIOnq(m5JUj}){OvhkX(@uQ*#aD99^gyarx zM#3iPnn(5VUmM$HO7yAK3KTq^LPMR=@U&-m zL~+hrZr58+w=-)q*D@-w)5^njUskDpVx+8$jNJRA==;LSP`i$?rPlK7jim-8bs@(> z6I@{H$1U!;z;jhTP4&tE&=IxkZNiK+Fy))yU&i_|&h@A0P@oX#o;N5;t;mXLWHq=I zii=Rw#VSwN*q^_VL=jijqj(dud$z)j>_cZ${hMSW79wQSxpP+45GB1+sWg?DuluuD zS}CEAsaAQKA#V3aTd?T9dXpbHR?}VY5A6BY{Z@X8$X(I>H}T#$xetscMc)G^pqyzD zFyu`Z?XjEp%T$R;2OgV>Q(qg#(D+brQ)R4PED|Ulk#ITDJWdnVLj;}78SJY z5QUquEW`X18<|_tBCI0AujQsCIT+bHcO;f}W{)oqk4={9gnLw!ZQ^SIwQ>2VS5+g4 zZ%iwen&m@u*JB`TtoYrS4*Iy78V>ZqgYpeMw2Yhk>S`fLC)(a59q3)mB~O_Jns(Qj z2c72KGCR?u($leQyUq}m32FBB<0$~hc4#>}GoupBPaY0{%)9Q@aA$E&Y;(BaqG2Y7 zn?NZ#Ev?liZsweLYM%3M1-B7HR~b^kP;gVvhHrHS)kd61{zAJjQveNPwryDT*ui6S zg8NIeO+YT9Rfyp4lCzx?J@j_-Vtguy_TPRuLuOLf3%;;?1~-x7e%2N3dWARAZE56k z&%xu((_bKdem5~Hh&bT7<=yy^l`@=Mlm*w{vtDX#XiVNi7)_$#yWaz3nvf{&d5D<+=Nuk78{@ZuAk1ju?V_#1gy~;{O=USgkYay zjO^Am=C_Xls7i09slN18WwOCWbw~}sydTM^^eS0uejnX=*sx<9hd}FJyD#Fmd@?=` zC=B&;{UN6bo~Z>r3?}{>RP&cvtDIS1DjXf#`h+Zi`@83p>U95aM)NQAm(h+YjlUyj ztn}!Hr`dVNRjGx0;d`Ybxm)o2U$&!}wH*uNIwB)w^(v=xFpSy|72FU%43wOG&t7mV zL}L_UHzY9XNjkZ60jbfH0b7G#XH7`)ieSn|MALqqRWeVZtF34jveivzXa6%UB92c7 zL#|(7kvQwdQ(UEz6F;ie$?CI$BHx8Z%xqv&9OW`dro_{%!w8V%Xx-j2V6sA6P3f!? zc1JT~4p51UwC(XQ!!xNm`AoZ3Da4kaUzmPub!<~PaoqiRM*k7-cok1ITMF1cP6O|U zS+P5%oj}~wx9#1@gQ2-Kt{kiczXwXk7#zPVg+yyPDYDw#v@z&GYj4G{`LYNU(~U=h{0V$6S|%oFo%*YV~(5Lw`F){uOp4=YE{m*)e;Rg}ESVRshv&q0r2Eh{))*+NSwFfkw@8$$RE2I|haPlrZT zu*WoFj>=2_S~o@klk(IdF00mi(<4x8XTlLyoh^K);Ymeg_bw}(bD{A?;r$AoZ2*w zrf76f^TYcjj#}5pl4%5N@*|Qj%&Z*5`i$p7A)i@UDTij}#UByH6&ELYX+CpxEK>kw zr;)X*$~WQt`T(?}FvYxsNgMoIyvpueZraVJ?!EBP$Fe&Zp+wcD0C(Y!ukq1Zm34$h zKL{YfOLAXkPbHfikd}3JsS`&au=^QqPb0s151E^pb_E2;h9Weoi7_UDd_V^RIF=!* zL-|U?7N}0-k>iLof%&ob)yQT2pG_qQsuCfX=alUE3p1iWyJP~3jQ7_T{0@BvU)cYXUUEU z#O|eDzILU_4w&|DI=Dc+`QH)#rIeT3!qjj*^j{ZvNf#zY-50Q#-3T&QE)xBRl*@FX z+#H_y6_*jef4tTkdoRJHZu~M9|2uiZaC(R#E)$IjZ`p0y_)TuSD2RjIhJ%%ogrzFI zzPK^FnU#!Wm5Jy#;Emj$2j?DqRBw8K%QHaN`581==qukd5S*p^^^l#%9?uUxK+XH4 zkIY#287o$yo75is7?bn)0}opusp2}&qXf}oUr z5W`&Xw!+)t;~x1pd_q{CHs!v^$}=GWE^9YAWNWrK2)Y~>D)@4lZw zN8z=6Lbl)vuaSP%Of2Z0WU#ArK(a*$*o5!peAB7vrf1s78aOQ~<(D_iwEobupU~7# zb$L~C2W%O&DL;()J!rGPsfypVw1pSsce5~pu7vJKpKUVLmSR{!w6(tVN6PP*V9(FH z`Zhs&8t!`48sWZu6HA==o*Or;nc{oPHjoeWF#K{X)eM zMM1m%09nl^QYe%1(cFzvAc9d$9fo+IkfZY~Q~R||1F+TX6>|yWiUtR^7)v;ip%3uV zVd)3O1ARbp(AkKj8WdA%xRX-cGmVc?;ATmf8yfYY7kuv0naL#e@#XvWiVay(aH9|p zCGnec3>4h5n9ixU-gv_e#mYjiPY~{kTZDh;O0umSuh_>E#@`VSAM?J>_{T zX>_@UbOB^FmwS*WFS~VpW$x<)f@aahF#k;>6P5=X{)9umxB@o|4LMWYsp&XD~X zbzFZ;b?;Xt)gATs)5$5!V&J2T(LueGu5|2z+d{>MnVGAkrNBuF6b7?%LrbF=jrMzU z=ZlVhJu9uQs0okbSri1^E?mN(4~vG@-!-IP3WMY5R@+|I&NnI8ELViYD=&kb;bKLS znjVzWzJgpfcVtsDVm{+^zUz>*Txn)$J$;bfHP|^i>n8z4=almThpc)V8PtF{*X*<}))nL+f;?rr z6XO*?!R%~)yW+{^>aaBzh?Yk_M)3R8c$dC218(NGo693ucQ9YCeaF0 zQb?4+S;yVCT2&5DyI6GFn9)F2dN;044ko)GAXm*_COuL(j4-QL8U?=t-Mhb=+>oQ; zL1~Ja=#Jgb8XNaq6%_9wAl|n(cM@@(Bx#}HtDHAfaM1#-Ty6i2G;h>v&i8F<2ATJ( zwG03%0%9W{%ovIN`q(&{VGO7=^|g_b6fRrHhG72W?W$*3cq*r72fe|Kv=IQkHx!5U zEh(Gvg}OxEr3TTo8V^N0SD^Vckt-c1?h!s!n@tkOE2s`x3#n4C@}?RagfV+8NJ?lx zo8jKROFMf@f{QA%ShJ6D&@H!xqf&p@x2@1oh6CrQR9p7zBA)%eeCoO4 z8^S4@Un5?`D7MNuspT1)89p@LHJhr$HwUqPz@5rORSg=V)n=DlZEC4?wF5-xW`qzg z!{J=1D!St#HKMKv1x7s;3hHjFxUkhx^eNH8MUldI`ibjEq@zx1TiHWQTzI6o*$0bS zBFd~xLj$W_f*srhL!F*F+iNR=1?~bVj$A1dapiapC%(6KgUbBQ-3O$^a(V4@$y1qd zAL$q=e}ozuzPz;@u}@BDT{#0B>;-P3oW^{`NzFmD!U_jo zY^A}$;V2J-I4(T#)ECKov`_TS8}iqZ7RbX#tmX?hn_;}2f#I3}(Mx>j z@9qZZ+(4K>3v?H;w#YPx3k0m)>??txx^%F94X^<2Hk&(uw)rq~K$?~BdUB5Q2Ae!YKok@1d!Dm7OS)-H{QI=K0J{Njux$$zvGAL7Cr< z??i^d0tl)17o#cAzrs*TafH4Bhzxcb(5YV7gh6uC%vV>anr$}J{M;oOm|&%0w0 z((iXSDWv#j0AcGQIF4AE*Fz7gv3s16zsm^@(~k^8CM+bW)_4b<*tpcpT)>fhG+A&~ zCwL4y`X>*0-mWe4wXsH1kJ!NHZ-^oB=rM{2W!C!T#Hu+MHF@NtKx|&*DaOYS31iKb zhr{!ipW#WGOn=}n_*0z?o;8lh$ZkE>j(S^gI%Ht3rUwj6LvjCqM7?!bR9pW(taJ)U zcXxM#fOL0*bT>nXG)Q+jNOwqgcXxMphlIep&vVZA{c+7-b17^#v)8&mcdgf6VIhyb zu5R+7;i8I;7;_%Pzwx(XMkFSHcH)4Yjs{_NdK55Z*y;y~%a7FP{%t(voL^D?XDbl8 z-J0Utdthm`ivOubo&SuJ1W*yk<+vMdo){`o%OMg!sAEI3w6$D!9^Zm~={LdA2Yex2 zNsCirv_*MIRL$};{^UD6M*sG>wSDRT_^}q7RDXFRXuHY#&s)6>H;K}b{$^LkIY00x zem#iBZ$x!GgNVq&QjzyXv=kb^W9?gtNcN$7v=tvyMq@DF9E1&9v^zUCWW3vaL1B5{ z4x+Vcz7P^YmM2V8b2Jr0^sW{)K5)H5@^jvT!JN+6G{pPeKbMXRq%~Rz}{+r`rNkDa?uWk&eTzE;Kt|;G%hAwZdZzD4L ztM5pK;?TAcJp-rj_ACFw1t+++6g`0>rXbQ^#EveAD5X9KW9Sm6r&EiX_g$W=g5ChikpA4#?_H9v1Nnq8>6*p!@!sav2YVW6PP z$*I2uOe%3ryrqeN%qD*CoPVtpdXw=So<^Z%pp^%Z{4tr~>;j5s$~+%cZ~8^1RLN zk?fcA5ud5H^Q*-Qt;j67)mrM27R1kpoE{60wC19E%6be_qf{zMU7{bwF z4=gnPk~0}DP}m)_F4f80g-E4|_;naSpWpMpXch@K{rI@f5fd&S68eQT8wpiR-q$52 z^rL}ZqtU3M@N1plZpvLbM1UdO=eL&q@i@+6R2V#S?h3@jli)Aio~$Eqgad>yKpNSu z?GxCvrdi>_kC9Li064)ii<}LG<_CuuDPOXu5Yx;}ZEFfQ?p`XUq&%PwU=ENP#)g=j zudf{Rrax5$OYVYPkq1(<)ZsuO_uqa;F%agW&lH8stqov;Mf+HGfVq2iq8olvXQe6T zl0Q6N(8(GC@{pK-@d~-ba2m!tr2c%PmYIr zDET=inBa27JD3V;fGy}=NZo0cvgTt@<3baxh+y>UtN84vZ%ROhJx7Vn z%YeVsF~p*zvM$l21=T4h4rr@p1GF4~wm*>4eKJm(&gitgIrNK2`rpA^A zZ&h1`g81k#EpQF}%2er(1`wtl`GnAvx~UTbv^pVm)exY!_m9G|Xo1#sE!2y&EneCP zT!~S0&4`z*SFBeC^a#;?Rdr#p6_;ig&P|4n;xe9L#KY&|i2^vr9tu8sK8BEx3;JJw zPT)9eHPuGG@ie`!me$@u{zlnt#Cqvmm6#v(xvsLQ9D$c;j7*4X1dpzDEruL-@w3qPVrY)16 zV!ay?hYqpVVQ{15d@tiBxifr!*0fbAOm63of-wps%s1Z?qp0{M^3e#Hegz2l zznq)2q9J2hJmYPJVtw+I9kKWGguOuja6Qd-hZy1acW?NZ{TC+(sMs1$6o%DpcNaE0 zeMf&U$uq{j1F(?-b+vV+4b#FDH_`Lb!H((S`ra&LiKAbK%B}!bOIXnF=6Kd3M;ZR8 z!z0>DYCL7S8Zhugov)c3?r>K81n3v16OKA)1S-FEan#>tFF2v!UJvXLMExfv>Wlyf zK0h@I)L_JAv<}H5F#DAnZrIvgvR3R#gG5O`=CJ1SM`1h~d;|+Z3je(#cNH5P@~S3) z4a$nk@IAT1#n|6DM)?KCQn3i=d=${}{`28em{mQ?p8C1~Bp_h<9-K92gi z^$(xCI<+!dby2g>4)HL90*Y;y>(A1DM~De_=6ji2j( zv&D2}VI6zQ(xpoQ4r?aay`2WS{IkRcnFO_ZjI8SC_WSG&ARE*S^S5g$H}vf}t0E?A zTPCB^^TUzeoHU6J6~wjcO^oY(B)r1dXw|W39X{;9H+5@1EWlo^+d{@sjcO;RKfR0@ zrx&a|Il{?MkApAf2f2G&%E#3v12$K96!vKFwtK=*(v@5lV{N&TtRtz0>{j~^IJ3Hh9D0h`i%@9DT5_!Lj~m+-sS_z=uyw$wF@ z)C!*g>FBg`mmZ5kxKRg^?EUc& zlNA7%)ioBlaMD-*+*Jv=JP5E!cy~-j?vLX1sQ1OIkX5`sZUM4?cV=lK;9N0qS{{yI zA6f;-KPt@+EY)uI_Lm)wPa_2L!`w6ols<0TWJqcfO$}LBS6|6@RcofnDdwjXeWJRO zV|=`JX7$4){eZ>$5KCS;E;Lm>+fQ(FO zxOjj0%WF)OnD*8&7g13-J2Q=FBL)jh3{-B$~Zo(CIu|<~u9{Poyl-2{fTO^Z|AB9+`#r^WFYfA?pxveM_OVLfCE`R*O z*+1J}T-k^w5i{b^kx*e9vGn7Lxox6kDwuR)v7{$yeYpd>HelqBTHW6=VTq@OqQiLEqKbia@4w0qF67#k!a% zcUvAB1D;%q(dm@!>#MuZcIYqZWnbDP041d|q}Fg{rm%Z@S8BotYFPaKxL{m1bMele zKSfK)V*liqmR73%Gz`iNOC8!J<>WN0`yH(zFPkJN(Ca9TSKZxKiI4>G8ZK2U0H8SQ_~yZr}JpvCxpB5OJIq|R*!u;=l<$-?;KD``qPM>pyk{@ zd?WPqa&;>G+;O@|s>|WTE(l*T0ARoygk8@(%=F16XB`8Mj@vf^i~u$(T^-DDt{*u{ zM-6mfRggG^M1)6j*0=_<06x?i;NcUdfYE{FFE*SO+OOf$a5aY6JF30KmKm|R{^9=Z zacgP_X!6ovEpG`HX7b9!bsTKRk4h(nGc#I&<3CYi0K?^~9;ql#(% z6V!uNYG+z+G~2*#A@s7>wQZ&jTKZh7uD@w|NHN7)BdUTdp26qFQ#e;2QilGeC zd1_He_~`H^o^W)$XGiC?KCVqcOuOWLV@j>kTd(#e;G11qiGb-vaM%kUsNy0V^+fs<~JvW{Q>77Z#!%tz!Iu`uS3)3NcoA>yQzmY$27q8Xveuw1Zpc63=pB?D-9j-Y6a&!;G0s>A4wfNlj zfDzso$dLgK5r!Bn+2lVe-~lq@1Sv28h&RGLHK~1SWrs_OPjyK@O0cyV-)mhqj{^yji3_FcS{-_0Heciv%zQ5&ekbi%*@Q->&q8|}4FgG}ls_?4mk6#-%mF9IlR8)ktz?NPPkXr|YtAYLN0%3fg#A!m9$A6eJ3nxncx?2a zzmfyVOfvl}Q2+uXb$8>k^rs!bUz>4nm zaJCFsb^ruOBGV3OQj|Krd(C8#DUWIP0 ze=gqT>R=$wdZ))V+h9a>-8)N0>CH}JN1sfU%90YgtL&AIygM41t=M2iP%fO3@3mD#~tAN-| z2>0BY|8Iv)k@qc{m=v_YPA`u<$Mv9FY~R4#xJeg}0jW1oRD~U(;GMi}a#KsK&<=1S z!G{QryITN&z6kTWUj4pW$Qo+m(595n2gV-IWXGG=%fx!33G8`&jr%3O-pk(c?0&Qz z0OubjAg<-Lw4eGDT|S7x>`L$(Rw+oW8{zJh&3$vb3QVM?CKB?&!NFtamB0xHZX+Nugzrl8+IVGYD_b62oE?@1ZHnRGYOq8TU??7MUt+q6^nA51@5ZjpmfYXIv zQ=U+DI^nXD_UU{M9wd)={1%HM=y}7zScZE2^XU)ew#qq^K`N7BNRRDO(>TxtN#> z&9`lV&i@hNZ0YyrG`*;FuT;bfeT|GjN`}3ou^-?lf=f!7j?7G2K6!Seq**0QV({HY+ zU}zLO46x~@S_7jnZq+W6BQSr4VH#@LVn!s9*qea= z&QK!Xt0B}z)aHzb%49nj9839(vUAh`aIm-N`tsF+0YnrZuC-G2g*>$d*hykl^rW@Sen-!abW z9%d>buiNL$*T1)uzCELre{BiYW$CQnUM~&(9Ek0r#7PX*@wmeAD2Yv2fe<{HgBjTUT7vV704HNh2PECImM--ftg82R_ z!qNIyEZ2?@+FnQ`4ThzB)+jTG{F z4nqcr{>*K>v|+%)2=sv*$r@bO1QuW(;Yqss9;j_7fU}EdMZMl`Bg0~Re$f6YEn3^@ z!qsAr8ZvD5YHzNfZq3FhY%@1S|5OH4Kfs?P{mckjNYPw;KQ(+8W#oaeBM_V#1blfs z{2A05)N)%tGWK!s2($q^FQAfzro?Pr@yPOX6U;gK;II}37x~j{(q~tf?C$lY6Z<_@ zmpLRiN3*XGWBz)p@_+TYnX?)ruoXTP>jt*XaP23SIcblJh;9|l1va;vA96Is6&EWw zKh?60zA@(ILtn=$AC#QxYBxPT4IV&IV>N|Q&=<>h=D%~EP*9F4FV-T-Go36sPBByI zuJ(x-xK<^`N5cxU7);Kn$Cq7V{rq0n*5VSB=$@2N7%w2XIycQvRa9d&egPO5Bic2$ zZ-n4dNhriM(!IYjJO)E3Nf%IH~|HS((A#L0?lC2@85LtU9jV)+#brUKS` z+Zt=4i_f!uA|lA3ebzBysA@`z(^LF|3tE==cQFA z1?YtKcZ0%|Kb^r#`>EPc%ZMHLzYbI++~B$JcX&wpvcHV$4s^8q`S9BAbjs!Y?fMjf zz%IaWsI>l+NYKw2&|%)xZ4hPY0RXJDQfn~@DD@&1=2=>3g#06=0(mn(bb=9$f+@R`-NC5bk z7<538eYXn2GU)KB&-HQx0k$czwFz)5aIk1l*4w@ES^Rl!gD>CIz3`Fx~XS388Qe?;wCykJpRffm(6YS1VE{{J%GgslK^e98xQxj!1A0dwqhS&!ev`(H@zK}tnHCUxdF1QQjgq1PB zIJdeU-TJl^5_y(~jLQ?aYbeBm0}L&`e>MQg0f5wxfQ0b(WwY}O_;Ug~$ri0PG>%L# zgnVhKjpgOVYP&n2YYX-=@jxkc)UKHM3lH}Wjb_*jFEi@0EUeOmw?}m zDUgB7SZxJ-sNS%l*$S~lf|Yib3v9o;D6UbWJ+HRVR=(TSIHz_E9lX{8g=#yKJz=>D zqFSHj#Pj=7D&Hc+@8j^&k{pvYVNS_IuQFf@bE%NvF3BKM59R#zTBX2`wWYJ7g=82= z&|II+#wsoUM32lgx`I%HMQ}@7xt_k76<at?8y z?hP{SPd$NCq)I@JM;g}*&Rj|KtyCXfP&Wo^?m@d5Is?$ysXvBV#s94;BbgBSCy$kw z0zY5!s9q7m=h?1C&4ZVFjuoe*waLxmR^ziDu4#$KrL@>c1@aZ;Ri^ng-Ix8*hf5qY*d-&s;MCo0l4A8>mwE^GE zcQ_x07=D2Pn&_CdL zdr$#v^dfm*6+>r4Fj<&6FrS2>zOI?wy&jCOUO`Y)I}I6uy3T!*y#wWeRD*gt0z`3Qme=~= z=d@ec6vy1z2J{Rlo3;)8NN28qz4-78le!nkHe(37t3S2?^!Wf{r>N{Cm>*bckn6UA z2ikJ}XhLu(eYteybFKdGu-GYaAg|t~`RB41?%{0x@_?}T@6B)n0WzffWj4V7O@gtr z*1x;^T=z#aS8fvEZF~?GH=z(On!CPjAZ(3`GqKO!089%cUM$%_Sdpfz^p`pqaL@(h zu%-ztAySHs0nyMkV`QZ#R-1_6+fv#s{!O3|a<`i5s8Kk^%s zOw9qFr=tABQ#?dsl2Ox=-mKEo%xp+*2j2)I@of|$0Rf-0uj@DFzN)S1^o=fcQS2_M zXRH24JIOYQJM5}pfFgSnK?{rZYq{(q<;Pas7DequrY*ffiOA4tb|KjuxBP5HS8o zz;N!y_^SIiV?{6|4^cZLnHncDi>Z}1^p(tZZL$4EAgu}2?q&`MAHa_xD52(b-RR2o zmhFEeEhhD^5DO)DfPBSRvZtZZW#ezG(UO|EI}oED-~~4lQ`ML;*``OTqH#iww^9@o zCxdY~j+ zorSICK;hh~*O8pl?uVl#$8Rd&@~4l?bJE(y3Iti{x{jiL>K5uRp+8HR#PDOqYk=wk zF30Mc7W7JpV*#VxXXfCg>NgWO zL?wITg$Cp zib9oYs+(lAjNFZu=^i1K;%pB}t>dR(dk*Fcg-N!G-MTE!KA5PJ}gf~hgPyt10HHCs)6ROzIEt=J|L zh+$)VyM#;faix?{%AfG4ky#dg-KJb z4h=;lCMvQDr;XQaD;Hl1LqozifahXwaQ<2U%7R^NVv(%ItLyW1g!9=qnWeXfM>g z)h5JlR*88cV5-(x_Rfx_+~;hDE;wEe0T|QAoHB>2 zcOm~z^(b%=p)0*!ZIHdP0Jq79*I84B;%jSr!BAx{HNl|dzbqQe%D{()?tMbgl_Y^p zk?+(-W0Fx|in+kO{hAYygZ8(oyyla-TxDcT93Xk-uzHkLcy}#$J_lX_o|wL}v_FS@ z<6nw-hfdNJLMUBf?;J^&(UEG_f87DnHhqVS zeWsc~ET@+c$Y|^!CpAgLWT64ZS=QxbC(rqhPQ3OXucZ#aZFyJ7^kscPSkRPvnfy-( z?NQz4bk^2*%h_F9eLZnW#*8N3*JeQOoQ6tJ0A!_Sk2!K3IbOX3J5pvDsYxE@xV?C_ zXUy@TWe-2`96veQT(=dv2g@Ql;%K?46mS5moHQVs^_L~pVhEHiSs%$5Lk*-9Pr@+2wtT5xA$~_vgsKQc2*V6nY0MRb(2gl-^rU;? zs@0Wd*&8s!>7286ZGSD6ynPIaiX@#Bxd^LMG9D0{-N+^&XtM=%r8!+}p_s>)vwi*= z`jT~zu_|@fxMVz)%Ssg ziCt>yEJ5!L?%xaZ^jFCy)LtLDZNw8oQe;QQ-nO4I+Rgn$5sbzv)jIiWc5L7*gm8T6 z5=3b|k|8_L*~Lx>QQz=l(Jy+~Cq@iwY$hK8tFgb2(xX%jGJYc%XhQ&+3w{|kC8=ta zj?Mp43Dn~9es1`d+!oB^JuU@jczbmoRTkx7yX#W}z2jT@jTWwUm`4owd?4qg}Bv_+mHEQ+qAUOc)Bo$0LNEMhS zRkxQmR2OzYZ&~8OUAkvp%IX3iiE#IT8u=aO5Ar7e#cxrz?yaaPfAzs4%Ip94R;&e+ zHVtKNU)YCn^?%{@H?*&9k~hq_|NVM_kJ)K|)P8wjANaog-#^?; z_vD5!rn(iP|L+n4)5vctQT$;Ke3Sk!`Tgj?ez|eI&3!@jVN0%40>=N=Z0v;Qx~${paOkx`7!Q ze5CjTDu}Y*lsQFNMfpJI_@tj_WdX+1UIt!J1;e|7?tJ*inSbTjdr2PZRv0zC^VLpu zZWCik&Zt=1=bz`c_sDbVbGU3WDsti&oR{nWcWPUp$E6ethKDuY#zCRDL8TyTfOkz^ z3^uhMonpIg>U|UIpVfsn;uXXu2zDnVs~(hC^Wfl_Ht|06!~8VJxN9Q)lNz(rxMgLsVNoz_ zvjgcO_)|YB+T$d{`G&68xZ~wf5)uXchwHyz9_pGX-k2`K@?@`tpO{&uNjLLV-=@1$ z1M6M!Wz_?{E9Tvr`MIND%g^_rFQJdpzz5MzP>uC+{crDg4r%FHoEZk%7Ss6uUDD3G z#U(>qUegN9n=pnk{cww^dt!3ABv+Pg!uY^C@I@jjK>7vlLa9!P&Otw}!!D6_3j#>QvgesO3C2JHL$m zQpSwDm^qM9IqktN9~mn3J}R}|ACPfqSCP0c-ax6wpunan*$t=lD+*UAD{@B))e{U$w78$KH~LvS#J`Ub0c?Z?Wrb{B?L zBF+Vwc15gV;xGRuz4pCSod11bphPam5Ob#V`%huKUp{w$Q=@rsjet%Syd7hvCmHI zn}J|XQlIJmvD^W#cXJ#KQ>>8vJ`9>A1#9n^r5__%xY4V;JbaG*w(&oO)5 zODngQ0`QvUm}Nc~S)^nI*ceiUh~oul@FZ1~$hyVG@X6VlE-8=`;^urJ5HVV#P75Dw zsga?+9F7jjP1k?G`KqR1EhT0&MzpQ_U35u-Zs?Qz3wlfZSF_e1W@7O1lZ$%>XJv1o z;_Vo)@sR)5T+03I~DbiPwbm2;zSuJFx7r$v1&uDHl`E!o0r?B>&e5K)6L!0orO-h zcorSOn}KS0a(qjzC-d(U4V8|rgwLjWWFj|GqP;xT*_{?Qi7{kx5JiF4c{P`Cf_cg| z!rvx_et3)Fh#TL-&exvXW>;roJ2(;{$S9_ZcGD$D5mp1 z#2X2*d5s`XV^3s_zr4ZMhHQDXskL0qSMs}?onm80giFodL&r*g6Gmzm4TryI$`kK1 z9p6A^SmQHJ!leUj0*)Jo#&^ACT+C+~-|a?UPHyQbP{tvzALi^82#XI2TJ6`|Oku!WvpN`|4By;fiyKG7$A0`|T~Ra;P?}#>qD|=}htNJz zfAyPFemngVWcB+PCZmd7K)7~BZ*rc)!OGl^(DH9_yD^W@X9$wbNX!KH90e{@s)(_` zmGg7nPY(n)$iK36+W36ck{0m^2pCk^EZ15nq}8VQu4wf&rq ztlotJmsy-4<*1))H>Q0SZu%8Z>PvyM)B#5=$E-@mYduul#`8+19v1~w(g&bV*nUy& z!&l|o$`sQsUrVw5<(bD1e@X0>b5VDiIFns=*O=mGvS4H9=gBFk2&zNKzq+I?s8!;A z$`9ZtmI)FbkEqgwrQIemB`vKzMBCq-!aR@)7iFMC?N+*2mZSXN5-`;H5l5&RtQOkW zmQ#TeRP=q?R^Sd|=#$}&OfLTjh%}pb{qzCZL0G8cr8*|nP>6zcjq;|uX-KsmTDZLQ-Ph7@ z88?ej$i*@2Q5zh#y3Lml9M*IKK7FV`MTE#O zLkhTK%?C1wHd{!E5}6K{AIUM<-=QdiR6NCoN5?ky3S&PhGQ!7$m6YvpJO2$+M9;s}=O~_3i427U5cH0FsR*Zz#B^2f`7F3XH&PVj+ zvxpCeL?;vOIwHu0eMP4c6x()Jm`5nlB}qe!S}+AtxX{S2s**b{HrX6FZz3s=Kk;yy zF}cchn$0Ke=4d%evTb~*n{Z5nXU=&0Mm3yx=g;%_WirA90*&p8*M{z9Fwt8@z$+3B zy-i62$zw@fpXtPQZ!%!H6bZeI?kflHt9k#FKvtaLkX8QXV7WR!n7Q<_sgfP0@JyHEbf~58{JKr#?_}J+v26;5KnKem0j-T=Xc_W+KHO{&bWD1FOVu zNEq}Q(9pj|hrL(@@4M5|s8tds&CUF@Rp2DKLc?0&DS zlxgD;Pckf#?^h_UCVYa`ug3B#&d-Y|~b1H#bzem*zM?&S@dnh^Oc&|^yYCWeE5_N&Q)9ejwX4Q$kq5s-PF zg8a4QB&cs3BT0!l1I)6BowW3R9(^g{a8g&E(%qxlxX?sdDwW~Vhtc?Ao6KXc zB{dlN$6svEJfvtIw^9qBv1JijA?`2`B4y0*^G6P6Rk~oiAE`veB#}ecm02(M4ztFj z3~{p;Bl6!SoQK{N{3e2`s}VYCDS-x%RQ6e6=HW2n{N{zTfc4adm^(S5U~diN9GR?Z!vp8$WtpF8o{LvMO0e3+lKMObWH5Yzs`a^Z;xdAh< z=(ad?wfr>FgHZ}7v!0Klwx4{WJ4D=;^u}J9(bKB z4n8Az1R(IW0#y1r4T#wex1&hhzIySa-mzD;tNbn2Kb-a?5P2=_5KNJ0wEa1Nj} zG|_e~6{u#C$keHVg~4|Z6#))AF^}K{14W&+lOMB-wm_r$091wy#Zpihfz49B86Gf^3u~yllAV%qLM`pt zIg^`hxtLib#A2V<%FHUrrJ+GB*=ZO(W-(T;WLrtBq@9H}5O21`>)UoxWb9z$nzAjY zQ5q`%PD3-btXxRbR5V#B?V=B)wjg3=0ZWw~`RW!LDy;w^&(6=2WcgQomr~86Kx0Zg zVGk^Xlb4poi^vfM>Xh^4Th$+#8s!`FQ|y=+;C}Sh8IR8%U8!%vLjP`B{)#k6(+r>t z-u~34^-_h#fH4edj*jC3MwS*?TKlBaKnDT(KSbsxicm!TxS)}i1`kgDkWet zxM`@~0KFte;+bA}Me-##M(=4<*%B-vVd5qt8vTSP8g$YKDo3^#)R^at*PLB%Kj?nR zS5T2Wgz$ey#|$Y{XXKt0Kxq`_q>hwxOJ1~=rMvgqXZ)qu613V?uF$EG{HkOCfp_Dq zF%aDqZ&*4aMAuTPK!Fe`c^DMr5vkXufuw?2JRASm^as(oThdt%#1>;2e{v@a!YxMK z^P(5F2*o_`B-UlK5dy7z#>L$$|BxCW^<}ogu`80C0af@MX_`&JTR2&Se>aZ=TrB42Aocn_}3B)6jCdrkeDZeLH zFOTOia>ecWGy`fg4(qt74%&OxBBqpt4|NaiaTe4RME&$H_e7eax6K;}4u9w;BH(Qi z!IZ>XLz2zNXkL1)2{Wjl+l`gzC~pWY2sD{ljyE3k#6g=8WVj0IR!W z*eqey#RXBkfkvk_U3RPARxLUXV^9#xQ>2#NNG>d6G#w~&;nEEN25me?t}%3jR>?^O!1FC^_gQtJO_W_|2kJlm~yU zj1VmjHW;NekMya6j~P(bJ3N0^5V^={YNAMP=#uBQ;&{_ihIqKMa_Yu!Uam5;0FMs8 z6_!6XX51LsjHuRK5b!B7YuHAF|E;NWWZ`L=T4!IJhm<=>E|0RU2ul-uSv7Tpo$*MB zx@p(|!TKOcv!Cv0i58HucINsLY(?n5_Rhd?5hE)yvi2QvqBzLY+eA;460EsmoJky1 z!eY`{5hYl^(%4!=@?mn_J%trbv`t|Xq{22p*LMkC=HFNoEVW&9TZA?c1r?e1_t}4Q z9n8x%kDI3Fn9fzGrw2MuuqKNM{)ZOeoEO(h_!x_Rr*5`%vPM8h7=^=$HPtM{$2Ae) z@ae4o?Oy0Fn_Ze1%m`~lGjzvWu{MaE!^BDK{!BM!16@_7>gvUd#G?z-2<$%6EEtNk z0j0OrnxcWlcQ+H)`hWDmwloZ+l3LiGU32Q6XGUOD6-Nz&f3@Ow+EyGRar3!|ySdlD z)QN+Im}x!8IB6A1py`|Ap^{HuxNXsM(1$gkP87}a+Y^#I=;`pr%zU*TRcZU6kaHC5 z-Ln;bVI5X+g;JI1?+Z*L>D~5WQDiEDC6IEsFJ@STjU@=Z=t_aq-d zmKI`@){4j+UR~#1>Iz&plk)Qf6H+%O@Z83yHxssTZ{96vt6ZxcF^1oPB}TZOD#kZ^MPgP9d6 zk9gcyQX|B9pF=F+cZ*q-3pMZt{g~Y~iX*zrLDY#sNn+rsnx8!Qv-*lqmjZuD~58EJ+-AHI+E&Pv`*#pxQbj67qdM;>TBQr*1<- z@J=$Gdk)mkqut!LTHf^4yu6vZ3nk|yy>^u5 zf42LA*}$>AjH(KY-*9$r0SKw)8U@?GUjtT)VRHv|?uPhtM+&wAD5N3f6SR1}nQw0b zu8Sw@7tc66mU2uG-2oQAK^|qKOp_`r=kwCXX5WLh^r9j0yZbqWB#L9`7hr;m`VZ&5 z!l-WgDvK5V-CzEs@TY;uSchCi4OxJQne5$=o#9_U)HuP ziuuKipSeiyeQ8Qile&5&l{T(->$j&PyNBxJ%4Z=kpKuK=XtY>CDXsh0< z+i5$o_jRXuHc?&&9y=Jn&Dcvlh`WsEd1~`j|7Gg9hB~QZqC1N-KS`=xz;VL|c{P$WE>CXCv&8aQ z9cmOA1&NGwK!Or(zkq#6(!`vcSe@(Hb&q!UY8dHG)XedgW*dr!ICBP&x3{kj5syny ze`kK-ORQEqM7ENv$L#uAtjw&jW-gt-vYMv7@sZoq$fT2$mH1-*thDl?{zWA+Q_Z07 zVb`@|Y`)Fh!Sb|v=YSMD_SD8C^ta(NTKu4iB!}m_DYLuX#&{RLaX2L_wop#U2Po27*)+0r>xHM2l#_53{pdOIfB z9pZf}#l&`merNPyOR6w>R1|(vk*2rpo3rn019S4mgVvGssy;*vEVI{kcDeZZ%I66! z4qkfl5(9p-!GN%mRNRaOBwVDyNq(NTdVl-l85Cfb28U@VBAn~=bG|aqd;ZVW-erx4 z_toB-k$FILagTjvVHKa?HTtX$9>h~nX7uM+gph!dj&C6VhuE06LJmkE-q|NDcv3kl zediGXJ`v2Y>qi1&*M-V4o$ZXt8KvO=2e1EhYb4y5`uunfYr_X7xqLuKutW;*r zkA=}Q&3gBwL(wMVx`{vF;2!y*t>JMB${O5G<}6D zmn*MOSE|ug!amX&IMlf@>YmgN*H1my^0uAXrBbzdCvXKeT0^YcB28(Sh%-6pJ&5K_ z0abKBituBVn5~D~aeI*qHbtxn0&TU1`|q94TrNuu1@%DN=KbUXWdqifF7i_NSAPAfA*Mq0njP{{6nCvQ;UQ2U#TaK=lheb?VTR@ zFiSP$ZZJ7VaC2qbnw3KL>{RzbRD`&x4S}DTVqhddU(jTg70-Pw&v+pfFyjaQ9aC4* zQjOQM1x6aq8VhSXQ;FCAZgCMl0Uuaz9_h{fTRSb@yb75YKI+sED`tO($}!E35W(X^ zZVgk<`ht(IBJ--^25IpfPH`2nqTR3}%mzQmU?sr2aI4Wj*=7JR_dt<|eR#pAlsV_r zG5m>JuUHZ1yDBu{T<{%qF5kQ+0zC5pXX2W%lqq~<3gdf>S{m8?)3crJj|Ho&hI_}< zscUMHvDCde6c%w=Rz+z}K@r;Jiz2%Daz9(??S##R6GKEsQYWqnm?_fYle7KD$0bxF zzc8XEmQ#EkR_jkc_^OFrjcAW}48-}tV)6hOn==6BD6>)UawEe;e=EP^Xf6F6gi9J%b&n?_I*g~FC0kLTRpueOgh=<;d0Q*acgqu-5Y_F>LTeca=a zq;8m(0+~#zludw5mH->UiV+nH7X=u#5CAFvd!df)JLUf6Qv+d{nX(vFd!bay!?4n3 zj>8ivQClD^78_X~1@EHfd6oAs3hmQ!FdzH}^L1o%*p~YC=Ju$mwCIIy$DmpLI*+N3 z42oEqg?I7ppB|@(SuxpTxv3`3!l=2qQe*MN9$jh$Ue$x z!C`j1CU2?H z#P#W+?uZ~aOVov1wLc$0>0~MWQzQFl_De0djSq_UwfZ*)>%x3A;awtY;r*>AO0$2E zmlKK1k-tis=xlL-V8O8aMQIGWuh5X-586?Gw1vZ%O|uyNf?o?#cJExkG7>6{Z4^b@Y>unc)d^=$80WM%yn%17>moX58YZUgx-F}R*J zVpV!?i$C4Xm@Rn+6B#RSuEYpcSQtA$e`*xto1##2-QU!65`9CpX>V&6Ym@nxiVIN$ zT{L)mZ}ITzpIbu~aJKL06~pjx`<1!pmFsngpm-p{5g^p&@w8%9{Q^EofvDqL?+ea7 zq}z<|A88w9yq$L(Z3R*n9^FirYz1C0U37B4{=O*|=}=?_;8zkn)D<0t1qWkq_0nEc z_XznF=dF)h8GK%b)Uj+B=;!U@O>v#tTq^6F)wFWppVt%xF^TGm6{gc}toc;u&%{rmU3bjL4fxmrsv zKj&TBiek6eiIcIY0pc;-z!9 z7d=>#x2FxocPBM&hcmY;+=HvaUjeaknS2|0%2q~@!VQxWj8yTPgvL_zc-0w-w(b6X z@#4iv=2Psf!luDL!4P8bi;xXQ^g~nr-JeYSd=4q?g`;Sjryn&vDn_l&d+S+C|Jl*4 z0RJKL`qH_*Unj@zdn38qr?+m?8R(?&#rNddn;jU~`i>Xv>-7x2!IuFJ)n~T`07VB{|o(v*FP{8G73Wg}%%i;Cj(VtfV$f4xce*_atW?IhMSlj#TELJoq zZ|e+B`HCq8-gjkORQo+H+c@iqv+Ze_iz*7X9njRNogM!g%%i9JX;~m^&1porrG~*Xbme={rl%698{${C z6SJn`RFuVT))ywnCXdZCA>}M>wg5Z8W0K8Aaacuqgu()=({9Sr^KZ|;%JZ18I`4n- zcB>Tc2I_6L*7o1VDqn~Qzl!E7&l%}wZ+Z@D`hEvg@r%5^0D;Hk+*JrbpR;yA)yjuL zBN~3~S2K&7hNCcPvM1ULwtrXo4fNrMNV9B-Aww1af(MKEeXY$}_mSsj$Mp@nw&>eL z<8wmU)6>ehlwC2o@6!+V9>u^vJxAJ8nLZ@LP&7F{8KeQvcz=y8p<_g^^b{%PrL=b6gUW2*^%-h; zCdJLk;PF=pvs1U(YWsaLEHlKtkhi%W9UP$;DT;X}J-C^79bH)!_dM7>-JleIk2fIG z_eD5%=QhG$!iX4zjpX&5=V@OpWza_ucrTx((WbDu@IM3ecQF;RuzTGcEo;?Z@b*=_ z+ej0FSIY8Gy70C3*>TjkUskdr_GQOV%0wsOJ`*<1TvmKpS#)}z#dRiZz3Q@kJ<~p3 zRe@h=Dk{oY$$B@VAoyFz_WhdBLdUa>c;;fm`licR2V{!+e^)l4haC*o544&@v5^)_ zYtpYi)yLGhL)JKx*8mbw@;0adGmd??PwzDHG!qEpSPFI@AKEJK?kb}Z2|N*eH%WP8 zE2iga{1H^~E1O&&_)BqcmT0N|d6iNB{^-F3*TFR^b+M@$gI-f60HUKOet`Q1+l52@ z^mGXvFv5(xDUJ>En3VTyt5|vb%zOM|hV3uZ!RiQ;wC633Uuvq0{t|7;@7w|4tLf70 z@z*}+FL`k`6;84%4!X9_d9Xqn?lVm5M<@HFRkR~!7qGx=K{T?HuD)+v*mh&=lUzc> zT*z5WcRLSO5?;;1d)Z_5pSd!bLdi7|$4*Ij-FQ+bnv0R-;&kgr2f`T*l)F}H8SL%C z(|_;Uj4XYg1yNoF2kCIr&S)!6!?x2w%NrgW{&i*vVlYf86$EzlQaFL^7Y}0nG1WH8 zD^w@5KDGD0!Lhr}Tb)?FZVvp;ql5Vxu zd-dyQ7VKfaW*?Y-as1+d)i3Qe0-B85K<65dro$cLeT>b~!mqMwADYORkRW52{Jh8i z5?y^GmdDMfKU4|(iRYc%;V{yu3(u#Sd6NcgaRo+oBZ&`aYwXEXV8aPi(&g-O^JLjI z>hgM43Oj`WjA=L*mq~&lEVf&9gphw4&0cV7={R-VCCX%HM%sX4cukuboEs`^crE^! z+FRQW=5ug-yFxiIx~ia$ak>G{iS72uDqCOQsIA0R{C;iy(iZN>QPp-d^BLCT9>QQT zJ&#JiRU@XoI{V$qhajE6tKm9bjh^8k?U`CwiJ0^BS)&W3(R#|<+)Bm7JXUs`6S#+t z(DVz^gY=mVb&0{^3jX5Uig%%7MU-)zVF_Igs<5@+g7yTU>hfRHA>w2I*W z3FK-g{1G2geG>6wZnh_=7Bx!x$*Ochi`1w<_74we}e- zk(mrz-I)hH9XA3zi+6o#ID0r2bER~AO74gEPcFJAYBq3p5a_*@&)`mD)l**j5Ls{x zmv51W)WVmVK)r>U@V(Yx3qi%7YW#iS$IdEi?c~Hz$KcEI?J*1y-MCV`B8@6bamt%=lcC&!KV2el$;ojy5u^uWYw)L;9D`pTvf|VIGT1zlGN^$-m+`FEDwkg4l64Ujio{8;{4OLHu(- zZFjaoho7Djgmxj=3w}fkIc}b;?NtEIN+O5~s@8H&uCY7oG%4-Xw?R93Tt1y$HbmAt zYazCA5@TO_so_1apTIa+5nE<4dd{cNMr7*hEH0eOSLX|whCC4L%JVJQ3a-kR-FgGT z5ewu$5l;Js#f->`L+>sL?V?XC zR=C_Jjj_=b^I4@dg4(#gFH00{#Z^LwXAFf2Du`+-X@$?-io;@*Im#*Gx{nGjf6rO1 z(mHskavCzR=)Y(}%*8w`-7=p3CKa&e1V`#=rx=J^`X2fVM-tv9g}diQ_F6d(&hRG3 zD8|-n^2PQzo1mFyR1KN}yde}LqbWOKh1)AvuaCI%=>t=oXL+$-#dNtw5Y7S2Qs<5s zxLy1HMtL?C{aCe@ChgQj0NulE{VFzKQm8#{M1udc)zvPOT6!1W%&R4p+L$N^#|f@d z^kU9aGN&c;3?yTX5(ZP-m4y3z=OB;dVd?v;T3V&V3=ZLh-uzhWjZjZtnn*{^ ze3ciI@m-cgGI@WGu^$C4CilXM2Cfc@V^P)SUfxUy-qdk45s>TrjnnJK3X@47OxQCt zKUQDH606y(0kBeUj_LqAc(m~ht%=(TPZc=VaUV)k70-kMrO>VhVo(O?rJ{UJsrUNP z@vIXM-q~hs78c}5D4CvHJiXHaVz0v4B87>gQsm6kE%H!~3*i-pe`a0rSg$hax!AUO zUA>1Ig;sJKBf2{Eg9fmg?;MEw)9-oX;FiU&AQR;QS?&of#^5)i>0d{-zKBMAg!p7k zdLV!SZKenlin1Y@T)Zdj>gS8ytJEvwNBR0Z68Ge4cjg7dtv+*pvjA^c>eWt2?eo0IV{(fmK2u~y@ z%o|mriC>9CD2CvXSGLR~cL8()>`rDe(9Z_GP+NikQ9_1UVQh0CVrEWZYwcrH=`FY%WQ%fwp z2IbU01=qtlJ+eShsyzB^pRqyp5W%;NEcl8%0IqPN>erWcKa_cBqF?WAm_4!C+UBPz z{vq40Tc9+h`%)H0UT~InGo6uf@Ja^0Vp<@?r51h?FLH-Z#9f z*n-Wvv=*vn+hQ3%C6HO{t<5DY$~q7@P3cocI^&@8RJJyIwzv#N#(lJ7!BONuEEx+S zBI9IR8F(|RL5Rsou|Rc>>~w^Lc=i{X7bzcpZ7T)Oa5Z~!jfg4e@EmbFb2(266&%86 z0%Dl%T&lJ(27E6zag1px;Npf|UDW9xa5V@pr2L6fW72`EuNs$6@w|I_D*+i462EuZ zFv$~mA+QYbAqZ(uazBx0-X&0Hu38Udc1dr>03NBu6u z8RA#?sU7si8M+<!j3#;aIP&MVaF4V6YmB1tlWp zzQLP(XcG3EXKdemnS|)d4lRCJa3b{dW1jpBw{c?4;87LG0dekz%sIiOc^%n1nd@2T z!CMm9#*s5NkRVS^H&ic3HuA47MYnY&wPU!K>5UUDm^`tf#BPUu^+@-*N?#{s1_{KG|egi23CF1OWuHw zQI7>XmivE$@BZZk9n|+d141uN-=fK{*WP%1gQN2RrMTtcQ0J!n*E%e%f^ED?=Imf> zdiP@h`BKd@h50xE#fN>7Ls9UN(2+F*<<)#@{8+HhvY@SaWUt2QUJyq=zkLTG#HXbtB=Swc6FE$AtD2KH9Pv{zqcb%56i~d{^+32!g0V!|pQwXaQSARHA>aj6Q zuy6NLkl#{z&6R`#ifW+0QVMxvE?jA;vOg>>!1)SwhxL<&D6k|7wH|J~$M{0<0M4yX zLzwv{@l})l&o6BWD-tPrnlWba+dNoI857MahIX>X!>0~qu%8>MZPHBa>8Z^HHWV1v z)nxtAq4yyR)!~~o=+_)t`kVSt)Qs@A48;Z~$Xrs{Nuw&RmEx}J}AIPE$?gGBogs23a=p?BXbyIjc z`$L=^e(1MVm+FA6Xmb72Sulsb&q1Lw@y&^u!W-e=)F}{wFpu?pw?diT49XR)kp=%B z!DCoF37{&Yrb9#I#xlP7FO}b!O^7njdBiLini5_q3Si7qSOMtLSi7^3mjvt?W>XP8 z>$Xl~klkxQ0t%toGg`O#`s;U>dlimP5o%8)#~&Nk0a5tAoJx_ZUoH=}bbM*l%*Zml)ljm(Ht3 zmIE?UMnkTfWGvCC@x2IneiY3f3{BzWf z`;&C3+R^QP%#HoDR_RoCUBFzlzh#IF4D1Zn1Njr+@Iay3XjwSgf!p% zvp@bSnapq1p|V3 zonc&46Ek>#=?vX+TFql!kF}onb8lt`#xEHCLl{iKgQ=b%OaG-PDljzMCGk^@4k(y( zK3qthoEyOyRF;}Y(-TQ5b3P!D&7Mjfe<(o(2hxyNHA00|$d4dS&V1|$sg#vms1 zrB+|N1hjRu)QQJ+$BBqbh^e*TGvW7`r_dJEc3cj6;=K@`K3pXaYtIXeWa$WmSKqEtjMnMaD4~eWH$ytJIeS@+=^P?pYfOrh+o#8l}3ZJ>fGKaIOP&zl* zd0ZHka1aOY^oFWC;vC;qt(+rQUO#CGe4qd0g+(LuZ+)cxqy0xk1Yg78b+>rVo#ct| zXThy`SS?6rENBwiNVFZsu|$~$UuSoC;eh!o|8+1jBQ|+LCPJPqGO>EFM(Ft)7W_eG z^cikh4Nuil?HzMZzP7Qx1N+k2^#aFFFsUCS1cx9)KO*653M!6ad*ds%1gRQGV)ydb z*q+e3S(J2aGDg4jlg{T;K<|?_lq|PGywh-?B2L8GPq>d+Cv`)d*&rjuzT2tnK{=rJCa-P z7*ya4P!DJRDlA(i6MoFU|6#Sf1b}@%daVqfdQs%NgKVEM{(f9lHv7{6qfdqw}k8VAdz6xJX^P_XBXdTD>aJfHZgAeQ{9Kxuo> z8xnIl8ncn;EAP4Z&-Kz7AEN*4n>&y)bSC%SwB@LTWSQB&b&0Cgz-({*kq}sor>KNJ zg-1?1i1WGchLU`@P$!c7QFzZ^jb3Qjm1(3;ntk#R0gXm9#n%Aj*K0%pRZF(C>TiEx z-t1Yfp-8QX@bj0@Ew%wp05B_Z!ATMZg0{|!6%orHF~5Zpr^Aq$k1Sc+fhCY;)RN}O znw{VWcy$x`-@zlRd)y!I;-lHpjUV2V`@juOc24?o84x3-mX|Lhzh2BfakyuaYAa*6 zkJZEH2U1wNm?9`SKxx5NgrQ(r=Pb=>UO<}#m!^}sI4``&Ov6__L;c{~Vro@_{o5PG z4*_#Fd%5OSC&-yMmpqasy4%`odQqPV@EpFilNh=8t|GVM>HMY&Hukd2r&H}qdAm}g zbhHRk`Tg_5darQLtlOX^iWGYgTM*Sdj`aI8G1B@y$T)mv)T*-wri0LCW6UC6C+|iP z7Ug4ATxA~*5v=ytlRTx|Rz6ay#rZlK3Kp`-h>)egU7_3P0%y{Pw7oN8!nJ3#958uc zh*wCNc}NmrLGHVqFWAe5jNp2xVm5SJ*r7|^t3s+kGyz2GVC`u)NJ5!d>@oL^l20El z9poLf^+p6N0Qip8N7Pg#yUKvbipr#_GTh2FGNnPVzZP)mRmNQqfA-O;8Z^^FLIxAx z04n^`FkFpn;fKD*8T>=Q#d!%O>Y;dis@XP0pPuLqk+71s-u%(!1ij0d0d%2F*NoE) zk2U&djE|VR*TjB|UdK4VJ>^=$Uc0>pO1*BxHMb*p;3~rLE+kVf=dA$Er94NLpBVb?m(SGeXViaHh;;QeC6-H8~)N+_&1d?9V`xP_E0fDz(+lci)&T&$VO z31tdx3nlY?H1~@dpl&F1euUO{wBtUkx9I}5>bdt?=d;5eItMN!KdRT9W^5;uc^JHp ziEKEyvx}O>>nqLKBQqPol!7)L%6r^ks6|q^)U;C30aIW_>3~kPDD&V0@|4fwgDEC% za;aIpcHy1R3pNs$hddZHD| zKNn2Ukwwfi)abu%Gepz9j!XxcjBz1kIC9$Ox@#TL9Zo}Ry-y=jiM6*%W;*=rX|qyU zM#5`I3m9$JY;P$L0T2{O3U!23R8Lh7&yam>>itHNP=Uj|dWR`4*28(8L`Pz%}`6JFp#60i56`K@lIB^vG_Zu&S-1ul2b4Y+(# z#I!M$DMj~DI6|#YBn>?rRU{9nN}&{$>Y1yo z%&LShGoL`xgh@Pjio3Q=sBUVOvkPrv;x#A%Z8OXi=LEm9@|9*rvL`CJL!380Y{&IxuKq%JbYRGPHPtk#>4myvL=hwGv4 zrWD?fQ8ZUdAZDF`6!p2*Q%U|IMcS5@*W4`ZT`Co|FR-}ERD=l=UnM2SvTPQ}%@+fc zRuFqJ9&pgf;wCbX%Nf;+{?hih+UheO5s|s*fx9r#%n>$M5h>B;L-BHv< z!KTvm z6KzA_U=i}g6L!TcLhK5A@SbCAudrC{jnbVt1 z&>RQf>QBU{F%3P$aCfRrgfAm9?QIB70@|Z!`#YF(B@QVak%Rsc1s!cTz<=3X*vGWs z|BbvVP|9$mC}wF2&3zFFe?{P>h%g6zDEg`}b$mpQ@>Q<+`&H$~ z30fztf1ndW1&bVj|I;V=2rqrQ=2_ZYCPE>Q^kHXO9@99I?7flOuYLjtgD$XrBA!LF z-oJEf@C!_97eGg2CCa943qm9s_<~E!@zvA&b&!JlO-GiL4PN%Mz$yO!@B6-Jv~>Yi zR0VBThP12o1#f2tbRI1{M*=Upx@obdVGOtz3RYqQFLD1y*Z&}5op2Gi-$2BQ1x zi(F^>|3|}~IL9wU{b+7F_}OZjDlT&%cS_<#(@vdo1{=waGPqxPN2w z-ujyXBVNbUFLv1H;I?4`@9Q7%;&l5K3)tt zA~*2v^dvXHZTh85$*jo__{TcV7M; z3;MNyRW}A^QTsD9IBqrNxKbxX!_~K#Q?UT|rSkP*Kt)CD-qimD86hs6`CG&gjmX`^ zjqg2qT#SMRia~0p)4x3BZr+aAIdkAng3nU|AXk8M0JDLUxnceF)}q7>beOdVMl&LfQIjIkDb! zmrKCOl*qZL4?^5c(mm_HHt>h=JO$9@{CmC~Ez3ysW|e!oOMpWd>wQYEhr5o9=~U?) zb-ZX|qTcT_r(1Lm%l#D5>*Zu}ze_bKyRu7(v*r7(%3}&UO1bk#JEH)OgF;$ zH-)$O8#DU|^bDi^=S14**O`G&TYmytFNX*qb41r>Bghws%@Ccq=+o6oqQ+wV=!-xw z@rs_fV~xqg%>m$*1G5VH*x4w*I-jjR>Wj|jxA|fR(I;mG83DqyZ{ANu+Tw}G(ahsa z#KVh~e}0eG_&klQ`vvnmtUVsv)#Uo#ytHfuc>bPOP`fHyKyw(07Xx39Ta_Q{rFClm zZ(Ac=YUanxxn8&S#^>hde8HryvtE;h*=i-5K`!GtyPwSI#)6i_c&=6s2q>H+ZR4`E zw+BYZeb4Ur0iSMdfI+D-V3x$GrOR74$kt!4fbqJflZnl+f6_8-^hJ;b+`Oy}nAu6Bv5b9&E~6Aa zA4)D!$p#o`t^Fpoj)_r#NQgKj(A73T6s}MuuQ8%@`J0I1NCaGOd)RYdA9hsod!eLm z|NqYc8K>M?<}mb?UfKWpssy5K7~m)Yr^nFH{>z}`aefRlqjy_@?_&8G?0az`_Ja9< zH7{v`+|=HibluKf1M+JF_xE<#2^x@PH)wZ%IJ~;e#^wS! zMaJ}W0VI%c!}BUUw^JHw{I8F!APRZoYz!(>qbCNuFZ0~fQkf8krrG`oaLzV=UjrF& z)OEH0NFMlfw1FXd`nl~#<_|s@TII?$s6B|R(8Y!SrHP^>{CU-1uJRvHfptvE)H3H% zA{TaLp>DbT1pG;C_Mh{1UE!qL;gb<(8avffU%dwzlIr!kPOOpD?E3&$Vu@F&(}R?4 zEq$@wq|aZLyh(@>jE|KDjSQaZxajt}#+`4ny6CgY@x6L^Y$5l58N1Guc|U^m^OE*B zbGW%A$N#M)mrdkq!mVvcOEvTBFtKfDLHD1nKZXJ>KgPGLEeshT^HKk%jTjI}3JRyO zf=rjS_qp7b8bnA*Z&+aD;PElHKZ7_V`{U1Y1vizWidAgRUhc6gIh&`)=T1k5WO_n( zWSnyIfvijRz+h_g_Fgd>+lx0Tr=FX0c8GnR)bvPZObg4NR`EAL#rLI!j?jf@`9Gg| zLROhqhQ42dNr8|o3w94i&-46UvhFq8f95Iu=i1F3Ia{zHilR)g{;lrX1=AmM3Uz>5;#95HII?|)cUxYkeCm?jE__R-XNQz zL^(`UG1#Yy?-LovL@FswF?<|jiIJN?MU8by>X=ppuBf*OC-#qT5vC-ZpX2o7F{Wl5 z3~d{KR^-zB^~)-+9+cXt@IO;OsQUtVJ^Gxe!>1X?ngS!1Dopq@&dUAI2v|M z{$1B#{jjr?LcJ?k3OSv&^_-sFtN-13fy*zGG+&W|VrK{xOzHUl+^H*$8kOYlO=UH* z9MQk_`WN#5iRAt-{8)(?DLLm`1~*}YAycL)IzKR1{U7JtnRK=g>r2wte()L z-d8^d*zQll{D^PwkUht!|B}mZoGc{@4!E;mmmPGQwMws5+ITC`NC~d6o)|jAeTq!x zcQ8}IEG!4MRUnu%o+uB;Bac;cLd^jz2nR`eTyFQp{WGUQ-U5w(SJU_N_7GL?@itpx z2P(l@_$ghN1?QP5k*xRJ@^PmKA)kLMJ7ek!`6P6Hm21~0&c}EWlx0s`;Y(6Y^28D> zTv;8vz*t0lZ%QusF_w(#`P&=OduVM;_muq?sIZnp7K%4yd1H{&zM=d))X^i zq7=q5lbJYW+KLeN{cwR9g(EitB^LZ_SD>`s-`7ix-Xqa=HSUty7u6kRGc9eKznVZ8 zjjK{1(wz;oZi^_rvU6BK8qc_{ zz){rfjvY-i)gP-27?Vkc{ba!wYBO}7Cj%DTB`v@cHb2QU9r|+XUavxQi^^*8wF=-8 z<@=?G#wIymE#@VHA>4yG=b1!%P6DcUpxi%f;kLMn?H*&%ni@U7$kFrTnjB{%t6t~S zIuOWaLenFUNlsiBP}gQX#g}BP`-AS&2>ry<(h(m0;gAYvxiYt%k)&ucFw%*QV8kiTBHKY}nsAQy&TjjP_uiaB zPGdYV|MZuM%6c<4H_R2L9R@X++x`)8Q0W+PZ!Lq##(dA2zc`L#pwp8LicKUD~^Dy;jqU$#|>Zu637rRVxTYr*@o9z0i%q2BKk z$=LI}F5ZfdK1NLX(-XV9p_OI)2wO-RSLB|;cW-HX)cMyoUmjg0a8zi*_VtUJcM`S; zDqrJ66#b!jtCn?{p2R>DT&{x8&_BK?p$B&{N!8Sr?nFY~`Ns7|cpMcY;oP`r&Od%` zHe^@3&)#c;(qWCu_w7#GX_SPyT8Q--s^f@N=7>9Vdj?d4mXa}E8pn5y_}scsxvG8m zIAU+{Yy9XZgyh)OlVA@>+PH%#LiWpS3vp{*5opqHj^Zg#w=}n(>Qu~DdYzl+s$1SE zBtShpmnAz9u^#+c6CyY$FZYfAgE8iP(KWqkC3X#XCn-thJQ@<3K&R9ngh)ewfq=9N zN-)NT_P&fPQ&oMJj~w}_FEJweJHfXS?$T0$h4NBT%-J}NrZdH^E(a^ei`O@>vLxb_ zmhal;Q`RGDa`tHhShuGM^ysf|_X>+pJ%1zpURk`1DyB^_&8{Sa2uqMIpAJcbEY=V4EvM`EP= z`_WY_iL>F*qVqRQXE&w_O>bo#1RY}hitl@N(9XiC1$L18hZsu4zMdA}Rkj>s9dvR< zh>c?<2kC9sOc8yJ3>~T#=k2CiBJCq3MN%j!O&-WSQ?7^*wzV@HwrFfp$q=l|bL#+5 zejmR39gk3icmLa`&UqB1Yo~FLZZvzQc62UY^jRQ=lPU(0;7mNLOF%!W!6qs)DWS(u z*9F5AksPajb>>f2Nor@nNDPUmWpb;1hh{s0Sz5FV=;nt*;yXYtuN;V~C4iA_Z9j4x z)Oi`I#=HakDgf78qm`_bL|?j7yD}uEW?!V1OO0$I+l12&sFf#Bs`p5f}Xi z@eDnN9ER6iiTPD1uWQnC{>VPjHMxpxF(-&+3mi?+kFgmt69=hTdUIvXBIe)=(^yMP zkcW;^?DJd*dS=F6giRD+RDZ+V7m3;B*BW&U;U^;ATtX1LJM)>H?^zDnL-^H26 zwj$zh9G)T!{RQ6u$~5vXgDXvifxVW};U;45` zaff6yC)e}{w=R9=Bdv3XtD|?N?7y*wCH4s8plv4tbKpA7I#jh0#ME}q;De%qbUzu4 zqjubFuE|7*fAjQO3_^p8fQKX*Htm#b@yJOG+y6+mo63yB4-C zrBC!;1w~>!!^H=TxFEzKouX?BP$-o@2L#G_7 z%=@WJVhDpUa`s-K@O5}!g}V85HhDvkZ#?ncXk3e5&uTzlcG_1&3V1l1F!|6ZwNGcF zp&zTgKAyDZ0ehm)8I|b$C)thTE-%snQHj<+lDpuQf7uB|*hMzGZT@~14tk$t#5i1C z!oVAG2fUbh!jhbKl?h5I;TN~zv~Z@{%1k?A`MJ7u$-Y0Ip$T0UnzK`b__gkl-|KyB zcgwfc0Ze9J&GLa?1?89uxi?2jE)3yWF!@q;>1ujj)iTNoHor)nxRk6M&rA57`F@Vq5m zeWK$|Z=*SoYJPFG*eOra*3 zvSlk&BiWzl@)d5wcoYhE%PU0K@Jr zvd)<~K*Y(*MZ%V}Ov5#*DW?eBjie??qR&W+i2#dp&lN5f?D0#=9sWuJ9M^~3r-Vsv z%`&K@_Y8>obxoRcyU^OCelGw|wIpo0gq=75`Kn$WKNSFkJ5G82#IsPgDoF200*Dv1nrEEgI9@O#QW95j7>`?2IB`%8Q5Ig^>xQK$gEz4LPQ$J*N3 zIgtK-j$Tw&0Y*AOzA+4d4vxQ!lwhX2<=Vt|0@`m@P$>Si;{=bik7Y&f?kdKdkj)Wo zGH3`*5&C! zrL@D5R^nwo^OgPlKxAXvoEZ2+vK$ekaYo7x(4yj=&B+?~KY%AjQJMh!$tBMfQB9pC z?TXH>dK}+JeVNbQwv3e$-iY&)vPL+VMcc-2u`7>AkT1#H{AhH#soTg0A2|C{EARa= z7VzQ^1+O$U2bUM7{=k|u2^Exu^TY&1MB5w>x!A*?K*`7D5j?8dNQaL;`(FOe?3@SC zDb+-=*cp@Bm4X05QlKOqT^_LLar5Zb6tK5%E#M((kex2^*)bHWCJ5HM1PZ`CMF}xg z+fN}T4xq)`h%H{18>bXV6nZPT?}3RDhbU8)uAkxc z&{yE#!dyr4kl|D8f@8y|0x=VV7?2)AE>Z5+)!Y2UCg8pgYm?Ni9QG(>!SH_=fvR%Z zmKxpebk((`9Pq)-cm4poUe+``19X^FxP)8E7Rq+tySWPdKVtvce^{wid<%HS2p- zJSS11veI9loKD*1_*cLZ+1KP=Lik zvh5P{VOz}|&nnM!_iP!1FvcRT7uVW^rDF~5DeZ9{fQP$!fJa<;-1eqnLAuLV{ZJol&&M& z;tP6P<7C=4(!3;y>ip5ke0yKPl5yb!n0dEG8)8E5x7|_&UUgi@*oU z8(I~0JK?ryfwp2bJfdzlrE$O&2MenHP{ef7Ym8>fSTUFJ=6VSA0O9>lw3Bt*-`%AI)|6Gy8mw|1Mj5mmFcG94hB7{vnR^9aL@f00t- zxHDG_b-J6ILEsD&*9U93fB6I|Bs{3p7i>h}rZsQUh(f(tyk#pqMK8LtsX744>c3lY z8Irn$G;elCNm=z0F)TgTJm^mA9PcXYl~wx4lXo&{k<<<=w`XF8+Vwtg_^TQyfEv%W z!z%H8=LcEr+f1EwS=J-Em~5dRIiXMBX&K<7&6|Ur#C{= zMOLfl$B4%osE}!tV**&iabHsVctF~s)3rUrs1)s|K84n(KkfDQ9g=w=0O&>^yFK9&|FYWoA zbo3k0{>QnIxccJldOCm>ukYQE#hQMUboDM?<8kAwN-ahtMmubcgyEUa4A0))C!Ay0 zjz-xcHN0*}izc7H{dpy~)a*?-=L?p)XWMTmEmf7OyVUaq{>@ACrr4nwvtHS6;bssU zB809Sv0VYI!=lWrPMOsb=22S)HSRiE+;Ok2j<=@URxOcT?}B>`O;q?77#o?_3Fz6@ zs(C=Ssb>SNByVun$2giH{#TLo6&8}9k9+&6V+#?tiR^h@I2uwe=$cG-vUfrEAh~e^ zM%r`&3Ot9b7cOc=k^TM%sLbQtv6H2x9@(rb_!=FvlGsFt1FCQ*3W`HKt>xPJvKuN# zt0j%$+)$ksQy|l7St(mErXim_>ITB8^`9BH`uyn_ z9<|c^Ok6IMq;K2j1P=Jd749waHkLUlCw9LfV;h)PJyf*ZzANzS zX}PA{R<4olmousi;4xhzrxg8_eC<~FU4FpD|M30%1Shv_nPBLPpS-&Kabwc4u$O{| zPBYwA{;MxhY_hMA9EdE8D5F9-e3AeoWCp&PQq7Z=1@C6@QCE5Pt(WL4$s5aOR8n0V zA$olKP&kUYMZOn#7Lr0gp}NRPDk2^6V0Up8jmhz%R&lB(K+9HR)HwWSwm z(7MhDU`N)BGR;GvAP*orwu1yJ6Z}}vBq(X7B(pY~?IR0s%!qX68MtM4-s&ZlpPoYj8+>r7fU?->^cume`{_UN-~L9m z2j9b)8xDIF4y5JjzW*%NqKB#|;IczgL26Z0$S!7dilJAv070I=-TwOjq3tW9+T6Bw zTPP02-QC^Yi@TLVp|}(XMT-W9;Oc?-PgoiNtXJ;qIZH6C2-O>%LwZ>3-A0u}FyMR? zKkg;HZN^M$g4Sxk!}SsdbkgMZ=@l~d?5RKy%dpvV-bP`AO_p16NzYywVM!(LVVkm( zdBJV%k9pj|i6Zy3dBEy@VvX__iru?1i@er1P~Yz%)s&F8s zWaC`tKrpXy&>vwu?ev zpvK<<;X^n!CUVp#Aoy%~;5TO`q4fw-dAzz_?+cszpJ*B;oB1NYdjpm1B^-1#q~P6zf0TLVww}+5abY$8vQ@UThPB@Y>`Od9?39bamRQBg;4ZV9F=C~<$8CXAh z=2b+{?}83`2ucSsTDWwc$lg!hIvp}NXv&P`j@=3Ae_B} z-bFGjj468yo<&ONk6@@#N|fSLNI>->k=~bX_r>$j6SU@tl@z6tO}G}j3LjIymyl*g z;rClp^Vc3*5a^>`pvVF9*Df_h>RGiHYv<{CgS*7DK7U`q=KTc5I?YKywLps2R+O=i zggvKK7#1X~w2~$it}^yZYyP8+2m=j|1#7IaJ-~2c`*Wfudx+m8hLQn$voAMfk=S|w zW+?}s=+`dW_p?%Zv4B_I29@{NI#G(ZK`xI=;}5A>jx=R#^BawyKKz^f8bu{IUd?uz zF4$~bWt*6aDv5)bWR8h6++#U=#AJA_h>xc@4ju;|G%TYk9&?u*g6jEW1hgbwC>p>i zM;%(i$eb96JR1aU_skH5jVao4G5>KzRJG%6durBn7NY6YP+6(*r5&2Tbq&n2+o1i! zp-|)4>1ZeIRFNU)#{2Xbjr#s2LH2wg)K`bd2Y;$W=l7qlLw$`c4KL!?W_4)?*tJb< zmScMDhJ%JtSgBN(i8@>5)rkz2=h`-qdD)IpJ1xhp+A&A0eo0?BAGW;ECeG#ktVM!# zJtq#^MlD#T`m=g|Ay>AzGT0YYJi{&%f($7O*RmhSney%`lRLU<3P<$rICt)x@Cv>` zC%i@GK)GvHf15?1=Q|p6$mU^!rbN7VT(^`eVqN z^U(Z7ZuG2tev>DhH#d(rhi-=Kocz6n-$8;_%2;F}mqoX+x^i^^CxoC3VIvWRp;&(r zN|4M_0;oekoKn_Ci*c7bS0wHGI7oTJ()R=8jAjmXHdi(!h#z>`;C^A;t?2MVJc#Ib zk4>K6|IRNRDt~UwQaw_&NwU2RPU`y$?5Axe$1ub2s(sY2XI)t`mN}}$Nc?rbo})Y$ zLt$jpvgD8|?}iG@1+>0*6>|q^Ca&=w-To=o*cFEaInkVd>KitX(FgY-JCY0r;+ApG z(v)TkR=*@S(QO9`m$^xkHd@y^YJC?ByIIC3<*HCqau$HFmw|54b2J(-LCyd|$}GwD z1N{V|@AI)MzKF%ztKJ4*gpSe^{C&xO=UY3p>mCrsM;y%*A!u5r;>6y_9o^{Ze0uF= zVO?tHW}MJ_%C0(`w}0<@B$RwK!&a_rhY}GD68r4F&J|St2MxAjYtGn?R08o<@{Kj{ z48kF{){O>++KCX(l;ern+(L zQp49Y=cudi9W`4j%oW%-4mJ{PWlEtsHLGC;RF6(Tzm>!CVf`~Wll_Jq z1-Ok;Oc^68b}Us5)X!jP+z+Ce0V(%%{Yf)qBh8E=XSF_0yJ=r_K3CMH9i%KHztiu( zFbcsdr4&F}@3Suy=-uEB9lCHf>3No)rOXsVS;|_dl$oVEdsznJH~&5z!IE22aJSqwvx|{P<1y!`3Fwd94K8s3g#euhg=|` z)oJOscMXto=rpZGZV%JWlvats!}}id+J4rZG9+7*A)1gLa8bYC@lbFb38QSNHp9NeR6~psSU3?Mo z*qdcCn22)n&G$CWG|?ne5Z(_oSdQ7fwBmVZFZuuU9_>Dqu*W1AsK`8Vxe^q%I^nPk z;};8 zLAYFSuH~7&FTp4=OPUKJ-MF<76)sEooPN=)6Rd4(E9}3W3Gy{`FLvSF63ZZWaEwuq zSMaDR3NEG1+Ct@!UUL7;p-q05!Tk05efA;ysNj!nD(^RxP> ztIZ=}cDCE^(T~8fM`CXM&}#ZB^MDQ)EWDPJ0u7z@cIf}%S3OZ z=b7);L-BUgztZj84c*ERU3LMtvb#U5mQ(Y+Af;ah-sI2kV9cjeKyZ)1?o9&|fc-xU zLB5t8z+saoGQp-1z_Ze-BIvMw0jW&V*=YXX@zWU}j|duSWo5YeWuqGB&b*JrELN)pWBr zBV+xnVr*?@;)KYm;cV>m?^on(jV#O%S#_*Toh-?C+4vDzWzDQCES<>MxwsKoB>^@7 z2Mv286Ub+!%v`KY%+zHh5LqRxoE%ln93%m@_5eFGJ0~(eMAlDMHcn;^WUQZTjGWA* z%uE2LkjpBX*;zoY%gN2h$t@y6_Sf`&rk`X4>tPMe^@GC!uuefjpmax^57NlVYKl~x zbPRYQvEu9-40xUC&SU&=Sc=~}YlFCd7mjB4ZVF;I7xY!GVY_~9fNYU$$bXutP|heW zcW-Hilg4P04gFXp#gdpKNhNL-6JR>rSi^xnCWTO?8FXsat4I}dnfTyStH_ksA3pK$ z*8n?StBFXEn|u(5 zlzE|n2lyHFn@*9ci6K-_NriSsp8Xd8882B`Q82Lm#xx?P>FfzC5*AA!9D`YSHL3FG zihtbt`r1mDf)gz?b+f`4vP14?yyn28*go113C1ldlyih_PLaO`xYhFvD}m9p!vD-% zmY==H3QyVhq7ImC@e|00bs2n#pY_)OBY9>NlG&r{z{qSfCj6;+8HZ&F>2P?v@ca_` z-**8W+GXYIg2#g}3bD|yhXX9}=qKVqkm~}{E|!Tsng21xKi8nPkaP<31s~H`B7^df zpDI)V{?i|M?k-;?=M{;aSwuJ0tgeo=@B!N9Vq5xeJ9Qcqw6{pkwN+r8_K-h9#^dT# zlM3r+qW@hCkkjzf4jh0iCyiVxaZv7ua;<6t6zr3_o2l$PX3CG-lIpdtDuEhrZcp>s zit*mV#ppuAgrcs;ftoD}52sn)XrOS`viGJ}qMAoeDqk?T8vNh+t{ZvMCrJjt;ZWtq zD+eD)A&ntiUq9NO)w<_UXq#DSo44zMM2>ZGDh?dYaO6veDRTTw4N^E!5WP_hN1MoL zSP-_eIk%DDT*0DUNyA{3;)lqW^V7d44_5U29E*%aWJn&%0CWOVI}P}-{gB?lx=+9< zNbQ{*Y;}6Mc)DV8u-tH@79mqh1aWd6k6h3ye;=;Cq_^?Es*xW+;pNiyikv8-+$u<4 zb{2mdgx*$M>FH}lj2#|*F;?`<5!vs^jH&au!qz(HBJZe~mRz$9ZC%#9qCe)D9jqhG z){kWnnzoC6xbVCLlVq_zu4u7TFombRo%5 zViFlRx3MXzzI}Lp89>P4?QK@SVO%@jm{xC6H*z+=GmS<|t!5evwHZS!MH6Go{_qrf zHBvpxN9y%82E=(;guQrc#^puhSS@e#%AV!uUymC`;awwrrkCrI-WZ%5qk{I%ZYb$r z(+5R>yJ<>7`Xt(mRC2*NG~lgI9mY3@hAXC`=13Q|zqJL!m%A8w&ou5t`}RlPu0tdL z7EN%CXHj=2&mjM1qq7t!GbX~fDTbs_d?;2X7XQUxxp%UD^B)o4-QxH}N|I1Uj z$aw2UpRaDSGjLZg(hcU8+EXJz(xGeG*@N+Po~_;I8fw zwv@CFN=PV?vA&AqMbU2ULqe+*8m)wgA>}C)LqN!936W>)S$@TpF>WHagBXKTp5tk_ zHwElgFd3~Fr%yWCm68{wxOAa}g-dJ;WOV+rFdqRi7B~KE&vp#FjPc?S0Um*Mu0@G~ zf7uZ5tbu#8OOd0*R2Jv2m08{o;b$;V1cJ5y^qh(DSWTr3qPn z#tJT{Z&>!tcO>=hu7LnmQ4PlyT{i{X3gLI29u1v&gi%ZeEu<&JE6}2M>)mTewI6aG z1JJ;E93{8Us*y1%+~?qhBHiPA!|=@brz$XoM4Y|6-0*h>d{$ZHaIFGPnt9fdIi?Xc z)&XlH-H-6lx79ZBAjhMmJAmO$X(B;t(KSE>BlO5jc-$|D54+(<&~>I>qoaJP}~Mtml_u7_R4%==ptFfI02nUzU#;7P>TCSJkb5-RXbD&Dqviegu<8FW+nsD%>PUX$!c2NI+D$e1Djy8(p}c z2la*+Odz7LiJA3vc+n)!S6Pkosm^KCp8Zy4oSu|Gi#>w>62)gXBf05QZj4KpGHeC35$Da>b?6S<_?U4BcohtQ{#Ve z3Jek5nki?PDjP$?q&p}HZD+bbV-!~^f&-OEbni!ds`c|T-5RyIqLIXN8u2MXZwQKVFq~A)}8uto%%3bXAM&y zi5OvWr?*sEftTcrpUqlUv%A?V;Z;V_=l9QBgA2C8dsQ^=IE{V336uPBWk&t?Z>)67 zbuQAv>04gKY}Vc73nde4M=%5u7*0-M%l{>X9)TF68p!pc&$OvHzZkx{rISr zhQg0HuAi%0vgb)srx?+~QuX6l$=%FNr-o*fCuZtv0xP^u%-J|AQRcQ?X#b_EvZ8b? zl?WZ;z8_60HtpxQtGb0x1!lgJ@U$Qe6ZvZ9OpgJKet(@Iu!r68RWU;GPNvYfmA_`S z&17;O`v*MG(F$)(4J)m;~BveuD4 z$d=vu{8HK-p5s7BOFD_bfs}+G*L1CYLZ=ISr;HtMLqNohKZ+B7N|X^TzNMjAPbt8n zHKAJN4Gt8Ki5q1~-=JHx=VM^OA7`OkAG)npB#Y{p=`h3xl2D)x{S6A|9~1re((Y5r z0LIV-H{rIU&!)}PVDl56&l9~Qc^clF4x~&xs$P+R?Jb@5*O>*Y#jI^q5^jXvARRH* zH6Ru3oz7wlT>bU>5GURoq_%@pBTpFX5(%G9!l4_HLtLVCUFYxw8#%g`pK;4#Opb*v z0%CO4{+LQ7+F!{XuwBWot9ny27J17>n#D`bmMw*{-x2R=ts-oJ@wCq{K+uXFO#T`5A*2WpUaZ5AK#fHBio=s# z9G2D#D-Rt^68&!W7jlMgZG;zUhIafQ)5(QFoD7@QVW-*;YQm4=Z?P!Beox5E26Zh8 z2OG136Jq=2%X(JlB=5|TMqKVl*)w}-sey+JRyA696nw>Gqz_2LF35Ny22#9pJHVw5 z{hwf=w^s0upYdPN8?cl1B;8VApc6Dc9mhY^+}~8N#)g!h4LBk@COFUh!il z-#$9+cG>KOFU>fl47KCLQ-yZba!26j(lHg9eN8%o@Y$!i{u*fgZScQo!mHccS%myY9{U?YmY5el|3<-O-4oN z{oXbj34sdR9*VR{Q!QJn{*x<13kh(m;y~3=`Uv;fW~O69y<^C(Ly`%=66yE7_#a z!%4%p$k@HW`<;<;5H^cOWJ{j@uivurCd)&gVU}1cE%-p-WcrlFzGE_BezUXE73va~ zjD+ORx#PM#oDHUndz86p5Je+kGlue|qU4W3;32#-L_XsF(63@)GBVze!a)-q;KVao5i_I@5u%p>BC!s>v+CsVv8gzOMQdxV`d8DF9jT$>s^jZ*K%h-6> zSw)D(Jbi$ulW=r;v~T)_-a@!5ZM5)G2A;nQ?TWc(^H{UQmWjM8ZO*OINvlKFPt&zH z80C1lK95}yh~M>POK8)W!c5tsxn9F}dKdkb^#nNQ$9=8+a>Cr+%IloS*QbrAI94+nWhoBe6JnH~fSetng|DPO^cm@d7u zBVJD^(8T-=>n2d?CGhR9=+is+!l(#}c{Am)Qy@pmaMKvu;3UCqUBDRB4tm{xFou@4 z?sE7{`63A`;0Dw4tI}yYjv=<%`*6;c>SF3S5srmv-JM7q-=g9hp8$SQ2w1*aaFc}Y zW}UZj{pl5#>7)&QUDl|-wR2x!97X~r!Vzr;K+MH7>74};-&obRnz^a;d2P*>*xAVEB4au5l z`>snMlEfwXi)6R^0jn|nd;&(!htx5s{)X)qs>~mfzy`lMH!Y+7PF&f)_NjH1@KQIOE{0hQ~owoir|;^QM_ z5YD5_u%p8IcDzR8&wgAP1E)d(%7JspPqGER=W-xc9=j5=xMLm zZ>eq4TW%K0et$7ATSJ=nr1IUiMf3W zd`?XIH%fytoS01CKgKV9bACI1NPk0DQJh`gCZ1IEl-l1SJX;R9v#C81zvuFFfj@!&OWp8_xQ2EXaco**bLRW; zOpcCdO^k>mM59R4q41xho=o}u{Q0OajEd~Aas8TkO1D3D-0apg##>H-aJdr|LFNXpq%tGTMtO|g~ZvJt}CP;i3-1J!*KB~zL1@11pEhH89;ABPU!L!4| zBMoOqiW!f~5R5X;V^I3xRaGYRI_qGN-0)FD75y&afT$GM$g>4|6)GEvjlORGnDmN! zz>fbnSs}6wq-~egiMBJe_cVQE5Y-c=RpF$?75M=r;&?nczj6=f;{R=ur=eD;aoz!J zaQ*60R$-8{3YxF@mk(x+BH=C@f>gQ~fogzZT9#5Erk2ctZ8}*B)z~5FG#v|8*1h2< zU@)5Ezg!fU_#wS;gP|KLsNyCn9NF1Bv-uq{!2{LdOKY=V>%GTiPvm@EY94j!H1(~5 z!WyZ_%3Qv!mj;qWTDgIL%@|O~vje~i9~HFP!gU>bgvh7qUEWNVm5Xp~^r<;{n6|Y= zA|N^*ViK>Z)72$Dn$)m9P3&rv_5GKvT=!?q>EkCX#~Lb4=7}hOczjHMm(7uFbZ$UJ zYtTBmQFHNVH}H{(ZLM=L|GO-t*P_By+RSb>j?C)(tPai-8was>^ zK5?IwD;hMu*YS)!1WKH*AYZ*%=4KuQ4Kp|~L}3m6+1dLuA@niO0S%~RS{kx$6*GN` z8xsKdDi{$!XhsIs0K-g0{|^_+`F6j3JX-le)=!1LUZ(R^Sp?|wt}_e9xykLeWUk&y zFU?MKes`zH5pjm!?Ur$P`HP<3*_zh=4ljvdk}(-U((}>0m^@+7JTjrwK)S*Pp*~SGqv)I zrR3eAZ>guViwM<`ECo{DEX;MZ&|rV;J76&qZeb15nmI06nx7k>D%vMqpxoxG3rQVZ zN{oMH04lbcDD}=EvK5mxx)qisDA|@^T#^7~I-2!iLUfKi=NQS8q89IOVizCGdcn`# zy{ND&U{Wd;shI9(DyIFmJPMUQ=#hrNLDs;6nKwl{=&zU>`aLP8$4{#G?#29C1(gx7ud^Ur8k!ReO#^IxOxAMSp&!EH zl#@QQ(p^!DXc?1UcIDTMdJj(P8N@uEZfz5P#cPwcJ;P<$AzXZF{wT-oeAIuPCyzT% zPS24PJ#pEhvcAx8F|)q~K79i=0sqICc4V+pKu%;Z2-!ILp2t7YJuRl7zko$Kvj~t)<}O!|!AIOT zLc&CQ}I+F2FlFzFZAk6@}S#4^;! z9gSkA$ki{TXbrVrJx@F$N!dE4d&xsChUnAIes{%P#1dvGmLeGLu8O*(^*hU6?LQc~ z4Fn|#Kj^=>fjfvG+^)(K@6V&u5bXPQQn1JK-zf`G4pJm!{>3h`6k`SjctooxHXWez z7xAxOM1-fOXp=N95>4~>O2|dq-hHeaFZG$A>WBI`cCvj$Yhxp*)>}dojZ#U6sRJUK z=B*D|`7G#k$XwLKXzCt0>gT+|n=iZH;j3>Wmg@6xCrtaUm&M6OupRGpdxOJ>P8D4e z`w=k(=}b4V2N^=zz!8ysGP*qI8B^TYHR-3P?Zsz6EB_x(BNap#G(5;1|y? ziG#?kuHvH?I_w2v@~}}7!{l{h8KLo##LC%Rg;4RIvYhE34}7Eu#^o5L60IHqG1NS= zy8%+xzXV{cK(XR60vSEb)vZ|)#Mm`;By*PK zXt|@35e-zzZH86!*{Gq?x9#$LctyIx2-G;yR+_jGe%;Rmt*P@`PEqISh}w4+8Fo*` zrsXS(OMq=9jfXzTpJ>-P+hbwD@xSl;+N0qEFg{*K;=ki?cpWiFfkS2zib)?77HB;Y z5z9p!sC+T;_inPWIj#VhZi@c;xp4KYmUaw_V_5%@1jc?}{7-PACY&M@e*0C_pz}oA zr`<+W1=98-wV5X!@jr8iMn%7am$_{gR|_KmPdg-Pk2k^YlIAu9b(`3QspNUHEdH_Y z%&eF5_D_U=&$Z*#A4P2(5(1akGFJd}kyku>nN^bfrDrK7}Cy41|c4@72%+{2Qn;By5!$gpQwc7$Gq2+MBSr zend#A!iVqrGq)HV3H@zyX14Pr=A}eO(_8BCHRgL3q2LFs56HQFi@Ddk=}a-gfkcvftS({Y9~{M>!A?d`Wo;2FNjcTzeQ zHU1tW(^Ip(8R9mLs-qaZwj;Lp)Aheh)TCh%8`;kdHN_dK&q!bjR)X^x+n)Ubd~R1) z0QMG5{=UP~Hl{2P9^%Nuf`shyFwXIV-Sw?fnQ+ipYZ#vpT6sb$$sl>pq8a-}d z&b#7PxZaIb1U^P~*TiD|@Y1%i^cLTG{HiN*DKe&eI@vJaYgRGw1RYTfU*&wBAe=Mx zyb_S){N$+DM#3ob%y(0}8=MHO4SV}#cBc203+MBbu)Arh?ba3L+K)b-t*02VP zE@2-$?nAiX31o3MFh$FnBYn7j%5ISgnNVJ!FbQ{{0at%w_GX1nR}hLCp8Z44rPYgt zop|EK@NcEV_!Dw4NecR@8FqO{uR$j16CCWc ziDd7OiA$SaToBh0+0K|68W0I)IlWjHZc^JwIoc?%Wy(F!BQp82d08&jJ7O{UeF2+h z{X8NEw?P38-MrOT;nHcSCF15E6q!K!I+!(iBGx95Q)$OCMs29%EeZv`ZK-2qbq+Ch z;`IgzE@ey(uDZj&HlT=C7%v4!`a7MMLaQn?91@ZZFblyP-9`?RHr??bP;A7l7mJyH zCW*y7*o`hDK!C?v5lcAlyoj}41M=;hwY7fQ6YCx=B3xLw#q*z0yPt~YaYlqym>ATb zDKAScj~kKm6jSxJ@p175kkJ}9#GVp2?O!OO$?km(ihXF2&XuGe=`=D75#>!3K?hfm zivG>>)Li{vNo27+*q~yFbv}UXz=ySZ`4i#!qE87f+lYZfCp@i{8Ol~ur<~n?sLjLJ zqP5}{ARK$GmXx~JGG#b_TP*-^+@sLa2~%DVMgU-0pT;Jqp-;wsi3t>i+#8d4l)bPL-gYO?uGe1VZtZVs^uHVl~@Sr zRM}=~!_b9nKur0a42A0jUgCQMeD8&>XFwQm(Fj+-AYgqnoUTQs*JmW!R8nCgnfa*F z50fVHYu7TlLUAxt8%*BQ9tljl%8CBNNt`QDn+|=#Eu#=|(`G`G;ZIsjz4fVU-)#Hy z2oe{Y_xw}DE0rkH4&5}STzLNJ@4ygy?F;_R6YcV=%4pFHZ{cUoS9o2^CFPqd1n<6? zd_6Aj4F8t}sWs;#1~$(6yH|-9D`=QYTK8KZ@&A0qaaU$i-WRYG&G-_gpmeN#NRtlB~7<=&9AK0+v$tTLNsAD8ykqz1m8U4D}WSi0*ct zGdXsiD_fdcx=QSeE@o8rv|y@+HJxu9C><>@-WsB{Js;;IA>maREOdrED;jmG@{M;P5 zENIq519E(OTYC5_YJACxVBK{Hx#;u@kjFKE6c&WB$gGR84>v4Vu_L_bC8ayidp;9|`zd)7ReoYY%u#ez$|Tcb=ti zyEzb3p!W>nS(`}OcVI#46{FCVP9Hz32EOoCoyA;z-w7gMBW!(Ww!Ozgf73Fb4{*?Q zQSjOc(s}wRP< zv^k4^evj^Xq2FLcg~?xv-M_4b1NMuH!&r`STEZ_`ZRViC8e(jY~dqqZ6 zTK75^u=YdsBN^?t+u&-NkG^6wEtt6!CeQCeqMk1l3!&;5ALrGM4f<_L;M#3vxeg6e z9Pcmk8nPcrC>=K#Ct;Zy(dwj$n+~}zP)1iFaAK7Yt2c|_CGYa@q8d?bLkW^VRhsgU z^sV;kEzLN42wxOkw%2^TFZfj2sO?e@~l>Xf`=u$!GCyD?|~0~ zr^2`x1lEK>kD!Vn{NkQ0@Zk_Y1?kb4(h-!>GXN)zP*aXkD<5{Jf)Q)-+M2Yq0t`0Sm?{npm~ z77*}Xh6iXY5*SC6v9KW(h6V8YcH6x_$xx_DZv3hLk!+i&=fm0~VDC3+sGSy2^zHuc zzmebmUKqSmH$4h{g`BB?I7QwUX(?AxNK&0bxfxB=ZN2x!PEO|Hay_FE?EQ~o70x%6 zQ83z|t@}m4RF-{RNM7?R3cFcsbuHo+=yUhu=uk3Xf51j7u4DQl<6(XI@45qvm#pN8 zAyfzL{vlKbiJ!uhTf@^|Lf8Wbm&6;tm_oT-mwDa*TsB0H9{%^Iq7-66Eq}a^{=lgO)4**E;`=<|9uz!Fpi9N{OiUmFI$}tU+uOl4@dB4FCw5L z;f+eEa#~Ej?Vm4;9xs*Kaer0xNJDv1e(s^3aX9QpL}vd0K$mOH&8 zZ4<1LUX9F(=DVJXqpb|-@VsTfAd7ZKMriY=giw^QNB%3R;lRE^Ryj}z6C43|1b^?Dl+crh8HUB*KTEcZ>BT|!Bl zwRU#Y80n&vnW~0(f#whQ0nhhyb8|uc`Kumxae>^0GV3E9UjvJ|Zy_X;4s`BUPlxOM z_ChxpSPMpmiOiB0=Y2aiws^gY<-_ZGG|a3?Yv# zXRID3*kT`Rru9R}ouc&a>oY1NL&;K~DEW`M-vcUY(T44#qx4jlsAuRd()-Hr9KAm#ExE?V#^6v%>*`&D6*&`DkLuEVp!;WM8$53CWuF=>)-Out z%O$Z@vV=w5U#ONcDqX=w1GN8+wBLXk6B!it#fp5XkaGkJlf_LD0w>c^Ma*(t#)Cg@ zZ@bcRNwgOjx>m<3XC-*wo$$-T1>Rkw!21T&moW=g6nf5nk;NT1{Lo)nE$O}(nxNa{ zczkq3CM?V^IT)42LCg^>69Kb5S=kk>EH?qd$AtrNT1vM%(YT7`*5_-RdygH)hkE@wO zT`S%FaUBWzhYuU&!q0Vuc_kdxh?(=Pg=JpQC6#$)$0JKi``p|qx-iruBVFIteS1{T z10JkYE4TE` zc|f#7+BPxTx7$A0U8SbVofl(5E`E2lHPv4SQxP=zdN$^RWv#~)!X-Z02InMx|*f7dokP7 z?_gFU8LtEqrvd2xZdlTv@G*yl#8D&zOIyY=b$eyNU-j5ZqJiPi`{pR%|JDXgk6?7-ioT&w?2AI>e4&zS3bKi8&H5VK_PVrjYCk=9g$F zK|d8&+7B-;IWU#IigM}H4NgaktVGk78s-m95Mjg->|SpHPe!CQAe+sVl`$XB0muv0 zrnVvF5wR8x*P?v2q&whd%u|v887WXDf!pI%!pscDw7ui&i}ctVbZ{5gVj?q(&pGHp z6gY*!M7t93X2L)9X$h$gVx$u*z7$ww`#{gh)1m@}i&#Vq-VTaTR(u5AoDNM3J@2;q zVoYc^O6&ZCXL_M}Rg}Ha@#4$$X~QS-$Ce2R2wOhf28>3pL8qnZi6P((my%VvywYGS zy!p$BbyZ;&^hQPn_d>**>WxvS0$^p!9;)1?jvcInSV z2S7ZYLq$8^Ai|%%LEee+{Jru_-=^LMt?z-aE$5v^p$UUZn)Q$qT^;usBTRXinVEM> z<`1{|l8a7=SJjB@R@<+0@?re|->l^_Z^c6Tm1QUEt>9#&VlHdE_U&FqK0>IOzfI1- zeANDk#x)aeM z<1&91`r%-FJC+uqq$ICkAtEwP@+MYT+|0#d$FMXTOb|t)^O?VA%j570pjL%xZh8u(5N$d5}|Z)h zgpzsg)Tbgj`s`FPxMDW#r6vBynfVTnD`cW^L-pqL6aCM|{Ff&GFh5dZjy(GG=(M6C z9OysHq@6?qY{CcKm>R+;aF1&dom(Uys$NY{8#619VL!pwd!rRy9hpBL zue6NR*e^x1_09_>GJ6o`S5`c?_sS9zwNsk>C&B4{Irr!5*Pcyz+cCcf2nobxxP*ZQ zoE+x*Ee}|%x=S+wR9z5Amf2Rg7)V;Dn39Qne;bW34RdynJvRNAgA+;hrjVFWG)qvp zJHER9OU-n3e>=)gALJiS{r=;XCb~B|R@+pu?RUHP>ybVTmh&A7iHSwr)}daZm7Vc= z0z@M2tug(ZeTB)Fs=43|^a|_mfSiQ8ullE9Z zX(hYbg4Z~BoMunZ_1ynXH6X7nS6V-AFwrFXOwu1V(B1Zpqx`<@*8T9c|Kq_0Ca@NSDh)8=FY* z#*W1+Z@iw##PU5WA9A}_IZ%+WL)vFv(+4RrT}I!+%-q=AhmQIC;<*Q}_ymOn{+x*FmhD4FkZZY+K#M;q$KZ ziwB=Qx0?rcaO}?Z0Hif|i&w{k=lPr2UzK=3-YhXbXJ1=cY^jn-MT#%>enP_J;~R<) zsbwJYbyr|GLKAs38@S(AP+~G3P$57QQCDFAlf0axlVS#*X8)p;iOQOBon*VY=jpI` z>2L-A2Mlq(b)-%dp^qChCS$-*>|$`m9pP-fV~$)UOVnJ3=Q;hKBp^O`e-9JXed>&6 zM)4;j7UPiOx8lFH_W07os8RpsOw<7WBfV;|9~NTyD>U$V*fCeL3QhR;AD;Aa^kIw` zsSS+Tf9{C6zOL%*{5;wl9L||PEq$OUIMrQ3Kpr}XeUZXivZZu-?xyfRY7w%MCNgpy0#BSLSCQ#y&G}Gz=+WBmP;ZdWQG+So z{^A=TAn*<7TY-uFfn}?B!_qU)!98((u@mM}XPh)sMS=bAeL|3!e;ik?=x%aR6)J(k z*dPTBg>p9qLPwiF*kXD^gf;LVQ*;-p!i~}BMJ9|^jO`i0Mn4Ay*oWw7#)a@J#E4C> zy{-4~M(fHcGQG9E{p;?iW=f-{?V}Lcd8vE@Qg+0}$ghh%7I@Nyy&=9v?RP}0(53^m zUhu)s*Z(gSDK(@jESbV#t)htnck;Qt>R2qPmy_cC#mLL}p23;byi%)7?KWZ4M<*qr zd)KFP(wQ13w?~Lp3IRXwB-<{#o{9c6-P)l7f!qYW?Ydg?MsyHS=|oI_-qaq_M?^$8 zAi6>Sz#b@>(7C%z>CUTPwnE6s@wyua^_;y_jA|K z2~b>tE7S{X-+K3WS=BEi&y^X{CZJAyg_V_^%l#pu;VnwS6Ktr!BO?KTv#{wlMA%+y@B~JR!IYP7*v2T!Xv&;O-D01a}P* z+}+*X-Q8h^`R3mH?)QFgt^RYSS9f()oqhJ+r;e?yEew5m-rRk7uU@IY8S8g0a}Npg z>zZCD`tg?smpaF#r%r45c-at_)u#2S>r-91&HZC6baPBeJZ7Hmd`=v^=W>TTf_QZb z(a;tWPZ&Ex=qW94K}vjfk5n?9@84yb1lK>U3U~%(ClZ)Lh9K$j{HJHl-!OIfxP-iR z=K4o9R<1?Bfs-0~KqnodxXBGpdR|X zF5lCK%q-vax1_i{H5E&v!?)%q4Lz}-tL$@wDelqHMHe;$%l+tlZJL8L&z-qrKa)3D zPJnV~zj*`&iu%1Fg3vt)B~qK{oFZSpMX4(El#=u$IJeUEWnmDNeGd;kR_?H#5jfp0 z+??P;7N{;cmh3o7hw!}?KtJy87)C?f?gh)E|1R3nft24_)vw5#a{gwi(r=$$Tf^d0 z&faUZs)t3J>$l#@Q;{bajzsilJP31xuHHWPDqni)*W!5zc?9 zbVP>B*F@cXfd1gEl<Cwy+P1{ev&p+Yj{#1AT*)XXs;998?&< z6uyCX`fa-EXUlQGtRVME+)>atoW1;P#*RbamN|lcYHH{n(N^Z*OB7aior{+0ExVr4>eQod15Ly zw?5%%eY`+TzBxEgA67M|6!4N*T|rr4q-Tx$^Ne~gtm8M#CN_>}<5Ruvy^kfuxPbz&eN0k7>kPK>RM)k?iLr)LqUXlJc?1QVB9 zG#Ghqz4))+Vpi9jRXwM{{De-E6z-(3VKce#bdDcGL(7YLoG79+e$Dzc3T8<_X@BMV ztCh9&>m7ic@*BOnL6uguQ%r6u1HjK3HEyxWK$0DnWM8cN(e$(uJW>lcf%f_S`8|L= z&zd|wi8@ZPbcbowZ}tAX66b$QoUPqx_l7Zp@3@AB(-RYchueU-A+7ij9-b;0r9bas zY6#N=&A6divm3&YuP&|WWLAowt)&8I|gPGof4<+=zu6Ac9`cVZz#N8?(@l5)f@XsiJC5S& zaV-(2mA=G5h+GQQIyk3=dy5sT0M!DiBh4E`B zQ>0Z43q}efWykxSYu9Ji@?D81R;|MYeM3xn=$F$#Xno9uWylxg(3T&0AU2gB`O0SExZBS z&I=nmJ1a}ukO&EW=qkV0LQnldXjQ%Uqx6%L{}=t{z#=MA%j#Xmgtrj8GJXwo4fxC) ztd%OxH}PEai5`FZkdOZyZ+W?iekth%dIvz+*()5hY?tchzt~Bd{qY)ag&~@5Y^n^p z+uI1$;%VSaxor?!D0VpBE`*NK)is3#jh+>gM5y-kL-45@12n#aAjRqPv4Cv z(Za4uG`NvrEg8jGH>`H*_g}g1Bixjl&xH4po(%VR zyWHQrS4-v@vwCglH4v7&a*KzC*61r%OkX^WtKOA~*23z8Mp_3jA&cBVjN@FyI`al%}b7TLp&JU{5JelXCWq?Kj%$|G6_!y*Ps0E|zhRVP9hT*?F6d zlw!2P`EaaPTqijz720;dfW9(AwC`$#O$L-gSISNn_ww89?ls;m>Kb=)maAQxc{hL? zA-QsCw-3UU9yo!}C#1Wj4rfl%F4Gx?rs9fPTy({a4CKPmk@}T}c8BUOCXJVGv8Xe? zn%~9WPl=6BEVsn)E1}|}VU<|8sc+n-rNIcRKV@g;MJ5skl>8u5WsUGOg=I>1^vs!D-o4WSwXX&cNPqTgn2R%oh`Q5F1| znd@r%B_6UBWgsyZHuo4n26prrd3jaGe~Y37s!{ z3g5hN)^NmDnEs&xq4_066QT0T>&650uG%4$^$k?5k7oN50SQwxYgmhE0?~(QDU(_4 zU!-?EnfjPm8^xMBG?!YsxBTwQUE1v>_*{_1WSlhjE$UQrb<;I5ovzVU0g*s9n;P0jqZYEh!~ zi7^yQGdD>ZDqM92%t@jiijW>>)PE;aiP$Y~wVrHP z5&E{%_>atXP#}bMds`4sIWt+ma+Wo7=K*oVbLB(vlTV+Y=cA=B=0;Qun{6oP?U#1O zUuo}Dm~b;_sxPdLW=POvf^%+=0(T1_*>?td#o{L#bWweYUH(_^f|ZDqns5D{O+Z^W zY+C9AgQ$B*(a&}wue~3HNbLWRM)`dp+I44t0PrKE!j_Te-I3$o5xT>AcfCI#{AeeR z6HpQK7xzl_xF6K#*$`q>$9`FC$k+pfIzdHYLhjO!>=Fe^g30oVtn2C^!#=_#Kyjdf*CQmAIP! z-+!d=K$t+&q!LLk^3DuJGc!yp8a(X%NcJ}qst`Bq5V$Ptt`Aa9e8^LVk+ zjtjGgG$Z!M5DgKS~*3O zKpeYDOyb5@#T;tBS-tnaXwOvl=6 z=!xtd4{>yNwbFpBmD%##T#e;vl?h0KpiAt(a<{r#=bNH+cXapcnM%SwrOdR?n+P#K z*u%3snjVc5an3Q@adRI~f-ES*qB8>hFMJSM!*W~f*56Iw{_CO@2x!bv$`p;#NX0!s zb$`!P_XTk_0UR7_BJ}xJ$bSJV4SuM6FRoAy``UuSDyQ7<#HU`t5Vx@RpFYP|>eJsU zy+7_dlR)z}{6cznRIX5gKE% z0K=TH#(hYjnj`*}mxlCBncVp{Ta&w{iGhRqstrnE5LN^SB?F>rRHm5s59{}hC{46^ z?MUP|ohLi!Y(lhehGa9|G)Ngw*}OuNLU_Xw8DLM7w`T9d$5D++@i@L+YNqRe98)ur zA$H2`mylDDf<-t|YL)6g@u~Eb(7hexdbq+Iz51$6H8u4B=wjt&@F~eBdgCb@UOKCc zzM-~;hx^=K*<8QXsoiyJ2Z63@R;sR!5a;O?1^tg9KPa%1%R$@VDmq-^QsHA{(6O0;#U0n!UbU!RBpMBk;7={~=B7`|qbjuThP2*ZhEG%{#4 z;$GwLO4jFcr(OON2-@^lmYNtN$ql2r`%0Ns^d;UK8|`d?BF=$5t7y-9!B)zfRQvpz zp!hm?Y6IHo=>vZE1VCt3z}@(BL{Le5ag9;+BRn+s9=}wQdgQ8#&V>f>+aq1Y!svd& z7ip!-{eq%1uMt*4+hb+-5$-<66Dm9@U-!^ls9TR=;9tgFeH`e<6w1<~^r&|gdpH`z zBrZy*68c`kaWjuk?3P`EIj;P5>(^{uA}{@K0%(j#s8|QA410DjA7{6r@z!8jWZKV& zzG)jVK9A4vIMwqq@vYYu&69|`#G6#Nhk!|e9;7*Cgr}Isdz*MY-C&iHvyM&PJ@9{o%SP~s(tU-dWWmSXK(<3fx`uFZp zz$}bSd>*7;ot55IZ_mz$vj@MRy`b$Urd9&AE4h6b;a56+fwYs4tc{835*i-l{p|YM zgz0rhhUUocT7-~+^wKLE*JZnXZ+g0uFMaDw9g!SF@sgGaJWRa4zLEVQ_IX9Gv-j&% zoh=Anm5nLBv55my=MIA|JX>+#+Ypmd{mJQRN`)q}06)$-l;EcJ_Ry*{gXU6E*Paj9 zfc|9lLI$S`y4icqaz_() zIoTUfIQVsL)e+56R1Y zhrGFCrN0Fy1eCgVd4;QKX_on*WP0tg{(}Yp<%_XYg2t~#Q8m_fpRab8m z&3C8o-FY5J&l=GP-q=K~T&cWtnUhnQZHy571%j`pH_UW&EH2@*qvO;cSr|L$i|mNqdO5C?=7lNqkSr z!2&wH%LEU!5ev@Bm6#MW+TVibJL_t6yGr`=r*|(yuKIM#7xkh%x01RYwTB%`SIY>I zeybAPAC19U1P$ zy?BKMY~gfLVu8@7P8j)6RAh#zD%VuH)@+R%F?ocZ7}5K3l>4h^WMjQ&gX+e9z4;af z$UW$I>i2}J8Gd42jFP9P*>AR6o7qkBjnCI&F4ooeJi+|QzSQ!cmRK*?`3dD&n7s0G z#OZ9dlr7Nu#>tV#_4q|GpCbqpVZ>86d4zs;;t(tepWX?hvPdlne7>#AT`Q_DECk(a zOK~fU!DX&N?h7!Q3xj%QRE+jXxfw5xXG#7IpbvIt)@o3!EUt?WOezaE4#q~jnt*6R zVU{L}MjNKx+0jm+a`*45&P@P671dd6G=Mg5$o4P2GcScweD&et^n%S=j}Ma$}l` zV#POhCaHq^^lMb3f=J&W`^*4_tX)xHHhF9U^aO&H;J(!0f4;j5OiEetLXT9f$EN%! z2!+xC_!P|DeyphOdu?hH*vD@$flba)IwwAP;fwnIIIIgTbln@b1N0ne(Tcw_2}9?Im-?km1Q@F@zqaHlgA zww|u%g*UK945e+NC7=9##KhHd&*1fWB|Mz;og^3__{ps+KB0PdO0pzCQYPUkrAm8o zW##Al#%b7r&TZU|=my73NTwR)FR<=}#~x#TLAvSa3hti2-NF8jo8Q+H%Q zQ;(q*{Qh~&$9RV)<0_L8@Q`{tAaKmKy&Fb#w2tmWpmPZ>hOxBd{9(i3!Iue*U5$_X zUIXeI&2gDb03Me!(=)*#_VZBNIV92ogW+rao!Gz9dqwjQU zlT~`1AAXv!jlH*h`g&x)SZV$FUiH^^r`xEsbe)x{UYu19@%9s*`xu277@vXsNb}zT zp4$=M3-x{~!I)sDI6%$c1xDF#KYi_v@%dXhI>N5|B=j5_~vA@UC8MUsqS&)$KLQ^6GoI%%BO z?|Kyo1^{L&?)R5=n;jIQ!WdOgChiFR&JIZHnQ-EPK@Wte?2jT3Fe0{Dfp(?SAsx%W z{Za&v&-11Jl#fOP@lrA8`L@rJ+4bnCdO_WGIP|ow#(%}x`XA|8THcRyt7+D0fE*d8HiO-5n ziR}bB1zjVKs!Gh1^WHsNzD1yaU98M^xB2ypn^7?>^fKh@C7}P&i*_M4%eADEDS}&d z*6^y$JMKk}3%F$qs(^p-w!UFsb!%v-3siCfC&GUcT?b9I62RyVF>lyPgAqyOJmjI2 z7b(yEJT5Y`Mov5-KhPU9uov55bf;*`PkH&}hd&ai4uf-T1z}qIm;P@nmlh#7vCJ&dgOCyrCdWKT=ymcv4b&5 z)xcj$jWbLKuf|^wJx$hjM$;Y@??*h34A#zc)XW7+!VgCg2D)cBFGXXLX1J?ms$@K{ z!~^?mbG*G=Q=}C(ka-$Zti|K;Iszn1UtR4MwC`cT8PQ3Q~q0^cNVuw{x+xfv9 zt?F%Zp7$r%cUKqO*8#6D45K4YPh(#c!=lLVfZLtkVS7lL`W;TLK(C|^*=b1#BshjT z+G&qQ0kqM;@*6HCd{NIOqunF);+MNPF)tb#q<`@po~JlNq(cG*TKiiEi2cRy85T>? z8%#I5B^}Id*%~)qPC2HqrqDE{hIakogTgw!eqh$3>K-&+fMXB!h3-Hjo!;FU$T=cA z`1nS2f;uW+!JL0uw_uhwe_JcNP#vJpjjDnjI9`Jahf)~B2u8DucwY#=sg!|b?#HPt z+yi5?MG@)jHju)m39?}JN6IMzD=j}*FP5SrnX5hC8>DrMURxd#5rOgo5Azy4S$PGz z256TN^0UAnLr~y*YbzUH=$l9Z>qI7#yF9mE)IW@X9V=c4vt=g&Rz}$=aR4H*zT-1cj)DERF2 zDd=oZFCQ-+kGRD=e7Y+>OXa|P!9Eb7FTx&ATp-Ock{!fp|1RFopFi{Pb?>bKK}h^C zoQOtRNCVEPZoFKh73co7Oey3@?!D@k>5-lRudvkOL&E&AYoT;LbveWY6bkY4KBOX& zo_TwPUH~35yeC8+J02n9Sp1S%v{(X%%qUoBk$EOWi~h{kIHU_1&QgSg=#c_&7$|rQ zW!8%RM#)^=b;dOnDsKhl}8tOBWYK{>S6P8&sQ#oFTY)mx~2k+#mgBeoDcCC~Vm`Z|m((rR)hV8+583SHG~7MNJWgHS5>xJM zl$&aX6WrP(`ZvgTbgM>yvRyN9@bC;X%xA-Q&Mz$FC@6$fi>Xr5t2hrWXp@!Qsy;5k@TvHSG)<+| zMq7{pypo}=xZs(PpF(#QeZF@}s&c6Ct_xtTH#i^em*GO67Xu9oOMldQ-#b4&dN5K1=Y;{4 zBqqqXya*y==62Q&&fdr6;*y@^J`VG1Qah72uqYiqJSL^srg#7zoMMb0&-!6Q#duFr z3-k0JP9xZq^$bp-!g|I5xmuf$*}0i_K#?s~=$$zfBf9Sio(*ydRhw*FSnJfKy0am^ z3wrs3TX{eM8t^@uG2~U+WroPcX6v48GYMyMu1uQxibJ-0FG=ovS^8NqpyC-aIM|5}c$DGr#txZgFK64HkqBv?3k<_5B4k&y zn3h2OYQY}_QGL?aNe`C9|F2UaR-xHrjqcaJuMe5uq?OD9ona@e=0a&+(X+3h#?KEE z8?cP7ck$EKBPLMaJ=@gPnN!kp`VwJaeGQoH3+*wb}dcjnjF zB6*%Nyqj^*_H!uiAw_ukptO7j`Qz=8<2#GWMc}w^4-*)w+0jw$YOz#M%I!x@MION@ z2c11*0>hknM+7((UytC>^f0PEfpj@5^p7g6Xc}Uo3USyq(6X;!5B6UdH0*#oohw6~ z5i4f2=eZ76bs~zLt19|Jyt6_^@gF|}`p2QmQ*!_?iCnh=B^RZAET|-o2?kI`;MA+b znfrUl8RCRpj||6I`gTLBkGMqJg%-XYv_d474V5v&2y73u`R1pUI= z=^uFi@eGrLsii;a8FTMKQDSPu{iCL~-{E9ew5NpTemf5T&oKzDnvfaB%}CXUd18}4 zeG1)R*#QxrDi6vxX(GJ)e{P5;qo?fYK&1J1DnheP8B?NMzvQGus_Z+P8YzM;du90l z4uAHQpN(j~%pWj9f*`j#4T4#KVu33ruRn)kYJl_1iVTg3743h#e?}Yw2El39h*ZhO z`>q-3FWeu4mHezN@M$Yd=2E5WME>9R*Q}e04AC+bK+vu>gdHfs8$B_d#6Sr%Ce+#e z=S{Pf(6KP&K9VQ15UbC_OjWwwfB)ltySK+Rnr1YFnK9b?pD==Z^N_4? z76jZTHm=bzzsH#p6BB8)mz7mi1a+2`o#g2>s>T(Hbw-{SLqIJDCY{ldp)^jZ0RgCG=VI%Ho8fp*^~^sl9U+wjlm@u%N2XRw@D8ltmb! z1L`b2=?H`JB_&O)$Q3k+^`H3~>l-OPY#)eNo+L}>zMI1e3CuNAjq|1GmfdNz2B*Ms zAhsB0ieOzCwrV4?^rZ+ycY8GchDo1(d>;~A8QJ?q-^ASBJnL_e#0H;;$xv&4ka1(* z^Ul^Z;8waa;?|Z?+W5^6U25XiteMjw$M}-%pBtLD$GSBnvg3SlD{5)rVbk~NLAQ0x zb{T+j{kvZ2^qT(2yfGt;Z? z9!H!1wbQ@`7JNBIlD5)xjooLk(|b+u32geX3#M#CH_!jHC6&=LLPQ`pn9gVawP2>G z==Ve=P9efEN&!Q>ld=jex`4JycVJ$1wMswO)y)M~zvt%S@|lMxAg@WqV{{HyK_VJv z`vI^Tp`&1(C63xCtC1qr!Gh!M0R!kyy{8feQ2QE##c3X9zF9}NHS=d(MkX8Brw}6& z)mgB(@$@QE;VGn7EH>;oJSmJf?<*yY&8m*gRCQ5Ey_~rBS*jW~zu(|no}A^2spJUx zR>3r2aWl9kOz=Z>r`gRD_#6wIj4u7agNgCR2=%jqPUU;kXAxPF{dt&uv)@VA6f{3j z*Ie@UnFrSXwh>J7Id@-zR=oYsT!W@xp~hkfIUO)kzK=8Dh=6!XbBZbr^7~GQ-pLhe zH4_apRe9r(#aM=#Jw&Ac`oxj4%>U~9yYqRgbZqV0f^SDIY1yC5CapxyhI_FHIbNTi zop__T4FQybq=BXpXe43CQ}{&5?xvr#biBhdeqoEy&=QWU;MNb$&akqwuB-}a>uAr+ z&ZeiQeg7VNw%*#<(2nY>%9Z$HK?+n0 zaf`r%Hs(HVcxrok-gNqlBAfB~Ax3mvOrJc(Jcylt`7kIW95I~VG+Poi|1;5f#B*#ZdDPV`c zM=8ugcMi6#qBX`+IHz$m@Zz{S*F|A8B{~zzLj2h^VLMd}Dks?5-6QiqCn41~J5WP_ zA*1mXpmDd=5P^`jmi;TTeAK_I93*u17)>e$ykpX|P3AU+gfD`Ef<(+HxoUNMbsf#< zfjj%7DM4Xa*SFW6;JvR_RwsAI+&50n&Q3QowKczf{W4=3YjHc*mX?-QH&fTqNk@Qu z5E5Kr`2GP7`KS!Fk}8VBHO55~CB2U%5{%kA#B;Z#-&SU7anWvC4~fpEkyN&0EHHjG zN&;v&X;Bg)d7c$P37uZ)qHl5w1r%@1B*pc-QykqnTG_G?O|k+?FCXfS9;;;9n5loe z4s|UDZNw1*2BwY{O+|GUEndQ+_WO?2c4^_?P1-AXDCZpRL{!YzBMYdUv>J;n#SIf& z9LjbuQ~T0=&88D#7^Cz)oXL?~?WJD#S0Sxg?o*`Hi>HFLyf1iaJKbqs@}dcTqU_b;avh&vJE=AQ7+kY3otg(2$dDt zoSolpnXLIy66{F8yIROD<)1cfpS`)>k=7iGF@l-hiuAG2Vtd}=B6Mniw^ld96u@!4 zkURpMtoWzVhq>TFod?QR(4PEuQ$%g?xK5_i#X`qjn|OXt05Lufw6awTWjIU(&$UA(F$ zKs}0jq#TXNXo0K2rXnB^F-AYYMUNdBE8U`q3`3Gt%xoQ4o1mv}>{%Fxs`~ELg{=OX z?7DUv2y|T%4oEPSvGY{7lXmFCvg!O?Ih-&no$8rfU7G?6WO1A!Q}SiB9t5@D=4&3i zXiL>*Hl{1pn19?{;1t$CmeDP@dtyV)ZS^uWZa9j~O<+Vic>b>jE2hqUif_^`IDtY;$?b7%B=zXL0=_ zZ}RR}OYyYTMK465TEnR8{@^XV$R6e4h$)38m|0ATHeQ@hprc{^f@+CHn9#(vz43$e z^EiTR^;<57Thi0H#56h-F!JU72dq*u?QBc8#QikIn}ZGX9D;@5tFXo1Y+^F6=MznVP?0w3dkm{hd5Ih zAFTinQXLR&Sqm(jOYG+Mvi0`nl_^KjC|xD9ZMAYp)nF@cfxoO>Y0Z9qylmL3{p&_~ zi;Jbx0Wm)9~vf)L?&!`F!RosiP793%+%T2p1J0B=(#S+Jv1(r-+S0>iZuN( zo0R{P&3pr4{MuG_xaIBQ!XJv_?LnWbQ|p`%12jSnj2CK z{Etc883Mq=PxNgb`-Q&eJ7Q2{2VIaX*6fHVbe6Fz%skCedT#yB*|Y7Uwp1s%yjWKv z^buJiYOF2NROc5TU~B*^PTw1w)mm?+p?!8{+J0V4%nurnXqmrbA@Y5P5{r}g1u3{bFY11>=aYeZ*5fLBYjR1 ziavzn>7!1xnNH()J>77Ic4!R2m4X%KGf^7>u=hNhc6M`#{5F z^^HwpFf9fnFhnI~rXSX#XhG3S(N0_Drw<<|sZ~2~1yVg;Na*Nlp17pcTM%OGdD!-h ziwVtNta_{|HspAMw72QJDxM_e?C-0?A9V#w7-s6-5fVY}m9n!G`m-jv&>a6dpFh#4 z7I+eWc=xV2wkW(_#IE7Zcyp3+1Pr0UsEhQ}294>|e-Dp}PLF!{YPUbNqBJ98m2gls zxzC25?V&&3<`Uu579kQFcwXzaMw=UwKj-m3Y4a*gB3V_Zk|G~h${lFS%1VgG{fN4L zqw=MTXjyt^LnI1MjKXk9h)r%I?7>X_Xt199xl2N`AzhH{HQV0o@8u3UBiYMKkX$#E z5x&(r; zU?L|N9&d^G-Cvld|8hK}{KSI4hm<7*@AUIK_>)6m!V)}wdsyD7zppY&F+xKi`KJF~ zFtecD_1him9{`W>bynSI8YE1Fev9ih>G{~F5c*i_hyUMc7PKG4%CwopEj@c!1;O_N z7X-tw)&-($HAt9!d}6$lWV72C4F`=PZH2N^_ke(lxB(-Yjn+}w&_hO1z{KBXl#hw& zy`AEk1Kyq#=PMb5WMN4^KD~Cykc>2P+NbGd7y}4jfvT2S(^7<*(yE=7%tC~Q?gEcA z^JApZeq&7_VfpG}c$5TpvRtms?Y;E$Y<>Zwd0t5{0)2eb(a}--hzSg`nBskF2kwMH}0HjW{{HW=!T<+v&Sg4-|3XR0b z6kNLteEfF7#*{ft*bS`^(QH>QMFciXej0DgB*x5ViEfa9cK-qBItcFc+cw-ra}33T zw6K^@zY+{;>}`*d8QW#?$Y6wZ^r56Wj+ty_#caWE>B!1NPfSv)x+og%`OOeZC^HgT15G+U^_i21bq!3Y!p;3d; z)CO6o53=n=&g8gMIA9~KF#jr33yjhHs?1n_MlML0Wdd55X)q$HUyC1o@i@?_1+Re9 zMeV3sJ$57gm*RK$&r<(f?gA8&GVm_soAK~@2-v1S)`Vu@WWk3Eb1~C51{NDr3b=|6 zp?`^p(5W+9bQ}XvfBJAN)m;n;dp3$ZYT8+R=`4c2&I11@0fmxxd^xM*6mj2gAY|85 z9Xq5*v%W!%!5SURft+M44@? z2hp$-pzL(XFRho8Q4GnK?V5@CT8%ymtj`Xz1j&3r*Hj2;7?4k;P5yRWhsuzTE(UOE ztFmNkU(kgRuFnQA1nMp?&)@HLC)Vtcgb_r=RW_++ctce-o=-?Pg<8Dhm&Eu2r*hG; ztnBQ5j}%NN7T0P=Ny>&vQM$=0S8`Jj5jxm(J~t_^x!EQ#M9&%98wA_r?t2nY>+ZrJ z1LNd;gqq9GjNiGMgCoBFsTEqvQ~%gpK3&w&bi;)%rhOvJ@!PxGJ&H2?fL+GAKT%EakDh}ClZUf1I~QMFe^6GSl5G1JIse~r(% zy2eI^R&kNwOwdNg3y_)i0W8Ab4;tMG{*ZX_0q-_`l+0Of*aXzmM=F+U;UvqnGvl=U z3VE$Cl_JFlM%-2~^>;PlvLIXlKqJR{HX3L{uuB}2(FKYpKvmkSg@i#eYdWboDA>*ac^J$o2!DcfX_0->9{8L0)Hx4>v})|xzZ!YJ=yr`h8>BE|ME%fl!_STt!|Ew zkcQB)MKe-N_tgswIN~C82t|yqyT?E<=Lgo9qf5^~zn_Dl$H}tJ>_PcPS`zkiimfnO zv2Xhsbjgshq=#3XhONm>k}=uM)m8N|_~&xYkxJ>Fg1t3n+!w&+rOMEcqf`PB8m7In zES+L~kq$lQNA2;D^&hCavok$Rz-Aq7)9W2-rb< zdQbJlo0vEKIhw+J?KeBQ=Nlw~PmO0q-8JCUj2w0q0u84B9cg7QVpzsS; zqn}-CBleVjzLBo(T2nVX_rE;z7nYoT$Pbqq;fVVo$GA2c2Xb7s*fP`;I=m_l`FGZ8 ze4bNq&OC6_GRNled2>bdto#0IkWV*d%vpyQc;jjGWn1e?*utNbrNAEoNJ@tXJsJ@A zGVMrzyh_N}!i2cl2Ae_)&f{mzZlt(8#$smeMsuYtyW9<$kAc z34Zz!uX?eqJHSZ=7A8)@GLBdS4k~g&(@Rm0(QZ{OO+_>*A=L?01f2rby0J0IY4oio zY^+e6szPJRkFFb`?O(+E$8_7=G{_I)NQJJqA`lv&|GooWv-5GdeGC7e$(eG!-P8!W zrR5KP!NGOCqTJc~sA+P6_RFyQLYWSWM%=8_g-BRQb_&Y)8qu@^zLisfh2aMkYkj;)Yq(JF)J#&3pV-|t&8TC6oOGsNfhQg4ee_nOzSGr^g>F8kN9RbZC zbgAf@cUp>QRDO>b(W)Qk7~Z;N-7G2cz41eQg9bHnltFv9Iu;g{GKhu013qB2a;@Ys zsR?u5tTzyUzsnFdoHwSzn6^mQ>=~lCE=Rjj@=!JeLYNlNb%jrFc(Ni(w*ex?{9ggS zJ9rJMqhEv%RxDkTO&(kVk`W`#Y;>Y#Vk!_~&!ar_(b5@(o6PtiO#aG?B;T;wLCc0I zFu0$aeAI%1b=0xCxKoJ`bQAn~gc4Z-+h<8;?lRYwH^PZs6uRIxGbwV2eMsD=G=hG) zcQJN^_`tZX!4rliJ$TDk%ou>D?_$Y?8XC%Uv|-~T zD04&|1gr0u4cPWMI1Aw(=8W6?Oj}gR^_rl2>Or z)&l1Htsf=$WcVU)q*voIC@6?frNw;BbvYWHCB>=TDKn=&;y^7oR@RTZ;?g=i<{$F^ z0Dn^cB1nVCIzvCvbv_p9L$c>@DGwSqWugD020*Q!7A88#=BP5qia)uj=P?2W?LJZh zm$9^(_i0$T#4WawitQUX5P6DjNpYLPgW)~@r4$5 zjAY8U4{GORI^Vv1kJ2{yoy?Fd1$lKEf(pGRsvh*u;al3~;{(sXaip*wKNGMdmo*oX zm4z#5cI86E(!&@C@&~2Lf6rDse{#6p$vtEWKgv+cf-m9~maNr(aCTKdB5s&-#hW&N z7DiMRURS9gDmBd#_4=87`Fq~yHLM|?^Cf9=o{!4V>a`Sdl7sgH!|L!T-0Ql2yu3c- zz~{De53u0NZY-w&HGG3pWxX0Gez2xU#pS9$OP}PcJy5RI{d``mZB=dwtUKy_*#^MC zPq-`Axc4$pY%SH8^))pETa(AS3Qrd5h#F3Vk)~gVl z=5Jqt`!&ZuPDi6=P(RpKRgPTfC9aLwd+M=Yo>`S7Pmnn~Om}4<&N^$eR05#SV@uG) zcXyqN(TgIYvz!nYr-bs- zH-1*D=j*ibPMcA2EmVDI+m$xEU4O4N+#K2yePPZA1bbaBQgn*8+%}x;WyYfJ&lrr} z;sUj{RPY`yYj@u=c?Jv*ll<8moh}3O;#EnMN?PUi>s?(#8tu3R!z_7BQEJB`>10$@ zu)$@J@)UlA>BgJ>eA&}hPv8GnCg9w4zIJ&hI=;=-f{ggL%qlG{ZAwRi=!UwmM)slY zyg#*}_;5A7%)3Qs595cdyQ-|7=WW$+{bTJn#SM>C@6zUzh_?EQ^Ty(HfIh1>!?`_- ztz|JFQ^WhX1@_Q?QQkPIwqvczLXplr5?>TnF3<1C?Ik10~o#r4aIDQ@dZ;hbLf zH-;8{@$r(R#cZKJ0%IQHB_5JL_FpS2FR~^sCK$DJdS5FCWD4`nZTD}Vv&?(zIihEU zPI@y5PVPn_Li2OG6;p{-Copff)#(RoG9szQBuj*fq@{{-B`KfPNmGnZ%>NtVW!yJk!J7v?wYJrnvu8VDt$!$!a?0!I=xAv8 zT@PrCQkT^vu_TRNo#_7_`CHPUF58YrpW%OnB$(>aXU=QHUm;Jb{o{wLs&g&A2!jM| z3ak&!d}BSYOI=3_YfFooNTgjMWe7=&brvv{$4M@pnYM>3zisP2tjugUtYJV#Yw;A7 ztX65ld9-q@jl<92`edf!nL~hfMavf~or}Y&FIql8AarVF{kN=)A3^5i%98##DXt@= z$yJ`B^CvLH6-SQ#|2`5h^MBP?K?fC&zoZKNQn>T#uI@vEn^_kgiOX->MR~?a*VCV3AGDVFm_y_Qhy}q*fnnU{ zosltYo4n=sFz3BI5tGkB|7~kFpQ!n(v`n%4%MzCi(i_mLIw_;M(gpD^leta3S7sMA zR0@aSlvHF}VJVJq02!ppvtDml(|+@PjHqzr{`u8V!dS;`e3Le=ADS025qKjVv73&5 zQ#FRQYSpN0bPmJ85Zh{;-F>F6eDOKEpr9eAgPV!UuTijzF(QUN{*9kXGtL7f!zdvo z$sQlt5hwqE&01bz3@mxmz}{_Xc?NCGvo-xFUbiDV6x&GfodnuSof#_?(QRtqO4E4a z-am9NI>7-_m2Wv7!N=A#l{uMj!{2xB!vva=gRDM0?m=p@|2B}{dAuhFPrz=LLv4Nv zpl4O{lE*bRHBnrP3v8L|9G z2e9l9N{bxm3}| zUeo7Q9r-d|jlLiEU-rIpKlbolZ*Zu2L4oKf{ib|1ndYRw)ch|SLPd3-DnlN=z7^hX zdbS=Ho$XM+a=&yodHvf6|G1nq7W}sdKP}KmG-LD{Z3*!Lq=vY=n7SbOai@#ZYWZ=< z+4RA|qw*s1rGw1KbL z=lgg!Tp6-Fx5UO1Juy4|g%pwz#*&mMtzZuUhyU40Uj(x&4x*~_0BkH^k$FP$eJRZss} z*dN#K2%71`z41G=K*EpbueUm5mDJDkJES7h;AZ?ARO8}Y9X5~g&YQzE6JdG*$M_!) zXF0#W8QhJmIGtZ^)-QINTALnOnOZDiIyit`&aLOMy%1*w&rHDVU}IV~mp%f)6U3Gm z7L?SrleBI8dY6Ql;!G*mwd!GpVG_(%@3}M@P?37RYpW}JvF@`rdI^HuAbA=l%i;5Q zZoK~S(!1g*%lsk>@A4{<;XG5-WqhLk`x-mf_4hk-`Y(mmMFj; zgFyU7+bjQccA>;U25DxNChz>xKW>{mc<3*n{qqIMSJ2QgHSK4I#~~HOh0a#xcN;4P zJRH{EB^n4*KsHNHQByQWBHlqn<^b<(1Ro@s+9kG$=HHknC@FKhxjk<` zJHf&#o0w?N;=DT#X#VQ7z!H!BD3hw?@p3z=&Z70^dcE^ZRbpFYeKCk#6cJ%d4;*tZQ9sE(n639s|Px`Wqq|)gDGw~@t_`1=} zThHSMiKy6wfT46(M(p~?2EW1HL1{Z6u=_ow?m!>E#$ta32z$#o5gQBp3G8#CHR^_1 zi{5x#ku(Pf2iIGm3&PLB+zs+tquz!1yyNO>2nYeeLz)BL=k54<2dqZl=7U6q^t~+8D4R*aDxL4IE^WyNMj)RFjTU#vk7;ZI5SZPQDIq^ttGX_@&Gr+IA z=IIWO)t}BT=x(9WR1oZw0qZWZC6)TL%A2qq_;oIi)Yz+tT}{xNrwxk4KVR!&9#Fp1 z-q%t4Wjt5va&vH45*MDd{$7$8zFJ+kL~{aJ5x_lDtWY$Acvtj6+kQ>)Un?HFJ1~oR zZjIgg@(#^1l@zy8#0{@-u=C0eEkDHXIysXm!YW4bFXtS^jHG3am`giwYc9$mZD!&U zaP6ym%za2+#HUhlq>{rm24!JBREc-548JUDpB!KK_|^)kTCN8HM_Se9!U~dw=;%YF zDF`fzDr1^M-}5%H>>f6%qK$XrS*yVqCqeAEkn(FWZr8=9JYi|O8(3D83&Tu7@>yin z&wU~miz^F`MfE?E*_44kv=(zqKA-vG3I}?Dp^B$%kO)BmcWI3~$&+DdRe$N8(4sgw zJ*0CwpkgsQt6Y^fq=on2cPY>K%f^xQfJ9=L&RO7=kJ>9_k8mfM>I+{(R(4{YC*6A- z$5?~!Q0PNN6rH_N0Rj!40ABZ?aaSz9OJ9|m|brYTR$qOs09PFz*jRC&y z&qkS?;1nuTPQsV)4QZL@(KZRaedX?sj=_Nw{rq!)urc<7;Kq{H#*`q{DH<97B8tXP z?z5IN{8hy@PZuk!zih)$L+Kz99!7Mr`2214$IC|Nf9iwD1AXW`>SE46u;q#}dRs@= zav}N6&7#yro8(enIhR)CI@39F_IIQS>##q{o$eS%Pbf}tah%oL)YLkvYfQvP+tXHw z4W;YZT4+tW)07pD8fP=_SDsf|Rsy@Gb?YT^%X*cKZS+e7OJ!T;6viw$?ypJxT*9+` zx3vgj(mS19_zftbBaVh=@eqHLRA$%QEzcer8ak=IgZ3hdi%s<-%#(PT9;<4-i%9iJ zr3GMnk{zCaRI@nU!SU#9_fxgra}*=wDr{!xYZ=cEG1T(RzptjbJ36pW(DeC$fnJh> z-6s8xoJ&Sra&~-7MmXTsVkSRGjlaXKr5O^Hm@vt?^5ZKBtViMF`ElX1pUk3X{^dpH zXFZxsA0`uU@F-{zVE~C|$A}6kKY%1~Y&W~9Slv(QdVPJry#a>1`qS?(O5oTBC`%Kp z<68H2$qD*AH}1IagZ%OPyBonAGs-X0UiUQrrt2ShPvMxlKsZ6rmOQ1n;CpP=xhXtL zQ`3S%T{&4;BdJ3E61kycDC1lXZj^QMTSi#dY)dadZr*!GTUk*_$D=IrOtD>|t z-j5JlmOirq?5Y;T^V#|B!Gk+$Bmscaj2Zf&=s2f>#!8%gXlb4D0^^gd6LTHCbJ5=< z#L^LiucOV%AWctVT9E$kF)Z!mB=i#HkNB7MArlT?%Aluw@@vsNbO z>1LhaoHXyd3{8oac5Cxz*qOiHL&?7t~ZvgkZ5tScAK~TOt(U{UKU;T z$kBT*v=@IwSr}^^^?q1PNWX1nz2D5giT_I@{4n88B$X%!r$Ekejr$~ymeV!#Dx@2u zKyGSn-kZd>eL$dIC%Iw#IqoD?8;%(X5l?Z%F|_c#&^`nuJv zls=j&c1%Fsj+grzrNYJEncPTr`kW}FlTxeE%yy>~B23xj7*hbp=@MT|to>}o>HBIF zwWG{rQgWRRS-y6sZ1NvFOWA8|MklcKW&H3D7ko->sy{d^Zdwb&3_43^&0%fD&B!%8 z{qh6BytJGy&nS4=qTZbkyuh9UijB8>tRn(K`Lsv2;Am|d4`PD!zYWjJI)~(c9Lc+D!KKl?ZgiNg5e!ITj-|gghc44RHEWAj!G)1ytUf0Kr z+Fpsh=RX+uu*4%Gb#}3HlKqye&w`|R_I)=DTQl%NL`p>n=W6XyYm>~Mg!c0bm(t?W zp!R{fGx#Pk^Sb^nlt7gz*lBm;tdw)PNAE0MK05yacpe^HCNR9RO)8~Nf6UZ4=-5LOxWEMHT(^@4 z_F+Dqgi_j;%+$h)*k0cbmOXfSfR^?Tz&%MpeSKrk0ve6BM{z~Fyjt=@=k0U?){iG3|$giXB zOfD|b;oxl3&aR$87g;uwPn(+Sm7^D@OJBMQKcjYBbaDpOtb&rFx3MtpR(4hp9p6|z z%wY^MOH*@$V+9+j5(rP}9ktij(zL|Ge@SMtQHZeP_vs4M6gi39>&vwASftITvj}o2 zFY&SG3gT5^!fxnsQx98BB_EocMFvIhAWR?ci|@8@z4vKB7Qi)y%evMX_qiae++h9Iy5*fOGVWR6J_KkK2uzf?P zt!^?oP4_nEnb|?){(SYJ{MI{oVLCfkp7xG$2n&`^FAQVeMlay3FIB|g&`Vp zL#d#m!sT{%{&;U{d0u%F9R|B)9G$#r25ZQ`Jtn2}JPM?Z4Y4%sJpaE0RFYSojQ=;k zRdy>GW<=bkFiFFsm{IlARM6Hpp0*De^`Km&{e%aw ze|V_t!mc5fH2UOLmzOpFmwO80mRoeFDd?~UmH6h=B!nJSfaN4cib|Z_Qamm4DlmFi z77N#IH$8N=7rle@)8IxO8gO}~x;E#1Pw8qH>TkneCW|8S;q#PI?rZO73p|VdgZP1f zwGZQK5OLV8_-5*hTBwbxp)XUow;`-;ecwbs2e4M^c(NW@xxb147RZqs-Gfcn0u!(B&Xu`TsoZhrkV6@_=!Cp!fVQ{suh6DYXCr zVIIMsjRZn1IvlF2e=O?#|BIn`nY<735+8LN4Ltjo1W?EfvixC0PAVwtO0;J7A*-GTjFzz2Kn|lmH)~`rTlH(QoZwC1Nc?{soHd!{9&s5F%Y#} z-)SDe1Sz#rrLGdgJdqk$^HYmBk>609dG@^Z_{PU<>V_%(6K1)Z1QEnC(MGKqC33Uw zK%_2Q{3Lck^7z0SmqmZ-UOe2!V3N!(q@By%)3;84%t10Fmjky$9UR576r>k^KNv;{4i0PQFW`CM zkz+)zxpxxxy(6h20McZxEN`7Ky-FEB1xBq*K0-v3IB z7t>;k!#z3iZ}~AWqX$Y*31KX#!WLSyUj#DA$&WZJ5^6xd9u01SN1^4GUgeY6D*c=jDPh>CBcfv4hKy*?YeU}31zX!qVd*CYLuD0WvAS3hYj zMc(O*J2%L5X;@g4Vj{YkYyd+S+3ket{!Og)X3p&WP}uq~J%V&OfoLTfe!*!13r?Xo z(})ykU$n9v@d1ADs+Eq{Ou=ZRh3araRp?p|wp_f&dNKpCH(Vv}s!s}V?j$DqKs$BUhKc6_GCD*2-&x9;R>0aCc+$5~1tei4%c0BN9n7MLDvFje0$Id2k zhbq7PF8V1ECmemm*msg2m#FZD4(-oq9nPH#GSF+k;jKvG0DgC+rORiGFxB^YrT*bm zu}8+McScJ{Th8VxRz!jgT#fqT7jm(bfs|$8CooULF*BZI9*Qzw7<3RC2@}1xj%%5u za}jF3%I+<0s0F8HSi+6qSoYlL4W3O(Tr#v0n27?hnQ%mXoNV6hRIp@thQ8fHk4h(g znYR;vJR#aMG39lH8KYfmP@nX zJlDs?RmCKfD!6u`q_m^?ltk8;Qmq;(ZzCk?Wgn!)d%4!Z6X_*Ut!_{03c=I;O&5Ll zu0gtdoa!3iYw-kED}vRvrWP4s?O%K3u0J0;e{890o^Q$WVeOa0XljEYom!e=9wvxs zZ?avtkY_+;dbMx=!N|X4!E})+FVb#nC12)!qR{n`6+bH+w-mPhj6M^?-e^s?Fl*O# zViN`t76~Zj5$^ z@T4=}cPJWuUiPV5HL>>JGrqf#EMA>rFE_&_!)3cuT1i4ep7)>Id)Y=P7B(FYy1nPa zv#jVh9QT=kXxg3H#J583_lqH$;yvuF#lI$z@U8yf={0#P@U{2miY(>j;pa}ycf;Xy zMQ~~nV2ey>MdIrE9BtSE6wy`fVs;#uC1BkGawf(l(PZ)#-C(Yx`?P*j_!oW0Dy`=% ziLqg~yq9jo)r@a7WC-w{M_)n zk=)t_T{{)yO#p4Di~0ehGw5UWTkqzRGLWG_xZmR5aklM3SgQ2#|!PYS;;CQAAOZyz~>F}n;iBK9HB46fP2L>~b=0~NI z?en^si0e)-yBIw}+*XchIx{`x{Y9U1LySS2i{H zE3VTqGs4n{7@8WJ*yAzKvB1&@SX)@z$=m4ag9Zy4I-2Sm$_ews((s$w17r;C1gtG> ztgQ^K?D1G(|9=w(W+r+Tw*So-&eok2?_jdrzQ;*3u+bEc3xF!qy*Uw#r=&mle^Be&CM>GztRC& z8)*;oIX4bd<}Ys_Z<}7@e>xAK@%_K^L*wT&U3lDDVLm)S{BwPaOLy^fBh7emi3z$3 z`pMDeUZ*_WM+VjJe@493>7;F$`~Ef7|2w93GR|Y}KO_AIum>PIGXMEij%^U4PZh(z zf1&B!?p?+C&xOgFE_R#z)j97!|IP!azNHy>iSW8E}dH z&!rbQx$;0_N+^|P__{!afZX{mtj0_!*9~TSSm9HmW3<>xJFGg1Aq#7f(vr}j$|DIT zJ5=!4Pjo$f&BjL>F0_k{500&u;J+Vz3QJg5{MH$^Pz9o)ARXldUHeFzi$eDz@yuaR zoac|6)9Y%Xw5M6?Bi3qtdCa_^YAgT197Ld z@4psos@^xDHs$}GR{sqYSar%8`x;oOd$Kgd#a1%6w~*Wnw2=o-Rkz#KXL%Z^fr0GqtP-{7Mc}TQp2;1{mY2x^4CIcy6@)f_T6Eb z2oHN7{a54vn8Reuep#@ib73WQxp~+)Q@@5)yYH?zSD`@G5WVbKBzCJDi1obG)?lWZ|=!W zX_ntqdzZ8D#_QE+xESiEA<>*+&htv6yt0}PlJ)r!zhooG=XssXc-I_r z{53PKFtGA{Na!L7W|ayhgE4Z+UX~9DBZ>4+u;l9ex^3^CRlGq|vpO1s>C#_vAJGD+%(+)}H&9Ujl=v=}}YI zTJ{+WD_P|LJA(((P#c-Gek{Asj-`Zv4W$ges4GPjaAhtBu-URuWTq&rx@auApnb(M z7CM9#v7kKXx4oj2#~Sd}-v!3a@(X;6yk-%GT$CQ63gb2u2Cnf_7P$@qsD4eS!DGi# z#}b$1EtUkoH>KP-{EMh3gDWEqpXO%IV~b&nWR=S(XpLEou8#dYGgeX4F} zYVzTeBxL(tw9W_uJwg$buVZ6QVI>^4(c}%-eAp7>dxidL90S6Vd*FZ;zTuYTEbmN zIDU+=G2Cd2zX^K24z`H=CnL$w*YyTe-e0wX1A2rMgyP2X9MT01VI5`!%4WHPG41xR z&lWXu7A8b=jTmCZ)jA;w@kKOX%N}6hK5H7f7bX`+74^0WDN8`ZLi>#)VTr9f|M=a} z@n2#MeJT~2MN31NN^k<0?kM4^+0}TL^wqA@rOEt+f6x+rY&-6x!M*dVJ8RA98 zN?Ddh5F4U0PrLk)NuXHDG<;>uQ3)R-VR(udpRB&9x!7KAdY}57LSbia^w@7OEO9o# zj6QB^iVE)l#$tqj#$UGvTa09`nHfvoVCbS0%L3^%RY9l|qP+}wVgyONhpEPX+_p7^6F?T5w&E645YIRfDEu`+cI5NNINAmE+aazRomfD!PF4Tl$YiF7 zj+FcpeLDT{t~O`FLGRNd&l5bN;`Z418ddqbhKjq;BssquhvIhMZ7E7ZMuL-nUfj76OF-6LNB%K0hYh>rKGSpRvfYpn*QrRM8{+(w;%rovUB3FPiB>{vr1oP< z>$d3d2f0gkPjuW`@Ny5R13#v@r<$bifk8L>cO+x{^4$a^z>rX9?QCXiDz3dald(m7Vt)~$3kZzoX@y^~ zp(H!In3=ad>q78+MsU>O(8LyxDK!`s~s9|h!gzQsrbRdaW{yoSqA{A1@lt85$5{_bYPmbjjkU|(BnHdAo>qj3kL28}S zT3M^Ft0p>{Jw*oLh|^uIrov`HY#}A5OK6X=hx8h)xGc-rfQGY!mGPM(2qMrjc&e*s znglHIQnS6Ox`QOIo+z)4s?*9y^k!`)@rm!+g&tYGSf{x}Kop>TS^BLd@!|?TwI?YB z{#*~8p$$&Pw>tK{Vvt})Z1W_@XCO}8vR(h+f|BiVd^6hU>tPmpv%1uFc!8}@?#LM% zpJwh%U2LTA>sdQx7G!8gJHli#xgr3pFl>Z7#_@ebe5I>eIuCk$;BN5>MiX6S4N12j z!gLh7#d0U^p?@w3tNl}`+{&HG%=`C7egJn)bguR2Z6zWK4zhIngw6PDLh57eI^|E7KDQZxOxF-a*A<9!42oa~K$YfgqPn?FpdI?*y0jm&Kb;ISB9 z?eC$@F73!NeBFV7C8(CM$2E$WkxD)0K zsU2F{B>yzC*f+>^^jjouFK=*ra=Wt6)D`6q2q0Yt;Nuc@rE zH^=wG3ITDIQ{hHCy|<*s5Kgs(2VjX_6uoR=uV(0JV*t&NujAyt+lu`*BA~c`Qk}oI ztrOFnX-GO-mWa*n_hWh#Xm0rDVD`L_SA|Xku#Mp$oQ_mN!D#%#cvbhnr$E0J%5>uv zY|2dcn(nbv!jhlSDcb6}D>OEpE>)6^-eQ;glEe605$&#=P$$5(@beW4tzC;eu>}N0 zThOuQSApCVh#Bmel+RQO2}uX>zwuuor%|NfizE`g;5h84EzoAmFcWtLAsYQ%47`sPThM7+l{&(O50_dTsnP-VE1%T4HL9OP^e;=#P9~PlO1=O5 z1fH5AlU(0Q;wc7Z5EKkf2cd+HP-e-o{s5EAul82|0?Xh$l-}?X2V0c7Yd7+eao~3+5@esAH+tS?N z3ey9h*Rcl(7pMS;K~SuCdJ+zpPg3=ibXD5^)FTYtgp!4rm__mpJt1@7@XR-gRMCjX z2j6!`|A`R@7s;O^GfajW;qXM>9%7pwtfhO5VfO^Q@m&*WyR}@~bJ$xPkz+YYd5*NZ zinJc9mfj|+oVg^%!#9Oh#;(Nwl2m*EXM1-T`)n>F(YAMIpGI2DRvHq8XC76(nrnRKi)CcO&Qdr)ZUC;2_zqepV13+BXsZMTm)a210(1tlf`K|ITBZvaRcbPYW+ z5mHJG6DkE{;Mpp$@JB~s-q3MXo<@n337#^Unb7{7fQF9+k%9{yCLMNC8EV$KWq78; zdI-w)W!z-~+UhH0jAQSEVjEvxW96r8ryBQA2=rZdtN(Vbx10Un`Lk8op7<$wv+pc9 z*E-Ladd^8uEqQ8mZh`=d*hgwDb+!v9JB2Q~!~IjXgd`19s402UU+kfzOH;J`@C{(# zvD*pVlrP1}Ef}#2roZHA35YQ~Wzvm*zsI6@BujI#9Zk6)Qb++;+!kz#+!1=XiCwVO zM?F^k-BWovL`XTsZRJ_Rq$v(ObrXa<@JrD@K3bgvafdbr+FEeXJIDGaI4GG28s-=% zf2%8^H1_q=fDV7rW|<`+U!R&0EpTM2wOde@^3R_cTO*AowS3j14@*1XJzbW9RZ?wD zU3KBV!07H-pavz#fxL9Ucqz-g{Y8hQrZF@uu2t1}<>kV}dfq%k#YU`T4zc)?x!8jP zHgi{{i_C>4HsZQiB1TvCyuvPnTqyW*m-|%JGDj!suv?328hicntIYJh|yka3>lQDOyR_ z!T(Uw_OaUOr^+G!Sz-s(sLaH3=w1KjQ@joN+7)us5moDs6 zq+}Y(Xypc;Mn_kplh|>yxDb|0a=saxE>_7DGJ>O7=7}1?cX{I@xxi2~)4{ofQ1mM% zWuxY(;LC0^`Og_bNuZ%-#4>t7(IB?5N{A@ye;eN`(|5o8&r1CQvi7&|(F&`SCaZ}R z@GwRPW|Qs4T{vdkl%{u?%agY$geM0stB#syvAY{&Al%TU+4UYT=+x!}D#hhLzki{P zYr5fa7N9>vuv;Ag_pWIY6#zLz(>G0{L%cU7L2taC15$zV2=h~#$~prwgSI`cAm7o9 z2)G*)C?P1z(H6k^rJ%y&nLIyF?m!1!ib=b_Q~py2tYxpSVW)!6d8%TYZO zJqJi20j?AL?l8-ygle`zMZ-f?#U}h%Q*ye=;|b`Rxcwb-uP>@WyH>z>Dr3eJ6<;9* zd+%E>ThRV&7pzqf*71o-iw7)=i=Xo|INve}<%j9slV_o4`jnOI_z%w$qtu=h5H7Jg z02emNJHcDR_Z{@AcY!Y>*5!o%vgCoadzhv29X=J~z6sFv}NlPX!v9JeL-etpWp86djNs$UH#1USdy+tdcddQ@p9{6;eHO&50v$brZ-J-ctVSND&Eq74*mG-Pja|44;#*|*aWL-vEFFxD012UFMPve+YYiGTor;)0<{AFs> zw24AxM@L4KvWxZcbXFM;!A51>=XC7R7Sfmi-cHSU{ zw&^3(9E&P)JJ*kLF8D$C;(iio-5=dynqnL8zCyF#kCr77o7}%O^hcyl0!jCYDr4(6 zd;(|cLidQve-%lOEl=7H6MeI5cpFNom71i6@XUe4l2o{X7;XPD@U+K*ojb{9UOjyq zzX9(+Nn@Jv=ZOQIVVywGt(j3Xhix>EKe^7!InUu8R(I&$d{&Fl4GaW1lpv#I#Mgg- zjTd_)Y;2|Dt1X%Qg_}KF`_9R!wn7RT^U>c{K7X>aIO3}hNQ=6)=2)m|Mtomxy3jdo z`|1PJ%$Z_l5M=_*xVZ|XNNdzFyDVKgBiE-$(j7g5l~A<`h}My)!c3hJPBIrU!gT3K zNy!wzB(dwD{Xpl)&L{*HgjQ@@7b;`3m~!zr!1ZzmkOS~0gWS6tKG~}hD&htNylR4DHCj|H0l{TFU)cu7E;cZc`zV0&TONMfk5TYZk9rI ze?9;oF5mGLgOe?T)3=G*AxVvbURii^#z6K=WLiy)52jaSSIet(ArlNKouFdijyTp= zAtX@vCZ}W{p4=D>$($Tr!Y}WTkRRlAtZ6gLei*vQml7{&+~v~};K@=czPFY;18LRFN0R6JGxkr!5<&JV7Ako$#zy=|t_mhJV_ZH3 zlQtCobY16^oy6lIgJ2f_097o4pCUdH?W3j0E={ernq9t1;!>}8{tSiJ1I@Bjv7c%g zcXHG9_cd;>w{1|lC@+?Z&-rI&n~PsJB*i@-PuW?@L0NGzHor$`oDzd@LT(o$uE;IG z9yrrP-)^p>Et^#3`KIM(v?tQE!B2_Ldwf7k7 z;qWc$MW@Wyc zVr-g(-*gu?Z6G1KN>oO}N)>>Mg1Tl-Z!0I%Uw{8zVd;Sd@+m|E3zRiAGP=5_h+tT0 z>Z|9tX++Gmn9TXzLTRlRpD2~q7^~_Fs@$J_cS_pHen&`gBU+3@)IwoV5fuC)C}3@_ zMpPTyV2Gz;2H|<*l_z5*7w{Q!pQJxy-3?$x46sD2xCJ^|(s0@o?cC~H1}nZsY#j%l zM|?xbK6|WsaB8r`Z#}zH>qW0;$@4H^5wO?Qo8lM*Hx8W`QwNcYQk#iUn2(obsV>+2akvP)*l&eBF?IpyxoC7SzHWU+Wg+8tz(?<*0&o`D%{L5f^e{C(n`iD5_wGm#zU0JT>Y$ z)iL8)7Cg_4R$gVd77&<(Z4No#GK4lDZ*6NydAj4GQ%xZJHe-raQEcn@0DPdQSOIxO zJ_EH9Cxg_Laj)uQNGz&f_?ycl^rY0S=EDf2g2=0)F7ukSkX2K^9=utd{WgU1t`+W; z5TE3gJQZAl523T*Ud9<;F&kO9o!y>}eQI~T{OzrnfWdmhR0H)s{35hCjH7c{zPZSZ zr_k7uXUBtb*}XBdl>E-e9DlAURJre3kkVwaBGTWd3BH6%XgH`wHw5jcLg9*pDoAGj zR&@|nxWOQ)wccxv1VQP+n17U2?2+^$+Uyup+`s|_$a&nd{#>snv7{b2t2Pv0`RBjo z6d!Z&ZQDBTX#jgZQ)0k}W7Dax+@*n%e^9MqyRHm^O3s@&v>T?wxpcztsE8_@Ttdon z78x`8Nm$79#Z^2#$0CTmg(%qhy8mfyxN@~nBKlR)*4hK%#mOwrGHPDi*-jCD9W0it zgTYh&^l8pZQg#*-vqipDzMfmo5rv?i2LNbfmh}==xEk^cK%PPrkQEWexGLvqImGZcMk z2MAzS(`It#4lM!%j`=4+kVg?JeNI#vo*O&id1Pwu7J>_(P*P)CbqlnoUXRgS$HX}tY%!Xb)sCJhqfLz@Zw z53Fti^aY^_X6+jY7QOo+p}eEjZh8=C8!i4_@@xuY&v2A8)H$R~M{(zvr?YK3yY#l4 z;EO7*h!JO^BlnK+rB9H+@7NFdZdqQOSO!w557jvvfnN%2ge1=V&fh51?fPYorWzpus?Lx&8=%^tQYc9!H;i4twrlGH3kQ7Y@kuiyOiFGZ^|vI8!hTRK&;0{N%KZjP#p__YajL1{VL74!hL$%Vh=Hs^ zQx`C2_1-TDSb1iagbiK@OJ+6FC4U3N>+T8ve@w0;o>XbCXp zfvJ8ZrDqx%vkhM|shP`=2J&icz2G8}p2|0%z_|ZT8&r|m_;M_1Dee)a!9|L%;s&2~V6K?#$>&=UA8s6C z$P+O~8~OI^8b~W@qIP4BOoo_ogAjT$Q?Ey$klzov{DrmrhMCIEe9b5q(Nhy*Za?{D zfiEE=+=xwUh9qANrB1|kpCh9i1k-(i1l1+#Q92(>7QY#V+QjcqMB7eo|zd*ztab!rn}PNfRhZrZMFjEsEs)7#RY;_XK&mZ6P}X zVTW95>5>%FkI6x4LvdXNvi@;-;|gB_z)hH6+jvKExtItQyD}u!{s9(v z+9x>9j7_Z_)bB}(>&r{6nDpa4-J@fUNSxKV`nJE_yxgsr$`c0?fcwNSPYx9~%tp!% zt^vfoh24q7sEqcM%b9X>2K#$(pII$LR)j{&-e!gBe1yQ?V^XTo?TPku-z0!`4&M!@ zlB>ge)~+L1FaxLzPtw>7rAN7(JCBa6y#RSXcaFln$B^JEX(K9WLmB{n{5*to0#OGV2F>ouh0GaSqRE?#gY5YgL()2D zwW1`V-J)Mp)yL6xO2t7iC{P8<#e=bS+Lx>A65pkOA%LQn%nz9@Dd`U^_u<+R zMEVf7)z}VC+M+C=nKzM}Lyws=FaMnT3B`REM%oK4n;q1G4?C^wkx9WZ^xOP!rO$(2 zHbFaLmR&JLcVLVduyLI+fp6juor+DT)iw~VgVudvw9!ZH)@*y+Z!318<@CJoD2h19 z9c3|cRW!joe>=pY3d^cAW$ZK>@23CEb{=K=iNrCacssTDf}F(?&i?0b_7RCvFIe!e ze^u@#-vjXdEfBF(QaM~j6PP95r%vhNwu~XQ@#$$nkoA+@u17#+^-E$hK|S7K(oK1;v_vjh`mp{Ncm2|y6sx4Z z`_jTRD0!j<_C4hRAvR+>lvFkQE7%~3S$A6tMTf&3P{Ff5iw5ct%C|z$JMTeE-?Bby zl*r++9EwS1YVdjE`&0UoQdl1Q?VE!T9hB0n<~GBN7Es9q%4aBjK2w5|vDnJlxLZkT zKG+pEpCG6_kw0P}jSZ8;ww>IPE><_%07Hfu47AF`$$H&%_xjL-T$T)M8mt+%G0csw*rk^HIkaiCr zd&%=7EVgroQP*p1nkAUrMwA~)RzyIF4ElUUL~=6BM2( zCqbK9wfxNSj8CAApXTi17HnskK^`H{L@#LEAn4Af$C&S(w~-fj8hd6L5s<8>B;E*I1`1Q1tC(%`g-usJfs& z_!m6E;!H!<(TeX@#xC&;nt){L<|`G?1FJWTDBbkEf=U8gJ!i=w5z%0zWxT`|$n}0|~5@49>BS=^= zXngt+ti93rQ@bLn1cb0JqES=L^ffVxI__3ViiaYg-ma2V$BI0xF!%JA!Y}t!refNm z9oT1E-I2I1$=-xTBWI@M+M!(=jd|?!vj))01^)od@cG|rt6pV3PM)KNyxFavSJu?5q6H#oc({fLQ2=ze)YEVU(_z9P5T)O!oi>e z%CMWKy1*{JN>ckSxyxTNsp}fzq+_qu=+g!WK}0CIr5?5OTD*rke?Zn8LSAn;=-r|9 zrHdOFe5HnbYq(|5J5TD1og5~>I_m)L_VrNo4U`Ff80MZ+%G!r36smSy($}1u1Fcm$ z9+yVxsUEt(FQ4~?E@bQJ#xIKTe@PGPkK#*%Tvlq&k61BfozmV!Qv|86T2PXLM$mXP z9j|K*E5rSG0?q?1`~dn*Jg<839^wDP-8;Y6^?lL8ZQK}*?WD17wPDjVW@FoIY@4S^ z8r!yQ8$Ge@yFcys-v8l!^W=v-CugsXwf3B2jydLBs%%>@{7KKgkkN@<2194sc+FMh z##j2u!XM1@4cYTU=u@(cp8a;V`&XW4| zM?*D4qq~dEi=9fwJ$c9NxlmE=Mpm2?)+)xpw*HoFfB!qOd(^j}!tnf$p<)!L@6gwe z`EZgWi8Pc!^TH%-c@BSiU@Lgi`cY{DV2t6}__9|c`nY};cwBsNg-~Ol|HZR%Wu%Jq zbI#91p}>tyU~so9mMy@RDKb|`ZJ;9BVtX@TjfmsTbc`^8K7wI+V|9ZnyQE-wS?vsN7+jgypnR-|ae_gq5Rx0^6|&vOzr3y4 zz@QVPhL1*vmI_@~>diptT~CL!ee$&lp#;TB&2N?~x=j5LXbSfJkowSWB#ss-)PKf> zlwHIe^v0~8-d-O?(qD16n?pc)0Ow>lsdH&P&< zY;vwj2S!2@4PZT1ay8Q&8u?+;J^>Gs(6M5$tE+q___<<+kF($MSrs|LZ?T z0@ubCK<>N;RnfNdX>w^KklY%RdI)@YpR(wgcrWenRMCOqVU3(%p;7vW-tB4cZqP|Izw2_+6q?DD zy(}fqgpjr1AXLZMc(X-PRd3jqZkMVI18A`~?3Z4w{x%dz3D_o1Ywg=GhVe zq*&dDbjwv;B!QTq|EL~rql2h}5<`QlxI3@a4e`J5J>Zp7zYZW=QR29?Cxk>JzB?uq z^2!s5Jl&FB?7M7lo%NOl_a2;uyl}w^J_j|rgGT9SIQCf!%gPmCG$zoKeJEaCWf2i$ z7+~J$1tp2Z`Rv0zNmk)fov*Q`JcDTXBxT=HxLqAK(_we<1Rt{0Zg86_Z{2jOTTWHj zgBdw-?-owx#PEm(Cz} zt18zPLM4(z)c0V(S|rZiazt;n{fS-!G*oN_+ zw3vJ-v!}qaHMZ`pAw#V9^Q4>y``8UI*(&nA)m2vFYtgt`V{b=dx69sAlg;@Gfbk!Wn8f zQ{*=Vx8RWHo-{GNG!VW5+DZo*{z>viXoU}zvlitZj<3-9T|55n?-v&zN;azrr|r%g zUywJs(&@ET&L4J`!*{RW^0(w)`4Bev{=H2)v7@x~-Y+-TDBfed!apNOH$gKKsKGXf zo=-pdUvC}+^dF2wTT-wbm3+Z`7AGb{VrG5BaSfdtbmcKp1KwV;L{xk(!L4z4&r42` zYVM)jPU-v(mkS%AGA^MbE<=6g>*UTll;#SkxyX8jqc71j&O+{eZCV-f&bQ( zZr&LxdfR2qtoGf^9ZJltVBQ1uHFoWs)7agVwGf2~+z`)aF#2j@lMl%miK2^N>xF;C z(5oM)E;`L2t2JersUv=aZH^zyRSy+m+OMLY-h6~SUH)DMDjr*vmGFLRe5j^1iVeG5zA`a6mNvzn zWk8CbET4Dy{$mLLw|uMG1Cx*w-MF!vIj=EoVhpn(un^Gg`+M{#}@nV`!@Lxla)^GweF2 zC*QxzaQ70$w*if>u~>A-uW+6BW)<8beI%q>mPezuiTAx#bMUIoR1IC)gVB(WhwbBh zjm~)4$pSwa61LO*t$` zQH_E+0do#POZ-e!_v|q6yyQ4_ZlU%z$BTmn=Wbc_`G>jriRB4%C^<_GbHL7P`?FFj zm@fK%k15E8WvI?vVlhWS=@vNxDle%ndhr?hVhr-~$>?3!@zIl^gGlC@_viH-tA<3? z!LtN2Vr9F4{kH`EP{pUcWiR~=j+_Gu^&dP>p~|X*{ua?3!HeFHiE0jkpNUV3q|z>5 zD?}U=mM9wbKP2W_kKnkA$ZSlKu`;@CO=F&&t(_fjDeN6YKLLH4@UM>ePsyeJqSpPj z0mbE&-?fi71ahx>n-ck%RGcr-mgQ$eaZ>Hx51G$lsq<^PLq$UMULr&!BWnt#$-%_= zStQ8o1g^gyq?ZRa&=AJsVMjL0X9XY~#*sXWQUi#IJhlL1x{3gDNeLkAkhNYjLeEgx z!Eg7>?I%FfkZt!|-AHyBwrJ1V5%m6_cM`#2MIZ+`Mi*(uJEOFIUe5A8%6>z(rAKzQf zG*s;`ymBv;b3t(tS3va1dj)bYuJ7BPE&QD_{vpTCc3vW>>){^**F>Xr2AeC1zbbD) z+5aJ}Q%&#S;Ct;krCma6x@CD7N+>wKcQiVL2XH8vjnm!qG7o(|++=!S|8t_X_{FY90&x*R#WAEzvdgxz-~$ zE>;q>dq+enjE+g;85~ejwVBl8BKXF5!p?gJJ(PrSJ`*})Kl9ICjSN_M;M5-%vy!0X zTvkv;*H6i3zTPi}Dsdn&NXrCsty7UNwLH4QO2J6=!UhiTctFuG950cH3DhUhDe^Wx z6lL-w$x*XD*nj4~#}C@&i6dHbr6bLcV)7}X3;@+MnU8_ULRE6a8+2LwnHTDDe@=Bx7u&>5$k(?inyc3 z`e(s?c&e-_#YB7-t1B?p$#odzcNDNacAni8)G6yOM^^_botSLc_4JCzX=zqm&d;$` zJMiwF-MAv3q(1%|;O%35Y$hx7hR^L%BVotDnI}Oha@JNGNL=dZnA$%VZS4&JKkYzb=90JxZ;7- zc!0P{LGxG}wdO?eepqv!me5^aN&8ldzW8hQ zI73b(uqf!i0V59(`#js;owj-0!TIf{@wnvp4{X*=!{C>hoI=EQe~%{5b1-@g!kSt3 zAlV1sF-3ln_4gUy&*VB?3MBmpmL@xXGHQZsPR-&u$vxLz_D_0`ma{LYRJJ=d*^IuT ztqgjPrUUmNiTI$zRVSBUn@CU+qvVfJXjUV2r=FhR4$JlWn!?)t879MZKMA3?=U+7*&I1wa#6GPJMo;oM zivxR%1pJ<*&F#2YPuJUtKwBiLd~nngEaczmBV`xFArpu#(zk#7o#Z7lVl8P!{+!1lt zzD)+B5DR9^G%%B}8_%U71xFFARPVGQU^8hy96JnhRdk+Tyy=nrTjl*IQh)T(wU1a% z^zMUn$r@f+`k_29$T(k!+E0BQ<|K1}LI}hT9a+wna4nauG!(d8J5HqCJ?!Z|pZVyX zuGee`v1{n-!Hhsj^#VM8&bHDLnSW5yZHcaK@cpMx6_~WLf%b{n2fdYry+(BNudZi0 z3#CnrS?^`r`N<1*ecoE!clyW9yzjTx+d#!fnh~;ATW2V@gpJ-i;0Y8Wt=HqLhzxy) zx{*d7ihpKAbSGpup6$FSbA&6?fAunAZD164<`~U#Fy#(Rhy0% zXYeRBvvH%{su22LPXw23M+wmAea_jOxHT_eZDh@-&9jP{L57atvZgbZlS;GE?@>i1 z$V%5~_|TEyLrll**(LG;`S0@_v<$&Mbz`04nVG89E*ses?f26&LbAGMW_#OnoL>D) zH6X3~>u-CbJkE?+w5iYt$>ohsPr>>1<6R5prn!Lwzb6;J!EzDr^9{DufHGF_?Y#t$v-6)N@qL{b`77V7d8lJ z2(c$R4XDQnUe8_CZ@wFZZ$;*RT{1KVYWr&5E=@o!Pf$m8gKnY_q6SH2YA+`Z4akI~ zdl!Xfrl}paOOfdt?CcFfUYj(L{hPz|)XlPI8E)X6XrG5a$x_ioYi|d86CL;V^T!XT z@sNEm`O5=oOWf3XdxU&;htGlGk!2_2@y|4}qzd{8u}YqM<7*?Tf}oj(ujSRacM1^y zB8mOX&W|$^`RD~SN44tjUsQYM*WXqk7!3cQWStC*>8A(Gw;TRq39!)*hZ1cHE$~SR zwka&CW0TQiwtSDJ`@_JTa&E|3w!Ybu=x zn~e+0HV4H$u!&Qr@g!w_gf;4uTfly98%*hqSfou=yeNA8QH4P$AOVlTdpC5mwn!#M zUK7ep0s8e>MpM;S7P=&-ic%8n+!gzQ8Br6PiAtB{6$JI~m7V1CBmI5(F(*`{-VK4; zB@0pg!K)XnyK%Wy6AYM}X08*KXd7@^vl4gpg%6s}8FT;`BF&6+z}1NB-vFq1exvL` zqr((A=HEtMCzV~+&2ypYo4{H%>RYMO$teeMzPC*KcwHU(bpLzj&XDcl(b}5|SPK^! zeJ*y#qrkoudBsR*o6H@@>~C^Kv6~C zKFG2}+Kh5mW3L1k<(MCbCA&@V<5zFDuy8IX4ZN2rS1{+}W^wUV6n?+4oJ?Aie~Ea0 zj{9$_;a)iCS)>kVoFX~Gt!nAC4%cf<><2yomI4yXhp=_KWs>8rd)@-M%Id|x_7BT5 zLHnu5{$Y#ANc#=QXU=5aE&5(HgR<|!fDNI#f4Xcc}2@t=(k=#L_uHj;7VVGU}} z>zp3xOyyACwVBPqzUHYlWv`z;^X0yVT8Hb1tmxKcXz z7rIynf0I<$BB`IrK_6>n-bI9C%C;S`(EmpH-{t*p-u_vm|Brk&$rsq4^wW+Q=I^cG zq4*U@u5+Inh`n)sOiJlfJ-<-~UdVirbA$eZ%07BuQ4*!D5eOkj7=`?=>iDUJJo@DH z9RDr5>^Gb(s3h@VN=kt>&8*Ik@o$DlN1Z54!0yk%q@ET}i#ASwOjidZ=>5s`(+gb2 zjx%kHcYY6az1zZ1SqvDEH9N~%WA%dhovLMYvJ0N!usH3O7{O3-7@cF>5fuHqu&-Uv z_U$ph$6_jPM3E^URT^R7i2fQ;>J}=p_XwM`gus=~71D~%oj}K%c4LKq`a{cw#a^Gl zpfc@t*-&NA9`#)X`GFF%?y%H99mSs-|Bf`0Peya0`tT7YnrNkM?`PApy4jDt z1MF(Mk=qwoA^P&dI;TsVJ2bMt_t^1%NnZYlQli)F>UTDOh{9E$| zVULN)Y6_x&neN)*$+>Hjgv85+#7I}FvmZ7>+BZ;uR41}c;C$2KywRt=5MBz}ZRdhx<5l~&tDOEVqm+^**^3@ z8ci+U;IQ2sNmIrX{mSohcb9HQD0O!>b#_RoIANa3O?E_)~qd zNGDELKETMriq(kIo}1$LkTd-TwCM^bQs_@k)!=>Lb`8|zeK@qcu0sh(2pgvX@md(k zJDJ#8j+1b8sLg~D(fg9}BnEVL^06{>v=`W#+vs}}J`*HqC8#VzM2CH*W2v_{hC>9( z2LVa)5H&>qOxttYea7LhfYnLbhcD1Kfj0tQeJ+|f@}0BjV`Eo)iRO76`kuaedMo0h zlOJWb%rk$^?xyE#F+XkgM`$1%kbIJ9L^tpB~C4oC7fe?pSUWY2@{=%OCvyR#C@@* zdO+n>rAkQe)a!)-ixn$%qSNTTV|KlNALp?6E{Fp!oGF;vZ!b_45$2uPbbD51l^9*3 zRzYf+mJt#{3|nNSIARt-y{OrN-rly+4)+(MKkt}mOW$`ag#PCTuB|clnftz1B?37^ zYV-F@X5`fN@3je~yx)%v`X9tiOe`Wr_Fot0<2C{|O^kSCla3_eS2iG(3?HX&u)W?s zD2XV|@Y}fpYEi~ZPHy3(4MP)Qz)>Q0ODJaT+37fj&5-KaWqu8EG4W^nyfdz%wNl6swSPt^`}G!b8w(SV0-a)Hl&e6AiM z>Gdo{#pb*j8>iKZ+y4H=4z)ssdP7sIbMf*I^xY5iJDZ2`y5F0AT-`dQ*WZq6SMIc} zY1VhBe%CU6tF7^1F1TnN-Vf{7)i?nx{Gn}mI(W#WFqogCIBURwH z{ubg}5OoevS!_2$ASOed6k2zbWIwM@0P z=io1ivh99d$yY{H#*1BA2uh8{SvW+>HQP&wsJjzh6!rc zzgc$JW18ix7vX(x8vGJ0*y{Y!AF5=MZTjoyFEr^-M-$%m);mcjYc*gq{F7G&ArSA& zMLT5h-Lb&=MblL>qc)H8_IE3TlF&rRQgIqCyF28dc|P}NijM#r3UG0!g zk!9x}&u81a6xlqU+Mf@PDmvP|_xD-gSZLahpTF%FO&0bB%BUg>VrB4LRo&{a;qU!O zf2ROz1SRKqG=JiTfE7GIVTK>Wq=czD3lKW{mx&WIHDQR#oU{iIFEU9!_FE9wANdJO zpBF>pspYfEtxcUXcBS@)kF`CQTTFU_g!4m@Mu%?L2K`O5V?Uhx(W}?9Qm`VsoBv%& zv%p4Z<4!$bt0xril!UZ+Rkf)ZzPHr}g{S1wpWwiS_+hMYBv~a^g!Y%)d9W3qJ;E?1 z6(_Q_x02?v%jq(bCcJ_FaiH&skZYp_m;g>}AJ|l&@Gm3rk}RheQX7=H!|qE9WVin- zqv%laKE!fXL+K$+BvYPA&;jZxbh@RjpQV#@fvT10ZZX~paqk&y%LA?I+(Nsk#Yv#+M9MzVF&1ipGs^VLD4d9qjMj_3l8mNw+Frl0a`QvK zI}~N(W1sM9mwRE_%*1sfhCjN!4Bnowm0NIr<3qn|Ae91qh|4v6gWbi9YVptq3Mo&* z1E414UkRT&$~vRc642>DS^jK-29(e2l0Y+uYJns`$BSiSakjxr+2LEzgqj!y_T)s6 zIt#mf1ut3fVq2Z5wXQKyS*&h!`JkTt3TZ;X((bTx7=M-s%I6HqKMYx<*w6R%eP0;o zH*Ic82JDLB0A4-wZmjX7besLMVv0h<-|G2L15hhqtb{IuY!@Pa*YoxAHI`7b$9@%a z*yts%mpvxW$2An8QnjY?rm|dswSqXgJy}Vv@Kj-|!xUueLc8#Kk+Jr^V)zZu?+Gq- zQ<}Ed=6^vLF0Mab{IGR<&?mDd;84J+0GeNi#B>AbnyWn~@m?yFr?#I85K@*Yy5Aml zqJ>1)X63CYE0p>_4t<{o1{8XF4o8V5@aI_J^{`y4Is$WTJfDq}geR5JmlWHWpDf3CSvJG?$5ZP4y3Th9Y zoUtX()DoomQE$;qYEz%mH~TPYi*emXxO7lVoROiiOi*RZ*>x0=Yb-W{HX1HlU+*$n z|JzBK=0drykn6pgmjS-zCBSxUMgGM8q2bX`7QWEv^ZjqQ^x8A{0pH0jh*!)1!)W#b zT+j+qb_aJho7)ineNj5@AuUikDq%YA_<6675o~g591Lt8)p&H7Ah!1bw>LR`$s(jJxqQx5c?_bf-0X^V!U-!p2ZhW9=R8P2XHa zy`>M6AP*b;Cl(eSkDIheY{52Hz>;P7*_Ze3H?5n%nOfS3Yq5TxZn^?7YBi%D%3A6j zo)Xr&t;jb*XK}IIyw$j1ohkw~M6bl~RYS6dRPlxsLx$Vd7%spMik*HhhNz!~?FT3q z7mW-EhCqLif70-l#glhODlKi~*L^b-n+-v&yFQMknp^wEEIx~~I{U4x0fh`+FYpYw zzC30SYA_+s-^1H(uB&H&^y`R9`3$CdqdV-|R#ecq-5r8}?frgg&0e$n-r^U}$=ltC zXATRlHt(0_;_{*KrJ1F*jy99chj46nAgDQswBGBeww4gGa z9|`dL+AiEHE0$QcojBHAV4*q0ae@Kkf)`#vajEE3F*~@Jk5%{c;M?!td&M-4D%BA` z0&mTKTkAhG6sz^gEqolgwa=h13Cb7VSfwqU3H<^Y@Wk{yL| zeX4f!%wZiiVKCKYhwlgRJyy9R(+X#5(=O4rqX_7I!7bCjzt~WkFzyt97)CO<8ZpR)6Jq8yPy5I>l*&ae4zM z1BR3R6P3i4i-AkV#hqsIxw?K3-H(>J9^uQUlp159kE|>m<#xB9>}yf{dawbn1>*7W zzFUXv!<CpT z1_TbFJqC(zF>*^NSrkO}ve8rFX5H)#DY;5}DQRjL3*uxnz=c6AiPTGCA%`9`0S8u- z5(mL3_!b409;O+;{KvkZZfsOrNy&TTTGP{%X|*};)LAU(cD!b{yCn%*@?2mtP&d4r zeIA}W@<1l2cDQx6zZzqp;bZiuLI}c)Pf_R0eI1^&FohGBRh{_mo!rYH{7SN&^%5*w zMky$Q=F^y~&ew?0mn5TF{&L;j*9MCW9XRkIvXrEwaB1TFvRlPM??wGqH(4p)8i`7-3i|O1ol63H_*L*(iYuAtX9_`Fr?GK z^Ec%&f>EZHO!dwqB_{`3yvtmzY)yqzOI*vHqf_$&Q2Fz9juy8O@=_o;xhz+$#N8;E zvm?Uw)bF!6SsH%VO>=7;YclDu3%z?P_!_(=_Sd^nNjl5und+(PQ%R~b{-Tj5t$LY_ zKxIaek*Srax7AmI;>rwy6aUWAN|)QUCWnnF18Ojn24}1LOa7GA*HCSbTbngx1MW(1 zLm891V}GeAP>18v9Npyfy7H+hD650!0xqWGfg`f3%H^WP@!>EuzQCmJ&J{W!&j=eB z?=G0w`yRYv1N6#vygL;*uP9LHc)48xKD3+Jca~BGjjrl9<<>ckt0Y+aPpByF9pI|F z+#tVR&nQ&rc6dKr{sEF(b~|lPC|N>2?*qGTZnNGyXzqpXRUhDM4ip&vM^o1zB(vIw z!4H>U(`$QQ4A0daaRRJUcf_V(<>1yF{-(HW8K?m#P$yA&PNc#%x5ehOq1GYssi|>2 zV_I{NvXk6CJ3A*|2O@Hd!`2-zS|W;@_z{rkJ_MqZOBHgKW`yRj z^3P+R9`}_3|FbG^+cqPPNCHMz%qphQ#$7BbpBus?A|M9D6(<6JB$vlFYLGi&%(Q7W z&j>Dv4zULuEPRr~Vky*5=ht5G#Iv}>tY!JA&g)68c{ge3sy;H=JWi>J537>gz%W>L z>T5N$p%h;rzW+M1V~7|PHTcc)4_USCHk|BlK95SrMt3lyx1B^Jq_VaQiK#w*!}aC- zEp&Q1xRkR#)_N7TMoDomyi7|bEg1grsaq+$4vBtX&SZ27Y{fs#X)`nGJ0}Nev8n!0 z*Y??Fdoz!Q565D3s#{4K!oVKg!D0n$9dj>kwjZL;I*ef95g&dCX;A&5Ukwzx$L4y` z^e4&tUttmQdlCdecky^0L(LWeoJoldvY>9ez13N}7_d+RT0|scT&LMetti)lL|H74 zMnib8kL9;{>;~%|wp(J}=sLHATLf{3<773lon8%eP9L@=3K=j#np{q@=8-%#mfe zbSB+4PHvy6Vh;Q$LZQ&d+PXX8YApfCqx5CL4sU~(!NNNKr$sD+LT3j}>gDRUb49*T zlds~(tI**UIxX$?V=!JA_)AImT3PMt<|?EV7cRVMk!(szsHj9Wwg>Qr)uv0sVQKvq z3pT%GMvQ0i)p^N!3h&tsU)MT1HrnnwkF%lYkQhukYLVCG_)8ELzqATH@{|7cL-$YJ zvx<{-im`3_`9wmcSo0P7nZ4JA-=cL&(K_NVr+X^HR9QYG!Ke9zYaD-z>{UiAAdqNZ zW9NAN4T#D7K1oUV!>+J8oF}+>)j!NJ*}3}VWh_+NAPNgT+2#a& z6EkhP&Qa6RxGB@*v)dKw;pRT!=`O|rzFgF;2P&R=vNG54y2tra&0d90+vD+eUf6O_ zZ|yO`QjOnqV5L+v3K7q|fX8I#to17HJO*KzlS*=4n}x92=%11Wh0NF5Hj{VDIXT%S zrBnjx5jJ|(mIs3v>NJJ+e&jm?Jb0d3656nmx6gee+AS!%n98C(%Ck<2@WCd9O!ce{ zPDzJzAA|YWc)Cw{9GJA)?e7;aEEdXpP#Y{)Qe(ACOY<#$?D>H+IvjD)KVoH?np#&- z@Zqh{k$4_lCZ128@HykBEH^$tO{BJ*KSrjLYq|(8ef_bY7UlO0Ynwji>d# zE-kxVOr|c?n3mo#iBoN}H%`WBK=NAt@`4=!F!QL1W7sPi($CA-R@ml;f4nwBS z%CP2vyfL{ig1pvuPtRkk`Pw5p*U zLb*qT_wx3VuS*Vlr0SI^38Q|$&be`PH=*gsDJ1F@);yr6EAs!#qQ+FE;o(J zF0vB4D&1q!ArNrZzn%2FMoc3}PnetIY6Psty!u*wZImP`ln5%+MeLUB408;T8(1eh zwN{?(?w2uGKC;mWG5sUv40FCks(Ua0ScEnnDtmYHIWwRQX;0P9c-aTl%)}; zxPFM4mSY1h?C1EHD&vO%-<)jKBLO59l%v|SQVm@7frfJqpTD7bXHa<%k1;Tl*46T~ z6wmZAC5>@SPom*2xl>?res^M|Ej$}w_{v#ThalL%w21yOnY!NI$Q&0=mY}s;NpsJ7 zu;joFMOyD_0Jeen(9~N|{j1n40Y}l1_ByAH($Qqlc>+2VpngKPuib#X?wZw@o?k){ z@whphn?K>Z$Zf7~Zx2PP-3Q)(q1StZw@C<-iFZy`kX3X`>b!U<%UB62k(O)7+RIHAZ*iCwk1*h^o8S)FuCnL}NK|v|B~K@h z+-~<=4K4r*K*#My!lu_@ap{WNp_cb?zPOCtq0Zf&$+u^hz*-oigOk45pV|R%#|0Q$ z7r-VL*JCj_jI^wEfz^aOcIe8>HE)}jTXTS%f!qDL*B=%|wOj{<(7^oQ0*PVMnpr7i zrD(>4#Hex*GB|o0%W?dBl(F?5Yi{`m>z2JvQUe(&Z2=5Aj|RYGfOx$)*$QwnX%)cR zXpQD$K}_xU|B+3CZjY9VZe`ES5b-7Xlmay#3#X8iJ!~cu3_9)hTRDG#Q$JomOBk*! zvFTA?JnUZu{10J7Ig(2`WydW>|KSiLH;UJ|f7e5+skr%Tu)&1eurTn(B0s9q6E8v5 zzrbSu3r2@jR*2q~INE_xVht7+2XX)vcGG>I$dbK#9UIGYc_s3c+EOU5-;%T#?S<`UV6>XRqvkq>0^i$x5WsmWdF!+vz9%b>Q4h_ zw&}lX+JOSC%#cqdR8hE{Zqx3YKAK3hVM#BLoWW#mdiqn@>+R*vXbwpOLQIxa%;Bj! zZdkwrC5zi@e0fOwVC*$)hd@qUPD+Mke3U`Zb@zU)zn)--{FB&b@P+}w=``7p%z5X0>ELJ79@g3ji zPGJ1?5OCWVy-A0n5?KO0jM_^ydb}&2nvWtRk`tGN4)X*!S`K=*#cOi{Bl-@-z4O*HIMt;%1WQe3%hh|Bf4HjW>Li?rvisOz zd6OfM%LHfyo-F^At6xb$iX=!D|Y+ZH@JETrIF#O+`?8) zhJr;pX3^%al!5aWnQ$2Ns$MlH4V(b*8Bi%SmENTdd-NjVnA`=r1>(;lhnZ40kg(L<#+S8lp` z{quR;peXY9x{!b`zGwXqD$5?rcrIr~mtt`KE91G^=@44C{DkeTkZ~ zrn0gW#!Y2*d~}#DJVJ(pxh`>t$^*|IDG>-8Ym3{Pv-6tUq0LwwWMn=a`IDnZFl2hK z4_`8n)Z8)(R((+)gn#j07ZcfHDcVPJ;8W#1+k5%K?j&BQ;3(>@BGP0cjFa}}OeGsN z+1X3QOwY*HQJQ0HEGI^1o)W9HeTp4MkU*8eA^g`rhmqW@pt#{y#1ZLGAd5O?cBn)aDJ^Pkr~=Qhuhl_V zX{na~F@H~rWm}Q7iTOb~--8DC18$1UcOG~6Y3w8MBy^vONg(@`9u!pzHeV+5atMvL z`8e%)?MuEc8QYh5`ZJq0r4e_>=G~NmnONHQjWh!#U$WXjs%*tjFUTt*LC;!m!;k&H zE%XG<^i4@Vq6@E5DUi@c}bk9>_+0lIldmAw_~t4RCB{;f`ng{mO|r zsyzNQO2!weU^0;b>|y8a{n8Iuk3-}73vn#Ov5SHHXyq@Dh`%lG(%)M5g|a~5-X=Hy zXrqwmq2G4PK6tIP%uQkRR)IseI(u`{`2T(D|L1?)mvnje*yvD%yfGrySEnIwOp2NsmK9lqOc1vS z5-7_Fs+#8X&#CI0%?QPy_+<|*%&`H4q3uI|82zbKMRarh=Y>v)8^s0A`FuR1>S?Miahbd*hi*73EwtcCR6cieKlZ(L(_EgG?Z(q0ToW zzdbhl(es+|5n<~Px7K-Wuw45I7R(s1<$e9Qi>Y$D+GKN=1xcG42wdguxL_p1Niw6Z zdaWg;actP*fDRhfU#`Q45->yg7W=fgjU~K)ATUez4=i&J%%2a^f`-9p#c>cp6f#4T z26*vLC5iMwSn(Dl%yzctq1W&VNFgJD6^gl+2)A10aO_j6aH|5`4geadH)tAu1~gPT zBg}KT=(mPCrD{C#lF`ZRy}SGMyYrqOR4AMLQw;-_m~+E$dX&^o%ge!mTBxD3w~C)q zkcHE_t1#}EQN3OZ^5ZT#>fR<{7n*DqrmkhMjrPmV%@`%Im*ea9^A8zNahfLr-@;39 zl&AC7HzT>+2V$^kM?p{+eR)=_vYXt_+w;U5J)sUEfF1hS?BB)`H#St~2h`J@uRbib zIt^r#4*=kj5mnRc+8rx-j)>dwdcO)o-7U|@`HipnvA)*D3$Q8ETXoIuRG;u#qgkQ; z8m{NFAc4p}rQM~TK6W;j;(-c1_wS$f7inx|6R!o-NCof?G-t_S6Uz(=Se){Uo~sk` zf9KOx+kODr@aR^$>CK&X)xqwS@y)WCoToCbvDjvb&q}P}QfaVdYAuI?h=41f zURgMRmd5KEoXn2Ih$p~OdrQKaQRD7&H*MwAMmIgIVY%v`XW@y+`MbK= zO3RmI$D6&=LgOqe@J5Y>_|oR1Bus2gfFvGm>~{_Q4;d2 zv3&r*&}N&?+7{<*C|hAA+n6eTQ-_t(to6)O_!@wx>Z6Zm7)54yM$pzYIQvaB+*VQf z=q0>|zK@|%QN-!8m`pRDO7{zA&jz1neXS~okAWK=B^hqe<(kYcjfRArYTDdvW>Kde zT}>^^{NR;80g?*~2lQDnwSU=vltF&v!S(ByRKb_CxEB=W#M~dZQDdD&D}AwZF>klR z3iQZG$%i=pC%cmWLb6_)u5G!6s&7uis?jM0v4X?b#mbzws_s`*Am#AD~*E0yX%Wj_^{*agull z@!@le$XTl$9UX6+ZjkM65gqNX5D>%p+#Zj=N5RBSaa6__TO8$NlRp}j7n^@TWRNS% z>;oe=B8zlxh?3I*&`7m{Wa6i-W@y7=w}_@*PR^@CZE2B(sqs;WC4%3(x=_ z#hg*5Xk> z!)$NhYwaAdQ&E$DJJ1?d2fh|o8u@;A*E`j z=@^h7rgXOL_ekzrI^Le*x)0@PeU{<%+g4JrbdqOsKB6)!BAg0agS7ut}gt#H&6@h(zTwZ^;v2(32~)TD)Jt zK*|x!sD_@L5vqo_MWbM-Gc##_y*LCo?)kC}`^V7&fE$2pxg#E>E1rxEEDiBSTXKgD zn$WF9d;pH$S*|LlA zgL~&y7$1t7;KrS9WNQ#cwoDtbNqJ{sSUk;DwhlS)V@bQu2wQHo+uh3wd}v7MVa#_9 zi08SOeKxYmu`9G*p8LlL`CPc_YsvNBmO`oCNuj1L8U0Br-Jm$h10viU3|m!z7jKOw zML1T3J^OW@4IK`Uv{5OGg44>SsSc&aA`R}$y*ID8itDqxtw-?j|$rIPXH7+ z`XtQTTpg`}9e|cWOHIW}|K$o}u=2AE?80SQ5RkUYJxQV7W75{C^)#}V6bxqae%iQM z`Sog+`T*!9#1C*@;tM7Q4}IWgZgz{jP*K;xAvD{ zVgYZ_|M?UO=DGq49OhE=IRh*ULra6eYZ`p$L1#ES;|ER)it_oF_*sjG%9ofBoR6w$ePW zF0dPZ^z0oHtoUAQW@6`}AkbDT+viVCtbtcg%d>%l&@1zclklwh+4cgT$@;5UuuzMw z-Nvh!#~op->&5htQbDk4#T`CIEi_Y6*Q4@@2I3wQr2$h|_2< zd5Bow&>X%MqWckcPsr`Ewy`vcj(z(aDfSpVrWrYQ!Wnf6_!|q@=(Hf?-iJ5$$B%u4 z+>VA<^MrrqkfuJEp;ghwaMVIyJh%G;iZr1R(f<+}%TvI@=QT4q#8cbFRuwV$0e9&x zs+x@{6%86>DhkN|5##|Y(Tygb!RxR+dw@iq`x#Oo0D9CiaG*&VyT&_{x;$m22~fm! zkHlaW!yoi8Z}mi`{~zk!va8B2T>rim0VM?KRvM(cyQBo^6zK-(hMVq%bmyXx?(XjH z?v`$NruW|a{~ew&c)=TBF|KQ#ah$*7oE)R6tz~wz{2+4%)p(i6fZ~tqc#~8>j=Ct>)abhVslA&< z^#?a21}j0<{V1i}Sd}E9Y=aDSMZT$pSUpZ|XD>wLAiF!ArxiG+Zes{8ThXK!mqw~{ zn%xF#QWGrXxvF5b{SX+ww;|xev)) zl8JXQkZG(S;0GIvNb|foUbs5!d$rkeI<_u1s`J>J+PLcZK*xpmR~~q@yz|Sv3jVCx zQ2Ja)>7`U3qJ@YVilg!)Q2ZXNI>QR{kZc|yskBg$=#4C?73^fuSII3lZEenQre_;k z&ZJ6fdxzPHj(~YBkBjo&bXxLf?aYr%a)Oy^= zklwbuh(^G7@0fhjt8D62B=jJ0K(@?o=vrG7`Jy1SKh%COLjG!eekHR2lxUujiB_-P zv0Dl8ikO?)pwGNr;nc7e8+0#uX5i^Q>zW|1AAtBLVp_gNFM#I6vd`WW|C{STPasQe zB}~4}kSvH6DJFYU0XEljV_EF0aUNhtKaETLVeqSIBV(q={Kl#(piPu<7V&O=*$indRx<1}MoVKP9j89cx!TgV{>}pW;Ndys;7@60?<%aU2v;^?p zHZBexMqh1g)Q3TQ|3G%SQdtXaEX``rb)I&0f7p~07}l&CqNGyLUi=5^=gmrU@uCxk z>Qo;GjCa&p5y0}iE`~YA=u70oHc)e{=Qxv+lub;G0=Z0S&aBK1MO7GdTAG~q&w(oM z0=o@xDyHCl#Q0)CKNK3=?|-?wO2FN%-*5It2()^_P%!UH8&J%Q9I}UhZ?fM8Ik>rU zS7m18=m?k7@o@|Abu-pWVV(ifaU=OJpy(M}l+~;O;L8ka6`=S|7OwD%W+8qOl>2XG zd$*|>tA>W?mfY6Xid0K8SiqzkFum>6kiLp;9AYo0R{3&&(gtCxuD$D?ILO2R_vJ*q z&a&t2pT865FgijPIHQv9-hZGEC`1|W?XYR7)4#1wExa29LlJ!Y*R04T#-^t#@*3}M z+HX%*8c~p`lfOj}Funo6!}CUHDTM>;CD)PBQ{P@Hk5h&~b7kN_p;>{u1UrN%o{o2cfeaxld`IL(6(nTs?wG~O zn>D~uFj>l5a^htd)MZ__t&@)GGy#0tMAOabX^6dVAMijKwxDk5!eA?p`XTCg%>OUK z8jZ6n*se)%xAFwu)GsVygYl!vvD7g-_1V(F(Fo84Ebx|Wc?U~JMwKR&cDjIjR= zqv7i;YICz(A5N0HK2OBhfI6adav&02in>;$`|?0PhuMD3WJZfM4m<0aIA@ZZ3G+~i zgNew^Msf3CEz0kO<$C+7Li1pA!IXd!Vzjri1Zd}GgGoE=*QLMrH5S;NI>#1#pE?_V z8Ou24%=KssIYjyDtZGPTX3#_xLz!|GV{sCAb~p8Qv$8w5Tjo?wOvq*JJ}+Qjmdtsh zkRVDZ?_U^MU^-|A?XETWvcRhdU25!Fkx4v!S`)qRnE^{zK`vNTz;dSxaCM zmaq^gg3dB?H`U(Jt9&#{TYb_ zgvEcgwN0_}Qn-vX`M>R3J>yRjw0I@wa{YKWbKHn(QDk#PsQt9|FJo?M!^tf z)Nh?(GgfoJL1}7qNXuMV>vSgc8}hGv@5u66cjgh9UU_&|s5O;`2m;ex z0#xYtIRee6;0n7CSz!|NPw#83R{0(NPN*E@oqv0ou!_Qzb4%fBl!;1zN^>Tw4S@7@ zGGG*9Vy1_9ULeOgQXIiyasur7s}R>`Mrg}jyKmr2otyPjA6CLA_pxOTR$A_NVj^F0 zlOAnck`_2ei8MaBwOqPtdIzM zFF3jXmd(vTJl}4DT1o`E(frh@P7wu`T{-Sb@?i(7JU;YSpvv(E^D%!6HCIhsV@8$08sR$@pKY!4}#KBSoOsVc< z+}|EtyxRzKV>L%^M<%^_9;A`5N~HioKh&r03hHmF>h zeM#N~U|~6y0RDW>Q3+0QS%4Km5%JykCg<^ql}-c1vGP6KtxEGz&oG``T#Dr2>g*O% ztQh2raDwpv_{B7Eo>a?&^yYF3)w-zm=K9!;47@tlzABGp)6G2rIRTXh@?bU!U`<_`)CIHGqM`g;AOWIX_ zsD9+7Lye!$R)=_YAfG=4_B)v)TyzK&&+TKegGp+US4x3zt$%c>#80%ssg@shl9L&3 z@~@MvNt~*V3L#ZdJ4q)wKUq)v?6pPA=TgAjT21P#E$Ioh`F80b;5l~7gXyN0c}r=zF3;qefc9d;U*+sXK5?-R@gX%>1hVK(F%fQh25Z#%X*5W;`Q7pr-k z0D68@Cn!iZ0D1ZL9P9NCq+}j|OXsZj6zuN`=H-J6ZX9B)@Nv?k9PSR-_T=PVw1BQa zMdXe=!Rj?``$x7c{V! z;23Oo2pTnHNGktOB+-@YZgW_aCzqb-(AQe_8zBRIEqgS*RjtzMjWE-`U2qK=*cX6P zMMauN)taAGRcO^a;<5Vl@Gxq<^t;eJz$eEDQz-WjDc%wTERr?itoJ9!Zl((|;PBlxqiOAk4{p4o97Ef9?>K_{<#lFZGp+A zJ@gCUODo<~ z`~IQw%NrpY2KX36yIVVhn0T`GAK6ELsz|(?q31CXj4AA=l_1p|!Kw+}9Az##owR)i z5s`QqpWPZzf!3!>^(;+hsqRe+JP$V?xouCMVK}je#>bY3UcbkNNRP;jPzjC#!Z$3; zDv+TSaKJ^@r~z-Q32-$2+@3|dAja!b^#;b{Q!iGuGQ#$ya1#?85Kbu zn%_F}pT7(BngRD0U!2BT-=BPiQ0**`l%|`tBuB*}Pc!r|dy&$M(-?>BvG$$Ix?VFRAC=cZ z_#(O}~wb}?|bmXzkY;huj;;0!8Wwl#0yi4Ox+=7)He&J`A=9~Rcs zXMw2>v`bMeP{e%z?);^%swQ?apJN+;=#Hyn)^W7fz_SS_E;~V~^}X-e9n9b- z;8#2!-+4DjH-2O$h)Lpdy%h5c1NKrltyoybm8XsE>Fsk{Z9ySF^D8q2CyMt*C)T(sPdsFADdy_1{FGRl1H!DxSn-pX!+sf+1LRB-MX}m6CMb=!RT{Sz0m?o; zafwmhJe^DcErS{@yq(OE?;nH52Bf^Ycj}j(kOWdb1lhqY^c_FnPETZuQ1c%rXsDVq ztWGnJkuB@m!y<0}G_CJQ=ipG3pH`6fKp$h~)XGd8>q@gWD9)ve^2q7l zN#=Bwz+fLLIZ^*yV}rd|m(yQ!mB8f|+t=|8*q&ZTBldqbOYu!1Wf`!i;Qhk2V{*Yk zc&x^`!0n{JxDVtmKHB)jf7R@9P`sMR=#E@UF1MS?=5q5DVX~v<%pJf6mGq=^|=R;&bi9lN21Ao!s9+IfQ_`y&qp9D3TA>nE_}`tM0&zyyNtk$ zhL)Vndctv@ls(Jd$W>Tk+be{nCI|SgSGe@*<+&~@s><4v0J+K}jxYV*X&gZDkpxct z%SazXsp-*PYNg}yTe8E8Lk^YSTIe5=e?vK*Jy`LBX9FUO_XOX@s0!A(8^S;RTX9Xq z>3+Q6utbELjD|zxb}^&MnBP!)uOt2G`rTUr&vRC8tQ_n(W!<0OX6_@unZr9>aR~c; z-8s*SkO>)OH_J2y?#peL_y7atv&C8##lhi@>u&13>Wk zj$|;b0D6ww_JMI7MG*xdXB<>BcUd)-_N<9s;ov)TDbLNTB-D ztQS83CCFcS{EWlD0GeSAC2{MP;qz3Z`>oT>9lZZ7hp1VN)RUYhJ5U$1R1Xa)LjS%t zzngygi&i(N#I_b?6*uMX@fH~JZBaG$f@pzL1(a(qPfKf$)w1%`yv!VF8As*8 zv4wzV-Ih5c3uK6~Nwn%BqD1I$Vy3wXONo@N1dSPiNqQ?6YyBJ_)jQ6I9<_Qnyab+t zRu?YAp>g4j^J4ASK%ocO>#rsG0*Tt1NSKhIxii(B!~@zt&X3b|4K@Wdy{x_R+4|jt zh98_)o&yDKfzLrdL9wNR1R_F2wDTK5Xd6f^sY_3pX!2xk*y#fciK?aAUbRqSt9a+z zQgsf{B$6t@tehRqUxXwj=FXsXZF%e3;B!Q*)Y;gb_>k+_!D9?<9N75xfZ=ogx_75U z(P6U7{m$Dp;$T!{(bt^)F~WdfZc%FAAfGZ<+Z)=2iI<@Hilb z6ro;pYSJBPz0s2fEN-8vyVQtJH_gei*PnfV=`uJiTvc#<^C0y58&g2HSYyj)jJHPG zq@pUmf9#RnLP|eJhS=Jo+#YQh;vk5d{eH>ht%u#NbAIe9=&D-kOUTYTKNzLg@>>!r zie#DiM84D3aHXI;-(;EB63q6-43Huq-TC%qG?$Sj;JMpjrWEB;MlisMYog z5A8>q^KIY(zGmay8xf^e&nu}N6Vrv)=wa32(8kO}LbBPuj#n&sHRV?Tp&ZlQllv*! zQD>34sO&JDfC-jW(b5-nqvo6Ae?s>tpUyI*0g|-)^^waLayX~`fodI32e-|gVgTl; zX$YG#>*Le7ao|hHX`P{jw%A@B0ObK_lZ5F}re>t=+Vd`k3B)>HPizFTiV|A~xN|cr zb}#Lnz-JLCPJw_#mq@_JDnMGgwHB%W;x6oV`j^`2TE)6%&8;C>^vCY}`~H@?=97I*lw^(KPsH+X=!dV76g6}IB+=$|xBUTgr} z_YbqNzf+TzR_I-TX!2sc)k4KFFf)PC1nevbzk#rqNJD>}Nq`q`S{!F&S=Tz&hN-n) z_0Q#Vy}a!SXAmJl-?k2Hmq=RVCgukjYA=?|W_^AP4n-2q$e4 za5)$Pf-1k~xxKEsgN&XlnD~IA{?}pzfNO;y0m48Vn2E5cci%n$F&D_}deIe+BG8O* z8kLg8a=VXRis3Ym(~bHQ)kdUKZy*4Pb^=1rKbikxWu`UW5V=1;cK1gcOBEeNQq;2lJlG>qq~=ljTOQgUk7V9mjJ2&N@7)*$y9)PaXiM6yeCaG_2rmYg*$! z_aNkZ>I8`1jOD^#ik{;sJ&@>MD*{e?3}2oK2l$5ZDJhUyfFPyYM{A}$IffP=;~jH> zMgIge-9P3?9B>`|!zgS*>L82xW?{uB=~LOj`nTNg;BN`kL%ACC6UOv^_P4u)+9D3x z%>H}X-E#qSvjAu}MRw=HV`ny|8u-@^0#1anh03?#xLLi*t-nmwSunw8p-*5l=me|# zeJ{2)>z(qUyB%G07#Cxskd` z=uYB#V2he%;VX>sL)+&kZY4Jnl+>2cH29FJoTxgvi5+cdvYwTxPgUcHC`Y%CzY_a> z24PpP;>s`gedgI6wHS-lkH} zIDz5Nyhm|um{3TGx5opDG{-PvSWIzcjL^vs`_|3SUwLy5y72k9vB1&J>hZ2`C8?CS4ha?NXj=vL(Bb5!h|`~*d9p3 z`}N&ptQg3#JT9P`Isl&QJu{_KFnk7$7q@Hf&xvgsRq0hL9(N4Sa--v1V5I7_bUL0# z`8YMrq72}J@+j7-szJ8D9;-ukh{Zz1)os6GAG`3f;jGYj;x%BhSgf#wzkj9o0IH^u zRGtX@ShWT3^>S?(kus(H`+&%CP{6HQ-@ThEW2eflG;Ra-sOnre~jkUTp=LJ4uq$^9*n%jYtX z8705ielxvj0xk94kW~7g%Y>uC$A*<$t|DU2v5#VLkbsi8u93+ezOK0yO;3J2y>E!Y zIx=6CwNK9h$_$1%o{_la^S3r)BVqLEe^}X9-;6Uv7kxxc*PLN)b>2zwYtlF!o5~*w zNl7{hcwQgdBFPNyGI|cxU+ai}CzodqLZ;hu zp1$ZpVRSm!SH&(YaF$4!6*L>35Hdt$CJxAuXp9&zGmejwn1fx@H~CSPUxT7ubM^kSlfegF)EK@bn78ja6=yVlGjyoC(j}` zZfs<}F*kGjJk}g%uheicQ>)bm<|`plbk|P*D*JXD2aBB)yY=$f+PJ=R;?eDS=_ef= z^`ONmw}82u%TfQHEK?JH@dM@sm*aaBfyXj?XEr1y=^q9L`)XR>Dm`}T?>IX$B46h1 zurt0;%%H`^{fye#eEG;Td(zU5o;Si9d-CQS*=Q%WXm+f8?J}`)PiSelLSlo;$NCGkcrSa%;S zl544(tLB%+okA|gWe7bwF3emr!nK;6xHP0pCljCrW(b$V1iGRB>l(Ox$Nkq)q~}%_ zoGkZ6%hu6KSIpB!*~m&#&0fkvLB(CF1X`5dHl`o~N>WUW^e7l1{R_{PAylUN=E_nq z9tY;JlD^lI;$qsfV@v#Gz`<3-*qU9DQHS6H=LgD#od9w2#Cgslxw&d<3m;vXZyP}{>bLn0YrTx66EF;h=X9hHdd0*Mf*~whEDVDS=Pp197x7N zbxQLmmkussv6B0D-s@+#Dh-n(es(M4caV~n`8&ho)TeDWJ;thp6BYD9Qf6>?h(Ux9ZSn%_9nS2juUKDWdk?zXu@52-%NZ(57b_nMY3=z1^ zcZTe-F8Mr?ZcZ{*{DZyCaF%)gQxL;1)C8k2+#sO}a`MWA={dsZ(_zR^k||{Lcs609>B8(^4c@{o_ehS*6V8(r30& z=^q_4xYqWNLC2!W12+6!O{X>jYh1N|k0PD&CqE+3qH4M=7XA zPyhKlI`?%;-|2HzIB?1*JNUFbP@!s~k;08&mX6Oc{09f` zvEVafYQJt7EO>+csxJ|DThS^e+gEU_TPV-nbNLHTkx^Mi2fv+}{tRa@kejqzsGtM- z-1CnWjM%NPr>{Q-ER?G;R-l(CrtcqMSh@t5M!Lkx&rDGtU*ggjf$@z!D($)cT;ic* zweAi~Hqv!kUkNpOy|g#^4=y$NRK3~sgzxZtaPM@gKJ&eD6*CpfP;Ji~ci47YZnPvU!7pFMs=b>MGs{P>B3 z*91^ANm@9QjH$h%!d&$N81dfp<9UiH)1hlBlt;M;o=Z|}@M#((Dj&5Jm6x6G`G z6O1k%RGL&Vu;q8%{vWe8c$m)-uXrYR_v-u2reXxop&pLaWOdOGGs ztSIsKjH~sMnaLNMUzKvSEr*_ae|O~Zb(h``KJ&@HZ^5T}X=pvNF&gf>&WJ`IgKBE3X{)!`m+D~!g|poL4X-IqwwlRE8}j| zJD94HGt;r=0!>7qXyjhiZU3e@w)COU^Cl*&r-{AiSv|(Z56GhirT-> z@`8!d_zimWHxnM;Bxr(!kM|~(!$Wl$v{3RwOCN%wl^tB zO`>#g&@IzTFsCy4izerZrlPhl|HpI}PtWj^6IYGR)>I6NP<%6^J9Vjzl7v26N>zU2 zM{PzSNvl9O^S_SXe3kR?oDNJGo(`xhj zMEh)9kWNU6D26PFL=UIB&$~w#U{7%-@sg5iqKy8+XwCm!8wor>#mfm6d?jN`d{q6E zydGMwTl-{6|Jd`f^h(lnqAzY}zRVG{CRmVN2M=6AhJId$Gu2!G!#Z_Y9fC|rB9vj` zlXs?nXotb*g6X?qEtn0y&Pg(UCK^O@{HYiiJy&(4i3gp&ApwMYSAM5>$m*O z_xl&2q(iH6F;i1jP+AKsqg>)e?petpNbd*H1dWch7KZ*8RiTmP6d5uiePbDe!1!9G z(SOd>c6VkrH?>jtwp!we{*K(hSCF+E-hC(AL5XQ!+0{O6L=Q{H#-3sxTYSz zr{&;#gTs&Mw9IOFnnl1*TktCQ4b|NCR>PEMD_N~==dvlM~5CAsW zNqls$jI4lT$jr#}nojeFQi?=}DzV)n6t-$y`R--zRAN~Wfn7x{)@qstSH?G)%+iCu z@^rROtLb>w(~HSh9aO^lr%DT+W$*4$e`#LL5@K?gU(DwAP)L&f$p}7mdEy5gxZ;nn z*7Ik`H5G%owwhXX5&lHPy0L*#DW!_)q)|mxxWm=Ad?q;^hlAYh33? zne~Fmf*jbZi%;_a5+m-)82o{gY6D@S6*CU;6Ril(XYwP%o^hg`S5o6(;AA&WiQrN> z*pbLZR1-!H(}N5Uc+v0@x7N92xXstNkjlY|X0KNBibC%K(ZXkHOhm-h%|#V-MKvU) zBw1)RJAJ?t*4AkK32$sA?793Hxm@Jf8l^Z*XLCW$B33&SG?Y~@<(pL*cgl$X^T-yS zi}A%S{JFQ#mUt}46)z$GF0S3J(XC9gbji&}-&1qUxuD3*PDLT15yI2Vf^vFDj2AAp zTTqYYt7aN!+7V+#QLv!>X_NUbraUUi6Y8N7Gi%Nc|7DtSfRou@mV|})DSw0jS*{Sh zZ=Eu6fcV=SFU7~Wc8P4idh{0_(;_h(h3?q4kbiJ`r1SsP{kK&# zXDtM`N;4vbG*Z26i2Id{1T0JfnVDRs*1!j0eBl>ivH@)|em(L>g9+=fZ9%AqtZ?=5>L;dg^~rV2a-Z>Qh+sS$q#WA19W3;t5)5+H^4b4v zuPD_FK?b~SsA-wpqx|t;f{Dq-VPD5a2o~)2H9ka5YH(~%OSW;%tI9V`#KNEW z<2YNELQDTB+`Xa1WM`*UTjXn^W33+x2G^Ap?h!38pHB@|H`8RkB8Kaw+z@n#ZNyg$ zO`hSiL&Gb!Y1e>sJ&i8@TgGuBsEY-c@O5fSCsFmG)nE3;w5k!o91Ug8WEP9{$y#U< zn=qCk#t^=-ULZ=u6lKa}Oz6FVc!F>xC)t*o27=$5mo&oa@W2u(X5vBH#u|B(T`ssET0~bj843*)?l2(uAVWF5tgq~Rn;Eku)=q3rO0qgQa$oi7^l9lR zZ*y~Ex!J;yaysfTc3`#)0~>h#4twi>D%({pI?c*6b#+V z`qDC&{X?ucJ4%ieNK0GRK2-W+T300Ms)B3lQ`y&Tf}z6ti&LmpWhWj&LX<3%gUBr! zEpx#g4HtH=BfBwR#f)RC>5>}H`&YJklHh0B^OO$p;dID3R>!&?xz})U#ApLpR7()4 zOo@hQPyJqfn#>r?I0BA1X$^RCD^Gc4SmX;kb2paH+-o%dtoq;4IK{Igw_TcwZZlb| z%BKyH@|Wfox;Z}=Hm8bcBH%yJF{%GKuAz&vB!NZt$gufgx#=_AJ&d^i@{iZqi_d?{ zEyoDwNH_qmHrU~SNhtlPf*=?MAxzyMZhtQB>`b%Db(+R^YZO{l5`?$FGQLIVpLz^n^MHUC7)Ols@Z8DC@|G z{?d5pwU)9ruVM%}Pm}%n#pcF#Q<8Gv?9yBCfl6R;#)Ou8mP~oL_RYu9FFZ*}=UNIK zCv$btxck<|hHW1w>{n_?h3L=ZmxJLZxJ|Tu)a^T;#Ql=X*5_v@G;5#3-@6{kaJyR23{PTnxF{ys4-t z(5CoQmrTx=>8dFy-w(McZ)Ak(+pRS%h6+-Kuocj5dV2ZNQ|wvUFxwc#gQZSBTOhvu z*U^oFsb#8nG_nrn^Kxu|=^0zcZ(ZE;CU>pH`8zE!c)(h?)y0Fzt#MOXnTj#%QMyYVIcSnJ2KKs38>ZVQ>*k z)ro;c!f@OL;WlfYVuGa!+31aR4hEaxM*9n@(W95te`)K*mNv78fwsWqhqhs_0z~xC z`68Ra>4nSp@P=W<9`*WcPOmt$NbBT7#uc)!T4f&EjYgmc?`F!B&wWeJogBv0Nch*% zpuu9u5EWwB5Nf_VL27;F$%3r^erF>i>6~fIp-gnDvP04Mgp@`%o-gzwoTo|zYN%pQ zt5(av)C%c96E}=uLv4&-d`O>Lnhb1%RqRvb@Yy{JqenW(q_?d>32eM@8&Ap%GnmSCptJPCmwug#a3F-g&y3$ z#k@!gL5jz_EOa4xD_BAx#x%gZ9=v*X+uUTp*nUw`M>vLy?fPkxY6R7$qQ^-?kK0+_ zCjJ$U&J1gSun6fI3yonQqil{BV~vSpP_*fu=6@cOXM|S5*7NA=7r8&G2KaxJmVK)E zjU!B}yxXpSp1G4265&hIsPWyMjNFiu_4l~ITL0W!1fp#V9Ub1g^iF#l!*MNS5?EI1 zn0@T-yP}Rx{3ltMxV6sye#SGH;CEsxaPLz!Pc~6tQu+tK;}8g^%zV-N!qu^@yMDTB z)P7iwx4i5P*EGa5z1%4;LSF0}Fy`D^))lm+cWVwJ$avy*d-;6ie$H_yJH^&?JGMmO zRp?-$pWNvZCXZc_+bsg0yPUpVAtL^cv9f)~4Pr~caVW=otGU(M^Mar%g_kh{X_>E< zrvolD=@nfDHaT71`X=QKE8Bd7H9{HtzIq}Xwupy2bo1_vjSZT)ERlOY_~`R>txk8> zw@Y}pXlL7L1`R)YUh@9u$_)mI-F`lptb?86!c)R;`@Vbbuv?gy5NckBWfn@IhYi`1 zXzfv0CPT<@z=99Pfljs4b6=Xb!^2KE?{w8qZFzgFBL!|wJ8OLZE~R~6T}t#UhUVYX zi7flW|5&r(9ff{w^2xWrwJAjlK)p6a#DCB&Wuqwak=gBhZ|QJT5dz6+9(1BrYs9{m zR)38-)Y0#c_>ic)Jov-7I?KUkF-z9#J5(s6-+4o-^6n{MqR8&hsAofbbYc`4iW5?$DM;+CmI3>5p<;oJK+W~)ly53+MEj9av$O~ zVaDT?!pQl2S<+BZiuaAxOi@vKdsQeO32gEhx>|IH$~@c z$3ek&R1El^QMmhj888`PLAqP~P`-(43Lk~mJN=N@-^`1Lo>>$6MNN*Vpe$RMG73-+Xp;vc!?W;bLUghSh#<%d)6DJba> z-ut)uQ0i}bmeBgxe3aVCOn|gWU8eG^OgW0R%f!}+7kitmDVe8qN zrP)9Jw$OQ94(9-;Af5D(?%d$=!_wj_rgVO}Y<5{DN{iwqy3l_)j3uHg+ctY=?kH+T ztgKXRg8A)ww9cyPA`i2d!RUr8JpR3^T-|O@G2-x1zQt)qg5Tr9<#|n8pM80 z=0*tqeKPz^EGw{{xEn=UAsuaXL^s@#W3$t0wF)p7htXVAB|nw`LCCUw!NcJ~+_td6 zuFx&x6+ZlovLn5(O^${ad?C2?&vdXO#wQ@Gf_<*vZ{D8*Q?Sw0qZ54i!p6Xh!=0oK zMcs&-QFB(+njgvvkN!J_FUgA*$L22Xk4uw(Y(!j?f8CwnugRqskB?yPoPPtWn4IxnX1$C&wNiKDIZv zp8HqgjaikGU4`D%32#sM^$pr*P#XC^YoO!4^PR^#UQR*k<6BJ*Y+%*0@y;6sQDiia zjNFtjq{$tQt{p_BQ?+NCMLqo-g3JW+FlAHXftBI@BWBo{2RwKmTH|wD$KLL{U<{e0 zL&8JYkEYx@kxFxA?!BRLb-WwT?D~`<-1UE&hsOV$1z4RU%Nm3(fx;9l)iPI}s>&#I z!zug>ZL;jo^=)UG&;1kQ&GzuAf>XhX5^pt56;S5SnUWkseWo0<4L2 zQ*ELaFGIG0Es@Lf)60Kyh|+^1$Q|8D{-^b}`5~dp@rhl_qXQLy*$U(IyZ#EI= zG7mBU_v_b#m(N8zqJn*oO6vC+;n!l{p0n20Ok!2~&>+6o-ggUJ%NMRyf#y|@@51A9 zuPm67g50=v42mPdEZAYU-0pnznsxjmymHzFgbN&OcH~pJG}7!zPqcIMVu9anj&Skm)8?Yv**QE8^qMoYt=Gtfs% z!$-m3p!?ESRNb`|=1ZjH3jcw_zFYjit4UpH=OYup+ViUxD!RbCBxSjapaFkYGo4NQ zyE~A1s+T+K+4$teEh6znwZ2%C5Oc2gEOYhICN_>Q3uu8R#`a=^88q65_$o6E`TG47 zIV*Z@O6ZSU{d~G+%G!eyQc2`iEjQoO-tBTjQsPAY}oLBc>fwRt(Y1_hf!N2b6^-}%*2p*oKu2m>? zn<7=ReLImZv_Km)Mqm6j)AC05Q;s?dB#}KSn!mJX)H9oCF=_6JE!B!53|chK^EYwg z5S(j>FBGK6P*vAfOhn}6&D||%Nd8qpAH`1S#-mQr;4^)AE_VO00$bNko`1cyp1lrlKryxj!1!IqcOPfm)W1}UzE5;-D* z4zw#%W3Ai;WkT6Z|J*7lInbGFm2pFxV(SdyMYb?;qP6GQnx4ArX&k|xb{2m;99sT} zI`qD_1`pss0P(Y?Kz7-L(eU=OSZ-Vm-GcmLBQtMK5RJnwO;ZzHIY^O=LP4Aenjzu; z-LiY>Z2Qw@`^)m=phi(+Ae4m$De4g_>(DPW z{;B=yH4oh4hFENL`TOep*GT5biW&ASepu}ECPZ2~6BY6q=jGZ>xlDejwF&quX}@%& zx4&4dJEEX0nMld8_>;d69xOT~#9b;&uS?Z`P{>>eq_cg9#v4xS%9iKaezh}tP~>@F zLNbu=#>_`|^CzQob=khQ)ooGK>aM2vB)lT)4GN#>x%A6Pr*ytMIp48`=SWjGF+*VPaRg9idB9n&3rbObn0=P{_JPW-K8PS2jM(XYLh~*SVjB4qa+KVN)#X zA)$VqF|qlaHJ-7V^eCI=+mETbY*9rOI}`i-PdJ=M{9&dSO{huL zoA9sQn8EWM6wv*|H+r}~=*vh@^%!z<-4o)QDM()9OPHrKOo|>brZyT*mV8$BrmzO*j^sg{7z6Ft1ZQ ztl#vOgkht_lC=4w#mD|!9qE}PeO=8r)-rGY-?@`8oP-VGG9{l*9Xz;KF^q8%&51Qu zv5%=`06GB^Cp-3Q_=bLe(%5=@O8$?-kPel*Hi&`cV8_)jX&WwOrbJ9eJz(^yHlIAS%M#svmQbk%j)i6*S|dGnDyzRTl7=aAUO z?`8)&gsI<0F!I~er%cEYG`q0CRpeEUwfu}E1w`(@1FvMwwd?zj1~BH9n_LDjg`h&4 z?lGVm=CON+cU(PGHOZCufEFaKKT-FrxBXLXPL&)M)$ng~rTG2Q(XmHUy|zSRljZKr zifGJ)aoz}O8YQm(R!{k46vC$AtMf0!t5jT(H$LX41XM`8IXW7%;OFL;Ge`W(i1;F* zlQERKKFb2-w6=oz6Vm3?2}#^oaEF3jw}U5z+HI*cLg{pjFM~9~cNs~^an}yCg*0yC z-L4;XKNTFluf|}DK$~MzadT|*Wbc-KQsRB&5A63xzEC-F)jKUJa%yF++UDA;{+G*? z40~nn?iVeBv;kzmPn^c==!RWFF+q=6k;;*!?FWcXDbY%Os?LkK6qAV>K}`oKb0#gs zlHJ2F`#HrYp6gxkvBXLTbcV;F53~Hu_xtGP*UdF1la-*(d=!pKNx5?*o4FM&8~;xY zB;t5KqE#;;sOR|$&sFL$+^vOuntp> zD7Dp0?x!%lFN0Ht?GY6%S}MvqyO)6zxX(??sT9%CN){b&*!qZ5!%Q+d$fQcr%H>r! zR+PkL0iR&}nW|}SEXJ?yh7vC5jn^s;sM3fMg zTWOeUa~TjOxIHu;&pZ^7X>?EUurZ4uNM!-sd1E$iqE@GQoLqL%|R@_Xv||V z|Knl)#-wC+n$&7hw)|C@LoZA8lXN5ZAVJ8=RoQ9fA|w2_7K0ySsaEclY3KY24i{xI^Ra z?(TB?>|~$s{DHe(`T0?tdq+MsSv@==a&Qr;&qvOUaoo<~Ros7n|hJzd7MhK1=Uk%tU3KZInF-wO| zA?}@RZNb5R)czQ;!yx~=dpS6l%K?;wC= z1WJndaL>f?GmEm8eEshSZS~8?UoTNW;LkuL#kXe&GHj!?Z^a?L%zVa5j?p2Gh^iD0TA2FuYyktzGO8TrsgX1l8i|)D{{>MT4BC>5bI^krl1>d_XD!rS`odD$#%uYeCeRXDuvu8#Z8$2EP^sca9` z<#v)162A(OjZ3a2iI`9WIa4o1ZJys#etc#UGoncCwr_i7&yy?D=wKZX>U5XsoxR!u zMQ~{l`&*IW*YG^QEL^mw+-`uzZKH;nkF+nMd-AdUGaPRnF-%-P)J!WCPFQ4|}%+wi{Q4>)i+vLm5mA=~7U+aP-*<)6?MqK($iq{REAwYG&W9N} z*4|R#C2*1HaHRa7GcGTGERWl&nB;VPB1^u_ z4cVqt8DoR7j*MQyC*Z|KMXhi&oNQ9eKKMKD`RV#Wj7`-3s-vv9eQwEFcP?MDT=pFA z^=j*O-KW+2(egN}{XeU*@_ITves6bto!70@eROu*r$6rUy&a4NGSGjDf}XuwYXwZ4 zgjAP#+yNn%th2ve|tAfpCT{N{aO z`T7q(eiDrNDPQ1K+O#9#)l;9;fJfK@{MwgQn*2u$JY zpy10Lo-68IbS%xY$IE`dvo*fSt=Ex$$qe{ozJW%*hA`9c&?n5ltSvl!i*jDIXn#Al z{iF-9?erQ+W$Deg=zOyW0G&^2?$#~pfRf1~>uw`0E(~?c2l3pZjptQ-)xm>x4daLG z8j8!dh;*%r%$%c#>rS8kPLY0-@lPPcqOo}AFb1fn+iJAUw79Gv1Vzk?iiSx&Kbme8 zElLB{b;)&_oljK&W7$9OPxrGc-tVVCUG={Yd%5mC!4RQ_Y|fR{j_dw#pg%RF7`5r9 zX%KmCuQs-|z+}h$C;usUkbTr|R~MW#v}NW`(Ov&Le~xz|Qs?1H1n_zVZ`Z#qJ@4}n z+vG-S7iujCAaK7F0SL6dzTu(R@%v|Y9f+Eix87;tY1!{frJwyUEPksj#)tv@yMsmW zofg^f67Lf0YW6zmNxouBcw2T{NG$ZlA&zp*#uz-WyGJ0$8gBd3Ym~@x$H^OFU1YwNNDTj!TdDpFqZ|jUBO%JeX{{S&){Qi$$H$NJ=ctedpg1(8q;aA zTGiKLL7;C`?sQpWd3s$ImH8iO>Rf7gSDC4d5jUBx{-eo36Vj#l48~$-ULx}Ar!DII z(xdL4ZRg*gZx6-`%Ml40Y1L)gJPxPIMUDxo_g1QbO?AhLk$wE1Ghr)B8rf!IozcK$Omt`^^wYFg4G0@bD?t2yE-h zWz{_}*DUH{_<~(3>u*s2QUlr!@AWOWrx`V8U9enH9NWwPcz2)>%Nqi9h3Dt5ci&CI z>KnG-_816OtM8v4;pOxJSRFMs%ZBA0w`cW!#&XsGU2owP$(@h4312U0fo8VtmaA2(OJ8kUqMVb7M$$P%^7}14sg%Yc%1P%lD!9q9A&r|0jDIDs{iq}!CKUs(w-GMg9THRB5 zt}HZx;;q&fY5U_3m3&GA59`Kc>hlr+PTP_n&{}#`*0)&3HI{IfAv&D9&TFh%Tc^PA z6SaUc5?{<|?;Dz?pq$C}K(FI5^zNE`euLM=5}6zQpY<=qVjID=_R<_|w;d5lYE&va zuZao|)R)kA^Fn_PN3gfricr?((DAeT?Pbc8Y8##|lZQ1>a*OQ#$$Cx=07d^iS$9)M zR$)#>g zXCT(|Jx2qg+4cg;hL!cj`AEiu$_QA~+#c0Gi<@QIi&3D5^Gfdws>D8UQFd^Ll{)Et zIng4VEq}wgL--=RGd3x#K+bo^x>*KuE)5>WwwwwBZ!(dv2!uqV=uQ#d?215=;w*y# zwJAC#OCr$T>Qd;I6{`}bgs9yY}Dz+yT&vE#CHr$;O zJMnkv?_`AF#t}^TTxM~3Ez$$0XSf?W+Ux|1k!rw4PeJdj5b=Ju6g(E0Mqm-X85LH3 zs^Ku|Kz;aD8l*$XLNI#x;4y!mD3Ac1T^o;H@^sdPC@J4j5rg7a9-%82f|*DWagr@{ z4|g!hHD30h74?80xuI)6qZg`Hf}flPhX`@)X^|(EG}SUgVgX{nMTX-rSw*nvm#L)6 zYb(!THpYQ4jz>KglG+n9PgRGG3X@i{T*QL+2SSoRW7H4M1EjIkb_ij%96A{+9y@E& zFO}~$&gd&c2=DifJChrHG-r6wGdB9;`46=3tRB?k4x5t5{tJ|M`wZ#?pxC=wdeUrk~QK_HeYBMhdcK!&V zG!(OSG5K43S=zefQe~neAD=gs1#hB?`Vq#>BqeaQ5qM%QSTmYKi;bjlEqqX5+r#c< zseYemeA>6+l-%8@74*dDNVNBmA5BpG1c7A{yErNR(@#gbRTy|nmb>4RDg4opiP!M+ z4S2HGflhm30a8u7jB<+JR)MfBOnHZ1ic7|6vW*A9R)n<}u#qTmQ@J@JB?}lYgNYim z8xI)WWj1O6FRqJn%}u}oyUno@JLJP zoo_B0BlCknF(aGnDMJa{{l$9BosEpo2Qe~w6Iw_2p@&8#li!Mv53k{od!z*3fAXqY z%Rml8L|hA$Fe&Z--T0uti=KL(7ayb?AO#Tf%EX|6t^1;Id{<3j&Dx*03^_GbyII_2 zY}%H7&t*5m^6dAAHxHQhznKhwjgzn)fiYKBz1FP2a9R_rQ<%>TKRcb%%WRb1x7k+g zV0-EXYv~xW=0jD*2FzSzcZcZIKeOQm6nwn1S+&)9t2W-rC~(CX;GfMRCPu0V<01dv z+K%1viZ#){$|G6LD{Um2EZ6H^(+eZ_eN8E7NSHuu%L4ykYjIpl44K4135=BkK4KWA1TWd=o->Kj()!VT zI!>``mVb6UsHqcXK4X8i2H74piQVdWVyYL(jDA`8$5D4;f$;gaNv1YKF+o|;XjBzH z>T7a%-Y*IP5j-Ef;{pj8dCHjW_|XbxoJUY#IXr^Vbpn3`%-X3y%8^6IeG`qOzo$IY z6hz}NwpgPHuW(U;o=os#MPy<`Fz0Z#L{C8qE8PuI?qXJ()49mJhf^eiad6Qa zD!>W&BN(sn0-y#rE2_}sSu*8qrG*8NH6AUx0BPpk7+T5awSAm*+ z?$(c7uw0dMufffr@q$hW_djaBQNq$WRj$F28{m7wyRx0e=HJTiP-vDkQ9By7_3JVzqK<04MdyDcd| z!-pa=_i27OHf8G|*f+lrB*5@d&@(|aW;VZny3%InRihD1xN@8a+&CoRy8aeks;MWu zm8GtQajL509dJxcM>lt9_G>O#$v@jY{+yH3X@bIm3S@3KoCU?02qw}o+mEN62HPzF zB-U9Cj)*s(DLgv~bXCV^d$M5oFjil^!CcMsH^6TW_!yew~fla^P?<`p`eJsVd%ETqyDbc#KGdY zXA&`#L2umw!E)>uuY3K8{zBIzk_KDqgyag7koRtm4PmbVhv2gwIcLTyvW`_@^DJR~ z7RT71!hR!sN=C@vJUOd&=!ZWHGMy)xf+uI(fiUA3<#G%rG*A5gHcv~szf#&bxkB43 zU%rfmS2H-90(D(q#>FskQfS_zk1Z_Xb5X(&8DI;E;Pt8F6l)?lvto}2rU1dan+7am z&56dlJFMJM1zX?kbL{8{|6R5ZIOasFQ)hu*Gi|dby87{I+q}!#2qRqBIg-}^;_!S@ z`Sm$JX9J0-UjEJL#BU84S}!6IEa6#&oerdvYLVq9fZHRbVN~-(;c?Y_*YSmF%GWZ2 z?;wrcgZyQ7)`}x01CJZyy3KUkMqCiDhjbY8FYa^27de?S2Ft9hyWp9El55j_vOz9O zXSYnsIptw}E2+b%L1qt;ch;3sl*r~MO4fe1V5btkd7nZsU(P7kjtPX;|z|NG%>rbsvdRkDg~jKjKL3wBz@FzBG$WX{UmXfpd-8|m?F4PK(o2*eP^>M z>5}c>(zgJF9EXc9FzcBOLk)^N~<2uw2tb9)GM;Lern-aM85$yc_vV zzbb3f-=9RD%X3~8RJQjfZx~atlA91tWBAgo!bQ@hcTvaUxHufQIerp%hvJH!c@f6* z&Y9Ulm3QQvd#e2;x(zO`c< z=rSe>wtm8Fh|7fcISJL_3;Z#e#(=;pO1!AoyPW+y>JLq%Wss(l8%pAOb>9i^dS^~w zIe0(ox`l5q-YlK!cSIGy`i3_H&0_08MIP7TvUR(bnV}&Ct4$mL zUTG<1NX9lpPO!z59B=`%Vh~gr@5v8HQ<`Y=_s2yPp?ekNfk3MIR!lK$B{A4Xz1fETri(TDtn=?35LltTKDczm{vGli#q zzVdvQ8y9g-aNR3~NJYQ(mOQLfevkHw=Jbo8jTm&<}Gnbz0wkGKwBr6qBZK74?ZKk zN+6ti&03XWUFu2)i&$6QM?~R}X?x`Ajizc@D|M6I7@nZBWC$+n#IM=3Uzj7ZcDeXz zdb18Rqd)qVl`p5+z;1Po(HMTqx{A-;(#!rOSTv#K#{%=!BYG6H7KFWL3la=1pE16x z7tgTPj7j)Ra?@7Xb129X0g0^FKKv(%sV4TV>KUUuSAYQ3@2g1JmuL~gr(VgeH2pL% zp>y~>rC8y$hTl2*L9xnDUWb6x&g!Ze zTDJb_pnNyxqzj*|CF??@3oGuS_W%vbA1BkLc2$r}rI-k3q|Vkp&4=dTL3dMVJ=_PC zu|E51nZcN&9bb3FG?E>5m2l`W3T^fN(F`F*>|NM4U344=t7DvPKMs-$mV*k{qacBn zNlek*Uq$!g&=V}K*N;9k4=6_KQ4ooz^x+G7(@A87JIw%p0PU53gMSMXayBA9A5FAn z`>{JKnlv7GrRJOtD^goAJ$|ma;OFTKR}FQE81uu!sxj398&*?cU$Ww9XFg((Zl7iNqUJrj4H zqOdPDHq+S_CNMDela(OYH_R+P0{MXt-ccevs2W*|=kqT3N8;<=-(qLaEyj0KYFu-T z)8b~|UMquan~!ulqEFMU_L&#$SWz8Lpx@kj#|Txu&p@srzV-kjHTnR@^Bt%gAXDYb z$(aa%`h~#FhE^y}|7-+geFQdLTX>16)~*7)_ZQ?#Yzvwy0f=FxenHilvaof^=?nb` z270KL4J@)rD~N6w4YvazGUCB=nXc1ss4iGEGhza!fY^O|OHqI(H2tVm)pqtjzG=rd z$fcxn!e78p(UHW;|9CD?)RKq6MgbJ$S-ZT~MD~9V!$i!eA(T8i;kfmcq%p|24OiEm z9`Kes;r*hkzt6!*XF6pO-G@=$kT-K66iMQ;251V}&O2K+>y0m7B~@yUc!iMx`MFoe z9V$Xz_1D6?FJo?5;$eo)4f(B&j$LT=w>UJ7fx`2;@$B*M4!byDD)Ypyed~;?F`oy=^ zFxZ4ZB&o$HT_#=1$Rf~14;PSmNSU=v%Z!Jr5ZgZ4dip`C*Y@qBn2gYb{6m284*qwX zKuVw)Z4j-O&S3C}Tylo*30_pcium@@4FLz9^@%&{mSA%eg<2~}9)DX5E4Uw2Inypi z`n3I#xTk0PoT}HrCEW83FZt$d<2imUz^l&WrH;gI%g-5bZQmv3H`DA>=XH@8RR(m= z1-32U38hB!e_jqdrw=U(cJ!y%g~C`kJ7ii;-S3^Zhj73+yj~fZ7pfGGZ#6D%=hF_c ziV~5>K25cE!v&hPv=HDc&bb1@(9&)RCZw%cVG0r|s+&};*<&)`SM8P8z2&gwg;Cu{ z9}02*q-Z)BxGAAS=znZe3mWUVoq=U`ppfqMw#P0Gph@tFm2+h;UP#-F#6Vfg>2H8s z2O_v75Z`By6!~!EZ<$$b-c^m}`&}YFRVhXJ_^K7|3?BHr72AN!f+Ezk{_aajj6l`F zI4&>*23R^nw?4VvwL8{aYsR=P2<9lu;a}!L6j_C)vS^$%QdZbrGWk>`(L^fa>?Zb7 zixps;zSJCod0*|>ej4&fqDbReO#I}UBv(r9WULWMn<1Ax+=Je&MG%+DCKDs{+P_Y6 zN(T82ae-NiJiBfUEZG&A5NJCg2?}|^>SS}}vzz9*Ty6qER$e@A-QV%mn6aEb_o9zb z`hA_f*h5s%g9;nS#!=Xy3m+V5aQ)=|$>6H4xqDCp0i5z@Y<4GwFD8*&> zkC+-orZ;gN=$cwe0>g|fVf=m2dnsDI=DdnCIue_2N2k2&|NTj!z<4@(T9m2K?5zi6^_)ubDkF8PETf?`=vpKC@zl~ z8xmJFt?Q7%)Bchb&l*1#)hdxxR5~O0zH4MCMOa^`VF8I!nwRYRC&&cVV-}tA=hfl4 zZ}>o7l3dFb2^AOwFFnFHwba^Bvz}Df;aY3bK?V1lOa@o>v!vd})}|2VHbYQ+spDGb zqn303*9Rn}wS|BQLJQ2^O#KTR;y(^NuY|K4juB?!uzu5p_Msr3BCSCf}mQFw|7@gHDL^OgIVEs9jK`!lRkLg&CX=v#M^t!(* zSr+-cgHkNpx7f$%Y>lu#Cad7|%|_JSyxmR_=NnGVj?Mkin9i6-o5sBx$GKDGQrVzZ z*QG4!IBEv4FCcIyM7aoF)pdsdaP}?|Bz7@RnKt>QL9uL()(;Q$R)6+N%<2{609gE# z+-)wjSm0> zL(H~Em$s}2pJ9>^T1LapWwtB`QfjJOV|fS*QR39@SYt^=KaTA6PJ;qbz1n<)G2VY7 zq_D39yl?;J)CAuN7tH>y=jNg7PidhbZ0-Qezm^y*FW=wV3Q!^2rQd)5Fb3I*^^dao zL4Qn{Y4GRyTeh*VUW(EI;(Br3INh5$oN$xMGcoOq5z z$fKn_-yd&&jxBO*U1DyJCQ?gUdqQQ!4F_M~6Qhq^D<;KFjSyfeL-JRh zYQG(ckTQwW^T1`w{<0&Uqaf&y9u0g{zy@cI;@@6|`8NS45z_$t+>xQxL?LP9ZRg}A zscNK^wjy15j~pgGYIb%&M_oEXPi1?YHqXz<>Z4~aAnv4Rh7d$vBMlc9MW+-jOqr-O z<1(hr=%ZIuTL`+TJ%^6JORW@p=oytMr0)C_SkV{r>-z5D-gRt03$dDE)Km4LfCI*=S#ci(T1KH~#$@^lv2 z&!$DKYc*f>r=Rn9Tuc^EpZh${=9jL&UmS(SzeXg9&*=27eioNX`lg?X*699PuwB{y zcG&E&KcV~8<8C^>vXiaK>?;pfERCI{*cj*Q?~vB}(-5ivKl2I&+0Gnk%`Bd4;NqC3 zi%4H#&v#b?L1{@0i5!t891%|Rf_U={+Sk^rO51~_XXh*xF{PjY>{}@ zfnHEmUH)9|vc?NKo6XqzF!Sc09w0a$bDXj3(ECy{9bi$FH zk)%oukIk)Q?(8LQO7=x|I|^Mwe8N`e?FPyBc7$o#FO>n=mH0l0%wr=At};?rn*fI2 zRPzcI(y0%fjqi28}(uPbPSgQu`6;Esp_0RUb%8=L=0R zKnF^bt>*Lg5=7oZ3hJ=$$Ed|qSJRPy{SX!p!Uc5mJxJc#9FA_TV%hw1nOHik|4PAu z0B?!N^Hz5s+c5_y`;Xm=`%>TBF8X=8`(WC#Me=)wH6yO5 z1!M5H1c9e9A~m?h-R@Y&3A~4+Qc2rRkE4@;Yyp7sTz#N0d4+oCW4@|vSA?#Q2NZ63 zLGkL?GVAs-=3nk2oB>$WHLkfakT&Ll*0~rE!uN7ZSd4YxJ2-12hy2 zMb`_0$kTPNcW7RdYu_DDhzAigXa5Q`F^L*O4O(`RI(+sElzxxNJuSoiFPt`R6;*{ofN5OOd zAsp~a1WVn_m@l18SD-z7^K8F5vXryN&n0Qi@jSlM27z4C`*J7B1S!JFesdR7wc}z7 zc;3il^3YGd)1$FBoC<$zH?w$h3_ zHa4QBK7BKMi3WpA5Nm#mkfrqN&gMMreyche)Hm;<_Xtt^u$e8&8js_=$^G^@qdPpE zbZybh*(hm6Iy+I<`Qot$Gzn!5M8TccYsL36?LK>em`1B*bu|S#g_Wj{VYYg%y6t`D=xdL!>9P?VJ>-c67txM-@R(v*^L5Bqrvh@sZ!+lQ?bV(d;h?MJE@ zBVpPUR*g*~m;2-w4D)Y&h>z@~nO~17crf43UbeA^?v-x_f@dga5`zC)A*S(#V=Q#M z)*3g_Ut7HUv7rCe{kvqBr`}$bPvaiyjD;5e`vWyT@tOp}uA9iz%b-6uvS4$4xZzA2 zSdd3s+y;>UzWOf{{e9nGv-7VG|NrnSEIsOs%gXyj(my79NA33}UaojRd4OvD_7gP= zkLXr{WyCkBHv4-$^l__}Q60T1Lvs_(Y7^~)yhyv-o=TU4Pzwl1fI%f%s3Xi|H4iVf{Rk{gb9_2 zC+UjAc2}kC$^Gt5mJtK8pK$}$BRA~piQChn)GYs=Q1m~?@K&57kWnW-{>8HRa>Rs% zXr16ZUG0-fRXVS^gMbmrrQq&F!BCDw#te$g5~Qd!ezgMiGUd5d9N&ZhAviB{dM?>xq9O^F0?FRe$5#_~(ofAs14^-u#bnvw zWD3WH-94`CvV8somehN@7sqI_m;85E1Sf%S=#qH6E-?;U zgWH}z0zW*jX)%aSu&6PgLOTM6NvrW^fa8}!buaDcDY3n*5fpxL z`GIwgQ9!UmH zK?a{79s31NeNH9Lmm?ypRc$AkV9y$cYO)Krl;U;nf5864;ag-Uqb)n)6O3CM`gMVI zdV~c-jL{92+>^fbwGE(JKv!(jF_JO%le?u)plT8xc?#~X)#%iB+@BuM&)_h=0!K4Q z<^G$~CNys%eax;g6aU~dqnv;Gg0`;U$>=Z1FhwGB12Y_nUQbY+B)u@q7yZ>R8drE*x8Ws4HP|g7W4@PcklbCGK~}Glh3=(ILCK0&(Qof7(Mpj$mY|&|7x6qrqTB@xTcJibHe^y(^FFHOh zSeV4#xK&+{y(`odqfYflBYHd_P(|Z0K+na~MUe@iSaB>cH=ez1(pK%G^>nF_z;MKm zMpbq6?kZVrX^mZq1W1FKadHzRY+h($uMhrQMmL0Fg);qJSpi=jSrUJ@ZAys>%JP5x z)OmpVz!p2^bYV%7^l~@-eiDj^D&>i=!GY9Cv96%@LE}io{cLR+H;Te93Ze5$oDXMp zM#Fl+AW@px2}FNzJ_#Rous`1Nu#zw{`huiXZAQukkVJ%4r5p1zOk)?i9`@EWxUuvm z>VOm--Do)4Xz+AojcNudj2>~=w4FX0=QTlI(!1^XXf~j1iuaA5to{D^uGN_`Q$|c| z5L6=s-k6$q_zA6s@+V^4xCFR3toovV&etufXqsraJ_-xJK?*g{N8%QjVt6!*@nNLl ztd+}|?EP~_<8)wX?GSonTj7zW%1N8onnRXDkvpH;_#K-3a@yMp(Ag9$2QEWUw2uCTSw~ z<%2LeE@}7}?`K{WI<5ac?@1{h`uJ0Z_jk6vHK&l@9|;s*6$gbA@3tid#Jx_?itm^% z(m2@%(o~{#i*s4dHt$!``2_dM$~a9%Yy`(6ooUxR_YFwEKSV3tlVOVzJ?FDO#V+{> zTP)e`44ph+<1omH(^RRSea%JGb&>TfKxz-D)1^(#A(a`$1#hD$cbBp80;A1w%AOBi zpDpb8APjE$leo3f6N=hS*1IB5#xLFK%Wo>;Ir%yn8?K@|9l@6Ix3p&+Vp}8_H+zkXk-^m-%M6@l6Gclv_ z-QJj^8jHDk#nQlJlgIP9;n^#T4uL+aTsd3m@7ag4B_E9Gyy&)=ESfPGe7Eug>>m6y zie-O=`EYHewC|*7*Ga!Lp2 z?H`P2F|0SzN@ET3%Y7uReHPUhtmDu!B0P5I0BRo&pmlPQ+XKQrB!L?;iCkc*pcgE& zyq23D&mTY|t~U;r6>4}s8vKA!DfW11;k(M^duW)l120dlXZ>_Q=Tw(L5$vS%#2r8h zPfOd_{;Bp_R*%)O3%gicvhULcrx>O!ki)C!u8m%WKa$N>L2=O*CUH{yg@wu8{}6M; zITi)6{>S}0v4h>;=hby593mx@hUnYXA=Oa>*%JX2ao%)Rxvu=;uTAr6qwo?{@xDOz z*_eZLzPL2xu#v)`E%D|{oT`92_s#(FWlUYaDl5p|&8!!x)Ao%LFRh26rsJ&V%Qp5q z8r4-avk(PiPLv%Im2>6i^`Fbp&D2Epn6`q<2qHp9(Phg=G|b|cu7J8ba>3ea*`1^w zvjKHxi;S)dB9WI@Ci0e@U3q($xp0j&;<4`LxHDktBkkkr0elsjfZ zMdp-_zc{~OinlhrN&m#f@ZFm6-zl1u5u{?<#V6dbNHUaV!K7~B--vI}X#762HX%+zhJXJ6 zH1&-3ga1t+IFwLoj|>ev*!^R4w1;KXOtS+WBK;JHtzqZ0G96Q&Wwd-|-7}k}d!qbV z-2+@TY~rMO{XV$6|Namb6iwkXoB3(P%{~-4Fl}dGvdXGz4+kkm6Dz@=WYK21^|dl3 z;_q`TN){hyHByw@z1WMm+zrjl2?=n@xUhO%n!P|rk^8m2GsHTu2ZzymNH#yoEqK`8 zFq1eqAz&nNkl+v5dL|y9WQgMV`uuKfWSvxD`8b=zQ?M(}`?2KBd(byOU@$RZBV z6rJ@OQVOBnhM{g48Wx7auLr3U*PyT{Db zG}eA7baewO<=aea7hxu9tWqxj0}^e~K@&)R%+u*`m{a%Uc7x_60{OY-dEpJQn;x>z zx_B41z|d|GX9ZjGQ1}$M9nFW9dz~=l*4x;cYoQE&}OzN&?{n>nXB!%mx zHc5>%k^gN*&}zz8gA0Eoa2h%B5&b2KlEUTd<*-UoeoV^Gt+G9&y|UT z$)(TOi)BA`tJi$Y3#&IBQ4c~Pjynirt4Ei#i57>)`uCYf#%dCxI!a7OE`m^vC7brr zjNtlN*%EuYUq5;Fz2THjLpFXMpOm95*z0Zu^9LrXE!l*D9?O(={WSs~SS(It@Vha0 zZyW&MW(k(Vwpc7EaaxaR=cq2M+5-8Th>geZEt*h!_XDQi5K=!|Wrj`}A~0I%I)tGC z@^l4uL>)oSYC}S#vbQ&h6-(`UtfKNRbq8!VG|**31Oo!R36F)4eR1OMhOhBPn7L$W z`xx?H5C`|xVacjp9sIDx2L1BCAp`);20n8)=Eto6Oh*FO?!+tA#HOQ<$*F%wR2?%^ zA~9mBHkpl}aaM4vz6}-6vX!O=BRa%ePgZ&L*P@7ATVng1=dlG6Wc3B1kogRBu!xWk zi@cAVX7G`|eqY0%c&2?mtp2R$(-YPHMBY0kK-Utk5pm)K83d*fxPkP6;4?71sAe?} zq#bA1;6LDBU~LTQvBt+i1}iV?PKmBHGFUMkim*xikPC39>xAxXppP91(&&zu z&iYzb)K1&&teCVcoO~Lx0%CqvDPJd8p_zYoSAZXU;w=+b9h;!*AlX)6$vrYv(zE71 z(pniI$tK_vTX2JxGasuMkYL9~L_1o0gZZvZ;HI11w7GUy?=i2NaBJ(oR3`2nP;~-z zs&;X8w4eESn!uW$LzZkwyPEc}q8z+5;C=7&ZEkK+-{0PU`}XdTiDQxIEc<7y(FKAtjhzkjDqQueqm zpko?O(iysQCj14VUfrBy(rn(j-6G5buIY>#%jMc5J$j z5Ixg1#6!i@8=Q1V<%Y>8gPJH7V`zZ7XHZ3O;jJ`Lb7ALiBOHOx0Z#?5PY;D^bb@*- z;916z(7q%CF@t&21S{rU%BFhV>W_-mPx{qwA4gFR*!JGuF~Jo#gP3f?R+?g(znmF& zL~GQ23Yc_r_Kdg(NA8I&)XD54YoX*P9l&nsX!F10vUzVWy^|l90@D;|^|Bjmc7(ue zn{mfZ*`p=Q{gSkmDG3Am(kUz?HHWmmqo;jg8qZpeEbd+Q%lN)h=ZIWtm9jD)`!9x$ z`N_y86sEl|B3vihlbSpOfO&JIJ76g)`aDAQjJAZRdK1z7?gbs6-@`j3e}W8jJWsS= z)`nr;7qHk-M-pQ&>d<&=5F+V#$v0?#@>a;J8hR=SUSc2y&HX652jrZ1eax5Bf!ziy zUweHKOAi69YP3Mt+6f07x?r6hX6&ejBR|{&zbSLQ&owq}-FalSM-$>)B1$|0Moj#^ zl*RP%RSOND+va1vkBRKj9eu}ds$*hbAPzoAaOgWY6VR383(d`S9;Uv{fhgqk0%2gM z1O@E}m@hadKMk7>M#tnT!^SM>>V&i0*`bRzfH&B+hL@xafWIFv(o8$5t{Jv92jdntE)y+pcJ#tYRd&gwZFq zN%_qP0Lxj@nFKj3Ov0EVU(q3Kq%3yV@rR`gj|lZGya;D8hwL{6B=@0-G&rr z3{61+yz6Iq;@ZJMY(W`GW zrhP((t36jnAz3c!M|?Nx?xE3KTZOl+;7-2)FBsizL;SVe_Q`jYx8yFo4=^6bWc{is zHe(K!1$1ico`U2&_(rh8fgbvAul|3_i^*r~jau0$4Y`&`K@%qHmZpr=r z-gqedoc3r3oT#mjkPf!*yd)peQtU=li&^0DR?s+h3iiR;Hn(N$N!B8ufi(Jyuq=da z&^rAPbAi7WBTb@59MEs6c=r=KB0k`A_0(VT%0agnjhKfrrin|}=d04>PIvKITDbK# zp+dlL`nRp1WvjE4ghg8Tj#h3&?LG9xJ{Z#HB?)P)_b~$8u6t{qeSa>sNZ!5N{rDsn z+C#!cS5%Oa@Yra~YH5+WQWYa%ZyB=)zclnro;!F*#7b)!xOI8a4a<^NJ#QCVZ6mOL z2Grd=j`p9-7>uta_h+x2w?hH|m0H?l-hDluIqaY9_NTyjBAc2y-uspBn|MoYOwtah z@K60#-VmuUrls$gBY~lsmfn1=kfVM7K2C+-=X@4#mo_v}1CY2HojgGIK7S1A`9a%n zGvF^uJ3iNDh`pT-foY1cd8yuLY-5E?0B&_r!k@}cYFJtVX-bi9@|?3`kFptS%$OLV zMC4i~fYE$sj-`48zs~z1fkm=9~9SX(OiMNTG?y{y<;;Iz$BnEDlM&8@Xez z%#73Np*NuNb;`_R35eJ{Wm>6(3SnWEbYoR`_e;D+n}iT`^K91LL+Xd(#hr1=LvE{e z!)K9~YgDTdbhAAO=_o{P_bAmfMx*{}h$Ljq|OY>5agr9>1x@oN#7 z8wyrP+Co)(!qyvzqHnlq;Ox>3C$oCrm_3Xl`y-`Wb_*c%96l3Dhe(x%=AiOQ(Zo2L z>Rqm60c(!xq7^^*6B+^>6P3Y z_fb>gLnyHd&$s>Bmhq2$0HgDqd~khV_NTpdiCbAt%pj|G1kF&RqYODLUK+mO)}(&MhA`^liGP@H_CNw4X_Gcb}3yc%7l2SdA0!(hf%26<$v&{tHu;jj0O!Z zHxC*oAOoO78y9x z(12v5BYCaPOoP(6F7Jh<;CyrL zZE&k#BBFgxu&1Uq%qkx%));V=0Hoj6!?qzjWtZ7+^*QF{so?C4eOuTQrJiq9zLc-> zEuc<%ePOcxWofpKWvmvnr_J4;oY*T|d0H~=8P`mN^~lYJl6y%-r{Vp(!07xJ7vjK~ zN3jBy?c3<+*;DtK;4_Bw3+XEJ34hmLYV_ zO=FH}OtY5z%+xFXb`Sq89aK(D_X;k>FKp75F^BdJev7+hw`+VQw(Y5CDf;&9l3bL# zJg5}hZjn$g1#2g3%=Wx$Y{w6;#t+*m;c-qwV=^a3&Zk_w)Vdu?Zf&8{LI5vhqqeB9h8+2Tp5!K< zdSO#cVHqP{lBRg*4}OIw+Y^(E4jJ`6{Wj+&04h7`_eUsG(B}C+BeJe9ZKc8rpS%?S zmPop{(BAhLoFwldDTK_nk(OqViH>*A?cVds0X0$eKm)7>1)X?H$0}Jt^cqZzIYxPE3 z(W8>#jV&bg0sZ$2$Bj`d#$Tj{G@1v|DQ`lV$xY}RVgP=UgAW}WT=E7e)dd`Cjq}KXnj{}ucDT}IK5@<~L!0enX_}BCV-kDS8 zzPN$^64EIzyGT7*@FKC?EAF}b$}}N%w*4Z{^2ot zM{L3ISVg)h4*mckHKAf*##ivZ-Zfxlzl9R>C-uGD?Xk%I_3M}VKxZs!JMrU!q zlTlI_MlobIC>g)#=X2N5OVajMP~Kr)tWa-aGJVrHKuor+llek*-H5cFNgoDtD@yR)ejG z3!8t!c!s1gAD2oAQ5v|mDo8i)uo6RBIBbp$Ov2}^G z5Q*eIiDlD>4_8<0ze-qtxN~ykYY28cC*-~@{fJQZ85uJVOaJwPF$4^$D`AcYWY}wi z+w9^%X2D1{tFKp~w&@D8$7r5=jQX!v`+~9M@@o!Gjm|qJ&-(q2o8q1fi{&H18;H}* z;@N~}w?Dcm@A~C4TG4n{owjkjupRnB!8BuGSsQM}!Or+zl#2JjX+l^mH!1XWXJ`h> zfb(R=;NCH@)Q^${d&>JRSpxrk!(cs~23r}-R;kDr{0g)i7H zxi}mB+-v2VKsc6KmN|k>;PAYT>605b@-hCj|5iT>4k7Vg$@-#m9Yvt_!`AGD*w=LSXERXetzaR zRx%#K!jTyw!hNB^DI@Lw;%P@&tfslyreIauQfbkfiKkuQY_g2gBWLJRbX{)bAcjP-12+Lf*mKj)ru(%ZbZW%Z`l!8_{rfzoI(!=WLJj+uwlT{0={dmawI7q$rCH$yZfKgEbY6Xcl zm(aFpQ(=k_dGqg!dw0IBS^>O$@rztbad|SzbEeFjEe$out&(m^zOn$Z1D`@+MYXbH z*t>h&@g*yPR7ZQ3^}^Z{(Ca^soP}ULyUb@y|92Ges`QaY1d>KDx`Cx0L*JNEjv$ph zBuKAQisur=XVB5d$usm(7(Z|pzUqAP|9US|=IFbw6&(L=Ny8+e=YjA(!9+6gi9HS3 zf_r8I>(BX&Y49TPQSfyS;3bKsh~ZR^|k&d;9N8n9j0?>pBKut1CSh}(quI;28p`{|D%(d9 z5v-)mbV`O~joW84%!NcV?{|^-hx)rt+tky%*^HC z5%T=bSL5w}-rJGkbV*Mtq+b>H#hWpCcdBTnn{KI~59{ zSF?@MCoMT&Jsr*P4Xc+=mvsf1A`%JcVqF&Uh3f*Kjcz9Hl1_Yz~zv%k<}dd}4(JGMzG;>u%l`LvDb zv{QQWFunL`p@@Fj-z%_UP)CST{ogBcfWVhw-5Lhu5#=A~8hxJAMBHs(=NTUt(ko3( z$E(#5&z}kxPCvs}HnQC0v9=otsUkoPlV8IjDEu-jU(cah(kw#em8&MZt#j6oD)yhrEf)6-%JYBxV$<`7{UlXNxru+c*8b2!;6 zk~jo2^J-h$9xYv!T3dFff2nKFHkB^^przz5EiBB1!KY_b## z_h`R@*e?-R$fH0ZZ&gC`OXih)ARNcH=_4PPB-9 zB+ufYlX_v{=c(-IV|6NmzbI3S>r{z!rUz3Av@})EbL!Z5>z?q>{weHMJSi_J@i<;t z-<>K~#aH!xhF^|Ntlb*l?~!wvCDDU0WnwIzuC>kxOxq3K>>u{C^Zj_d@83Q_QtSKP zP4GXt=O3T*;nsN6072Bx^5*kzvO?Z)bji&mU&SlywPLBSChEkO%<(=dI;v=}=!Zn- zc5HxdV@4~9ljr6Ho7Q1;(5i#QR(hZNeb7ShAGrZ0RFuQ@^~J%V*0dxKL252uYA$*% zE`pZ9CLi9mKZ`9fp}{VS1ss)C^uqUB*3hZg9``d~Gb%~M!sx83rm7P)m8b6?$Fh;{ zzwmsp8a$ct3b1Tf^t%S zD{HN5u4pTPXsJw1y{kSe$%zZ^>^utysJ;rQ4#?5K-C~{n9+MEC6c1H7%PeYa&CPvI zlvF*9L}>v^Taa|lDlg~&%;7Y#9F_up?iUbB?ft0d@ItROx?vwFqp%7BJLj%){kZjK zv}Z-OlddBT;u(2*TIY0(ORSxh;E9cD-J`lnf2(|)A!>Y)&B#UIu9$kT#e*OFoul5U zQdd8k(TZz!ZrE*>^pPLfRDRIm@}#QLZ7lYCtOmBR?inK$`7YO>>6!bXEEnD2_u$rK z9l0@L-WgyNnTT-Nk!Uu6=mU*W@>^HLi=otL*g-1t4-b5S!-x!sTwTslZ^Ty%2Z zs2#dyW>fqJW(le>Qa+t9&u<4JTh8nENxKaDr10jSxUb)DkRM%W?tlDgkHYQiuYUUW zP&}8~WP4{A9jR}S*>ikUZ2U56*k*4xM#;Go9raqn!$Z-)K-JL-|G@OPaEqDI;y-+lMW^IjJ+s|;*3qh8gPXc~6?W_>4$hd2n7l&&yZ(ga=-Bl1*z|<7xS05;RM-pj zBw|3~n~)S6YpA9(F*`ehm^rO)Du?ePduCx)ziD2SkuW}8Scy@byR7$6F!|JVn8>{5 zrg>48QhWF?H9#JPQaV$gR%-r@7zv#<|7y662=6v0|MD)k7`TP8-_e#TE>*NWxYepA zYcIO<%*4r>2AGOkMIDJbC>orIgx|OX(!6oFxH!*J_VT(N*&VG6Efu`vuaEd>9Hegc zmVuEOqBH(@X6Yo)Y&Ej@z{e_VZTFM2JYdzEWa)hAgSJx+n+{9(h)MHL~hhiCdm&MgULT8A6_SW?b5R6D@|K>nkZ z>nh|Th=MQ6BR9`243P``@8ssgsxiF;>B2%dcY@CZnSfq@8g+J6U`CRa#m0`43IYiN z_kqCREnSE>{`cZAno=#!a7CGdJq5hGBI7VQv6(AZ(FvKZU*UT5J!wKtg+~UA{05T~ zW6XvqrACB!v)O>}tVlDOpCMwIgjuBTpS2O(msYX@XsDVPx}dhOq4VdX}~$ zk(2tfaMJN7mc$}YIVpwdH|;#SI`TGP7fLi1ExiaCLF$*KrTY%nbE`Lb32W6Q6T5Zt z3N|^rc`e3e)gIU+^q2Zx821l7=5 zG0V&>czC(w2O$g4Fnzr2iE3J3Xb8IqjgUW1heGo{@EXX>_MuV0{wnPR>WN--wlr$zl4gvi&bjwlwl_lU9YSh7w=Y9FI3{UU^15P z`P@}Z7N_Cd9~uxqcK@xu7A|0V=I&$<0OA zM&l%);p;70q=xn)Y(S9xS*I4W>X@aB3d^+<=@bwelD1OHPrWm-3CtKkLD*q7Oj8tb2S|T$pQe z?h?RZrU(5t5gS2S^8uiOE)af!vIL!#G$GJV()VJnyltUDcTdzjdghZkwUZay(l(KH z1JcHM@f1njf!Q&d%0)u?Ot=kJ$j))cm)0~OtUt|ui zoYWZBX#EXZ7WY`^*HzNqdT z?WYDB{B9B@QYF2d^{4M5z6Q~&%%c)5*AFY2Mrj(Kp7;ZlRBLY%JE(V4$Xr|piuvRu zYKe9HtaUfKvOQ8p&#E>uQ&o;aHKS!exbJkbRuk zQDEVo)fKfB#9Kz9z%J9?bEJ56J{{}VBHu2M+^RKkJ=_k+_}ra43yz&@gJw$YhwwyT zL8P|j;|QL>{pBs9(Q#5%K9fOyhvi`MmDn-YL&0Xxj)Zev*Al&|zB#u> z0Ki)3s}}sSf4oPZQFGMkZv6_GvYGe2nx3itooeWN{W4_k{&ns~ZCO1WYa`w*|5Nwg zljlxeF`?!5lrGi2^N2k?Tv*Wjr;X-!KI*!)=~>&K@{Q?-@7o?9j>{88Z5A3bgnkh@ z`G1n~y0@0|#CPOyHh6{q2BMS>d2_qcH9$>2>;cR0Pv)o>-;6dOcxx!3Ha|PrdN~r! zO;Q&Fo1B}((b`T)pddGf2EyQEDbU(mWo-X2(@IB^W?V!fz^2=1Y;p3+0BXXMq zY9ZBYF3FR?O6Q$DQ46}9B?zad82$Z_i^ z#L6gQ8<_3C<#$t(SNm3k(&e)CkX|9(a#d({a4dhzx9{-+|1o)V(N_gmfG!0#3hx@N%{@QQYo@(d?ZM5^zOH zni@!C!yw}??PU#X^O<_;%pVn<*5*7h=>c}+b%ES^9k?>#rR7#0-p>C|=?T=J_W9!W z{6>vs$YVBWJw8c`^Tl^jdJp~L4=dmW4_=Qk<>Ncp5gqwNnuCtL7;Y_C7xU(cZgSzS zUotnU$?aQLy#p zQ~vYt?>9<%!x8oEY~e=y!=SCWB{^F5YEnUm*+AwgQx|ctppKUp)WzjFHn_4|1Zz7) zcH2VUO!HvhKYK6r?ks#SE-pO$_k6b3I;fM%LT1v@=}--X{&M!Ez(R4b)J2gMgM`>^kAH1#M=BwX+`G&K=8DO$1WR^?I`6@iAlXP`YT(6tzT#tE;QI`6jCY45J!PltBs>)W}p`(%;*!BoUo- zpIN;pT5dpzEZ}uq^rb=gScv$*f)~Dm&brS(>L2AD?*P_KMBwE8rU9{XbCHPcM6vSU zozJ-esXr9XN`<@cA}7tWZDFQ4gjKh4a~lmm4=m9$H``Y*5aY5=oJgrngicbhHF;7y zZl-^I-6o0{8`GT|alf0FqR}=9?sdI4`wg7X(6NE#jJxP#2mKJ$sknK|E6Th7W>=7jD;fF99Y#yKr&a9OvJ}i;odg?dPB*%Ov+tK9{Ho zOZc`Wzn-n|EzW84s3 t7(+bqNyeJdPm%hlHGrRHcsfsByZ@nbbn#=jUF#{vO7{s zkF`eVq0=%=IDo~;3WdiC*egL3k-2{o?Nt}0grhPoKjzJDr0bOr-u=N{&U^K%hzd4` zJ(0kf>%$!1khYumVUdMZc3K5PO$J!O`p7Q0IL90MJdm$Z>CtU*D)KGb^{FaZvC8e~I2Y=yx&! z4JX-wNVnV2-Jkd@lEh%U`Fh*SF6OCS65{CavrEwh+}a+8wdrPm@%eOL50?ug_dlZ} zL{0>Q$>h~Q?%A3Ss3It1(XD{le_$ksNWjcK*!57xVZQ7_q+>gQjvc^`nkH7S9IK-R zzGHbv10~GOs#`naf|-BTdKB>ujZlX#mCtKgRd?=`fbB0u>RH0(u<}e0Iy^>DmPuM$ zBP!y2b=4U05wHrSvXrQpXztm$$i5B&Pm+VJR?m(}AgKiwyp35FveKJQ|0?s$@8Nn= zewnw6j)z6TFohmphD9m0^=j`rY{~C&^$5WgWL7)7rq|QyBjC&&H@eVpkDR@A2o?mClP+) zg3-@;o#h|jVX|HI#j{5&G>};bWOZeO(z1W_Yz-~*v1$xrhlvt01;IupI$o1Y6_wE^ zuzLABhg(_Yl(?LqQC7LDsKGEY3i))zrNzaiy~PEt-F4*Dqzw)hPWppE3sfKNt>)*Z~6Tdk6&d_OrP_w&A9RVJz3uXF=ZvsZ(`RZiqwzV{pZz#0+B zE25F~JQA?U@o|5X&7c_gM<$rrA!j#a*+RP>ew@41tOoH46eMm48rH;Zv|b*Iz9DuU>Wppr$P8sD~WyH7~dW&gNi<1~lGU{7XDPnU0YcQa=X zEFyxk9u-J1O#m=Nr*nROw}8QTFbg0?JzvmO{A`IlwLEmyCQ)#~Og(uW>(=-`tOr1J zEh=z_vt~MU>fF4M>3^}?|8n5;>~7d%PH7T*cBJ0uPThs67W3Y>jMf2I9Qx-56jMJzMo1e&XNvndkA(WjrcWYZq)5;T9^|xfTwI3ns=wg#KpDL&6c^F z#D13Mj&n&VJGC@Mzqr_sp=1)N6~I$;G-h&VpEnx&T{)$ppt&*+4i5uYl5s<*H-#s8 z!36k;G3xk*FlhxJntmbd;k@;QR$cAuAEhl-O?4R8P^tBf>a*0VD{zjP%$U*9CPK~F zD0Ymi(wcmdm%Fb2MQLg7OAHzd#ZDyR8#Jl+?-v3Gcx}?8aRy{D1fZl}-YhYE=wn*b z-dc)X6fpr~)foY_O~%<7)h^|xK-nB&P&F;TFzQo{_fu(Y-nN$y9f=+GQL7d{_xA%w zjW_snuKR3^#aFA5OC-c8*fC=l9auVFE_>sG~=D#J3i-j zQ@Zsc;1Yne0O~PpcD(mAIZJDj5`DPB3EfL=<}iq*Q&JsY1Xfn!ZY13r;mux=8z{cb z5PsY(7v-vSOb95!BGy(+=Mbe8KHUb$Zo_786&(jIrVAaD@w9d-8ap<_2bH@_lc9Fn zwHR_I{I?R_5xA8tRjB$s0Qsja*vRE9nS97R32B&Pw2iyy8gJ8m?eY(W_TP3~gcTt~ zvLk$^>`S9lyVRVHyKk`eWGs>YvUAx^nO}Y~&Q6^F5@tArZDI?JJYc zP@-53M@5wzCjx~==I#(%9<14FXkJi5%NFOS=b5HB98JNFAz-OrQR$1bH+fA`7+`^9 z=Xb2!)bzaM+XnLT5PAczwyMU)*32UVH8}x(Z#t*yxbM?B)n_(mjFs__lb(?rSP&|4 zXi)b?V|U){jr905Kx6per2N_pRSL&|ohK#7>VAH)Ke0Q-X3)HMaIn3#wRh-ulL0OF zz1z;W=7swwloE4KUbe^YetSCeTEIfq@}+>0xtp83we?j*Z-vO%^!HyD_M&Tc=ZcCg zEk64C3+s6C`}>j6P5{PkB?2|E^99&{I1uIi(VDfLpW!Q>{8cb{&jXzEbM?+lsKovq zA;8I8om#}2Pfo!T0^t1NYrUkl`+4l0*C##X9T%iD!`49m8|i#A!%tSOj{>BaLeEj@ ztVPzyaj3MsT9*EhKO9Bx>Uw#G&8$p~q2FTJ6y0#YRndCFU4qc2-dk*KJy={!1Q0D? zc0wh^OO?ju@M3ywS?BZTiDlx+L5&{QCy=w6eTN<(7m~TTZ7#mmYWc_tj zFq{%HMtq_CDwaNa5-qxhrWqS?%ctSuHRrhi82)z=6Z?j zc5wv7-3d47z!e07T=I%!!RCo8Qx4_p$W%Ma{jHtog!#ib;gCt{1%JR2fKJ>?DU1~j z5UV2ob}tsnVSIJ13-DE0TOXDc+V-+FC#EJ4k!O$+Br0e+1O062Av~PexCCiF9WKXe z9!E^{86s^&MMVYCOGmJYFvc#i+Gtfmsh<5l*mI;IhKIev5y_yDNm!7e?{}NQ!_`U` zMq1j!H_Y>S#Ei?ye6B;R*{ACuC;V4Sp|V^1`+gUDv?pD+C_iLiF=JettSE?BE%tgUpnH3OzW`Yo7iww~MVl8a+*AEIu1Jk8(~_4<7$Lo79IRSRb)avH8JPg4$6c zt|hde$s`RZ&LKIDx$E%|9YS@TT%d?Z>LkEz+vWQy!Z+ zT40*uk)#RdpiL^lD>eueM|%foDU3{@8DRIXZ2KiQ>0ckj`_}cFa~mJ}{NI@L1*LqT zhj)tSviq6Qi-A-AMO`8~vMUL5n_rm)N3xMOvzo2VA+M#Z2VBfk&4|Ot+ZBTP+#W+6 zxnC3>EjU1^t%GE$<9iTs*A=`+fRx&wj+$l>W$QctSf@mf8@cFOt;r!5q88%$<(M>) zA}^YRKR`}>U(A)t9-d6{W3RikzV;mM z&_3`vE>81L(Zr~#{#;ZdG%htkiY1JWwIOm&+lJ~GkKD;iD_El>H#eTMtD+&dwJ^8! zX&o1Cz3Djj+Q!0y-_|sP@>1QV+~nu^_R$GQ!pGeej@dc;mGLA%y8tu>YurG)Ya&BH z_m0b&Ksbc|ge@yNH@-s#ib1ZNVYzyL*W#Vu(Q&e2S7d3)9WW1tNTH+9MUK?s1+AOEVJa?W#&rV%?CTH{Xx>VOtKv^ zxToKpnQ%oxY(`h?RmMf=wO~#}_GJ+aaLam65Ao79!*0$02LrvzTN$gT%8O<;H$f8lR?9%fhV5T&PfN;z_n_H}Ia|4B zb^^uyfNHnR$7=Fz|5)Hof(=?p?JKNtb-3RT%bWjd(`V!F_no*cPR{{_koKywqmKl2 z+p~KXUqtV)boxXv`v*^78NJLtKUvllmqnxW8aymi;?Ig~31+^hL2{vH$zoh|{M=hF zLPddv3f=Q)u!(JNv)n)tPR!WqDxR@9C#1vB#C+*3lc$QR_Im?WbuB$PBpsa+?*!^B zGXzHnLsX@y**YbGb$cM}22DpE5ck;nP!nP7l34E$ql6w9qO|ebjfRV@$@yx>zhzKk zE&EBR{p$H8yK)&DT3tut!{t2mn z!5$0wqM9$B-;J}2qHwfBPWtPo#xrLF8)2Uy*oP-f+q&6bK2Q{4G|h>=|3?}EK+7+G z%aZdhbwscbo-KnKB?QM>*ZtJ{;waHaa%K%7r&9GdKMlRjK?N7*aej}=YIK%6!%4n9Svr1!F%Xk_`r`RL!ml60_`mmXMzF} zHqji*UIg0rdiY2C-lG1Bts;X$%HmMv2BS5j`Qwl6F7YcZY?4hGNK9j?5T&=H8rRgi{^>-vK4Dt3z_v}1^?We@k!f;} z)8VX-LqmM1kV|d$E$w_mZ$cNh=TxvAd_Hm|e>?IUPgTNzJdKY`NFo^~(?BkgMm@Sh zJaQg>{EiJNQeB0TTB7L)t>z4PjsA)>@a_t#vSR@N2O!Tgru~R3uhBST7=?hNE=rWT zsEB*dROH$9dYqouvOt=5L);+*ezHZd9yz0HM{3iG_Zv{rnx_R9WI~}rTMkf+LgTar zAi&I*M6-wzu-vI&^I zO?(rS&hc;+Kc}|1*1^CBPq0pj5JNYS$406?Q#f*2mu8(h7tEIDVF#54CjAlizG42x zdmAh_h$*uEO%9UC+NcQ1i&IP)N6NJL+V(*%^=!kSBcG4#Mz;Ardhxf@EZqT<`OStq z*F^N{W;8>ei^7J5$xIae+GiaCgYAm){QO5%Yx9o|meQJKjc{6;{G}nbvVsx-Y*^Xu zmy{GK%Ma7Z9SnfbGu8<~Vam?Uv4(ou@9Fi+8nqksxUs8W-N{x<2f`=D-@l(oNQ5r3 zHj3IWSJrLFB`aGhG5A@1I29FwR$sRG+rvFku~nYNbK;Tzj}eL><6)zZA~pj4QqadU ziUPAuYO)~PZlZaFS-Q_xIC`O87MJNa8yD%)PW&#JcCs)xA$*qMvGbXT#I~P3PhUEZ zzgv<8j7XFZnHw`u7@tLPGh(S9>>B$9HwL}iUTW^VL!e7g0D)RIB~XpUeWhDQF@fj= zkjC?&^Z0E_MMOSJv79@hi=hVw&}E;VFV2C>eu4EDHwi1#m(+gxB2_JPIRs;GMZeZMcxG+n30ShB*26_Em zX@gp#gVgiM;Em9W*8i`|dZ(vr&3R&ryueTWopvVt)m$M_5RhOwcV1Bp>@jP75OSM! z$eSUYR|)biv(WPi>a$>>(7~Q$D2l zWm<@D;+`j!UUXzhf?moKpNU%1$XXd!QG{sFNC6Oq@?IqXfMaA!ouXOtw@sBBD1*V^Z8a(ml!}|vFO?FH75b8KFcni)HYL( z(a<7Z_pIap8~K7n@N_?$pp+AFI*`|b)$KQ4zVfRd7kMQg7>sYgWrB+z_iYO8c(EVs z*u`vvcCAMVF-~?r`idQ`6%zTF<#&hC*XkF-GhVfKx2*>0NW{YoSPON#+$O(84Rk-` z65D!i`5b@dC#1entMW4G!J+x7=a*S)-J6)d?%SJK{!vjV(u_sFg}8pzje>HbT>(#-LQN?)wT!V%c~QY-?=1J? zqU=D)#N4NnKVo!iM-^Z#P(v`Wr>5rTzkpeJH{VwN=%i^r^7Z!C@z&Gv^yC?>_HVib z1aVmeTkz@WIKmYUFm8oIVS$g>ulvSeML;C5;kFW!eR#e^l+S09E^9q#UFZ z>})(>b!eU9Y5B2o_V#OzQP{WH+lM>6Yfsc{J|$ElDnU6630|lS^GL()pb)d3A+5+& z?AjmY72C)cVPnyWvWZ8N(d>gl6%A98DLXWh&zBRVStx=mD1P0JBOvHkVMda=$-S?# zStC51$~hH<5fHyIz&44Y*`?Mw4+}+Vq>k*`@xGB&>teN?5$Rcnovz9G1cdan7c$O& zUW-{E4D=lEiOxg!X_Il%`#pbjVW{GN~!9_x$CQ$;`DX@*nzKlgb5mv13?p{eMcPsWR7`r){|-`-ntPn|!n3FB6+? zwiX}%V2xAD9=czv5oYs~DkwqHH8onkA`lV7I#}?!`HMBhY#77pW8FNI6JmUHmUPkx zlk}3Jo2gW&WJF7@EFzP;%^u-y=N|MaJZRpfS|JjC2z|EL=`%YS3zR;jh!jsR>WPEr zkSI(SEEiDIH^}f>6=_JFdvCfNwc%xS^5pEKw*G>OmR@q2k03v5m=ddz}Z3P7* z8$CxLcp4e$$mwX>9W2~l4gek>l~_|<&D|Fk0Ot7%exj)@)^H&v=I;YC-)jg-!Ze-B zg;<5n0Yc*IVEj%^-mAQdbqc3*v46+Wov=J3K#}EhtWk9P3{S-}XN8Dz`;VeXyJ7O6 zVO*~x$_PM2I@1uN7BQbRYCCMSzj`Q8L!~$*nmKbg#(L3hH?h&RhEBf+4V^fi z`E}ss2t`Ws5z9B|Zo@bSj0-RFEPi&6N79O>V)G}mt51Efv21kr5_||>ys2T3&WCp=X!lLejU8;V8??L1ew=Zk&=LK<-kU)(oZx##$6a$vq z+I@vd3~FkeDm1yKIc6r*UkBLgp_&HjOJ@bSx$s;(xWooF zZH+}`jVQ=EE*_@nv#3(O%lEwnFP1EwUI7&wAt_cYebz2g-|pL{$>(|p%6>1`+uT&! z-2SSwfw9A!H~RU--xwf~8cIFdu5cV3ea$O1N9N#jxk}5%j*4!b%BYU0$2M`At&Mdt z*T=LiT2&M*vlYa%&B4K=X^qlb-c?`4A&7pT^)pcvr!TZmUXYS_i#oRJdCQ+~7Nq@5 z6Ykd#j#hZ}Yad6n1N%mQ8!LUt_NhharV%dVMBMxLG+kN9esTM`3Fg`3;Q^GcA7&JL zp4o-ea)({E{waUEtSC}syCK{2JA^A6&93t5YnD!hYTFB1E`|RkWgp{eGtaew+t*O*yKba5%K*zF_du!=Wsf0~E7ZaGA zpPn8aKPzZxXsOs%^-)LFrq8KutvLATvo9f+7F9GGD(C$o;#2ibYN~&1K3fDx^jzOD z5S2L3-g14f(A;9^53;3AF3IY><9QZT#o@J4sFl#)0Px?z?Of2i8IGpM2iH8})i_Et zrJ6HBzZ}EXTHVzikRFRG45$wa*{=a@ZVe$5lriGimaNymHIqw~@w?7;lscfLNYBEt z%BB*D>T~n*g|BB??Q@ew%n|FwShlulmF*NhakIB_Fli+Ro5MXT zyKO*z3jj%G=3?nD1{&`tpwOxJniG_a%*9bKzjz!&`GI12xq-t4W>zN8&-0}@)kWDW z9~D^{?K+Jufc;o^t*nj(DA%|w9L1PfB~+7A6B_t!BExR$-TLA`ms*<$8_oO2&z0&4 z@jo-}GJG=bMaTzb(SJ_kX~g9v{2X;Q*ibB2P-XEUt+3#~5Gsfh5B;y5w!ULBQp?~N zYflk8XTVPlD1XMYPv|8{p^Dm$ea{1%8lA#geJ)K}fq%2E_n`xPY1G8FI@m~|r~Y;p zK?}4Kq}noc6*5oJEJ&B3sl}91frk&u8$TW;lIZ|OT`W5ro9&x}K*9;u`(yU=*zAg{ zodxXjmuS(TIS;H_uwr$oRON1ng-ao9S1or;Lw@|72E6(Hf>h|HAouGh@HX7MUp@zm zizK8Rl%_9J62-gF$2Qd4oCZj@larI8lVTISE`eZpb)+r(9*|vH9cAVKnm(FGB~?vL z14k=qac>y`}$>omnXsOJt%b!T59E|CPt6WL)J%_zV@Wzi^ zk2K`|6Hx85)RtcU$NSr%RNcRm@?^$f$l_sr&w>QfNupgjXq9xlf#7ksjOIh1FsPAs zEO-^BE~Ts6Ij1Al6*{w1NfM zehS<58-n9IZhOvb2nM$xIQt=LA8fJz@_ zmHhw;9_ZW5xuI}zIRTMyWi>aD6p$R@V2{SAaRDQCtTHMvH+K`zq0r~8pcZs>=SfP@ z&xeLaehUw4#&cs95TWBiP6CZKR-VY^m;usZM@TFzbGgHuTV^DxUzmXrqm6j^V7r6& z2jSn&vO^dCB3BM9kKPHKe4>9gsYitF20CnWzpjOga3%V#F&7-4d+Ce)i;1RXnjvQr zeH*{?FLJu5JQXG5SZ0cAg6DLto^33}E1o=Nz)-u_Fcmh~RLFZyGkl0-f1nwBvxMv|N z+e89;4cF=i*id?R-bH2Q&YW9lj5-$}I3Bm!lQ-7+8Ho@{tYsPg=5(n6+CnT^W_wz3t`QM<@|A(!&4vMP@mxmK12@)*0 z1~#|{2=21D2X|fE-Gck#?u!%L-GaNjOK^7yeEZt{-COkmRh;4vYR@^(%=FXK-J{*l z=_YG;eO_airpM|DrwSU{2xEqoiVAg5vE+9?H`pqvjJrK;H~8f7%|s+6_&HNGy5PWC zc?I{(6`p_2>z}#w<{iyre=g)NWi}KFASnL|*(<4q8kB+nY5|+ieod&L#EjpB{&ZI^sIWvN{SPNMe6oEOj#7WN(IZ zgtyOWeI$i4E3bt&tNgh4kI;>#;%fj>7t^I6Cs@(nS8rxKqafw2k_W94GY(_>?ArcW`Dsc9-nhI3` z1?axg^klahBG)(KD>G9p_F-Yf%HMgR7)arwvUH1-b2tW*74rhYEa#~HC~S0{UX}2z zoF$*P`*}kAlf`YiI-c`Z&uHm%gZ*7bB*KSPW>2_-8eC!E09NY5m`3xi`2Aw?^ESHr zvYg0>di~&tcRb4ag4swO)-qU2oT@oi$DO(Oej?xKtk_q4dY^C;t=aFG)J^vvgTqH@ z(SL+zkC39EgAfo8EPc+$>5=g5=6G)JB&hzdjZ-xyDF=sZyP-xKCb{o)>gy9>PGULw zFIzaiRBR2pwP{ARn8NKkSt+J;XeINgW@SiL1+mHXPOd$w%1E=2N?~J`2xj0H7tLV7 zQAN#s3>xYga@#$O95jPs)W@CA_z%rZO}TlsGyniQH8~3(U!)_eTQnG(Ac=04^$SQ5 zC>7FuLPz?QhPVlrGd{=<7Z~1d_em5pY(F^w>YjmkM^z%1XGXs!4MTCpllc97HH|6Q;jm0?oBA!96ghS*RLT2LHZpC5H=t7}E8Td?aI z6dIh^BZ0&s?Ds7KkY{%;5xZY@dmgHl#rvEP=;wsxE*MHU{t*PEFDG4Fo=^WdE(5h9 zOtIqkP8I>&Blup9Rd!iK9%sG@&xjHO$M@_jt&}dgRg}2OCDeY-$lDIhW zlAat($dS0O&aJ7d=)|Qtu)l4nVHFzszy|PlC6=K9F&m+QvEx2Fu&#^^goK2EJK^cW zYHJACA?4apt=`+%=5bIXl4}Jf;|FzL9D6!yYM=A$XX{CSC=~!T+9oe^SX}j-#nU$B z1{Nj|HR6&~Iwxg3iM&T$m$*tip^7LN z8pOZM*ngo|seFtH4zg!XwsKaG7NirPDRL@gB{9!tpz&}XT@biKCbJ#9GIz0*ZN()P zPDOh8ap&+#o)j1tnR`IXovN|d1Js}+f0KIYZ<9K%`k)0G8j?^lf(0y7UH#14l~Hyq zj}DZ8vhWd(rEP6#jRM5UkYgX zLI!!HP=4t#HTDuM3?c|aEiz6o|e7^ClYrIN4nm?%NA&}XQnor4u*-r3Nt5W$s z;agS9Q(nNm;#AuYHtv}0D#wqwJTa5DNgFpFs%KnSmF|TD3nr!Oe$xs~NGet&r-zX{ zNP)hA4jZX$IoxveYFHFZ)yyvE$;7qJM^#5G{_ITWSdRg}IQ&SR;GwCo?T@klSco5I z{&6e9lrW~7Cl592RhJhjyAtqz3i72LH)Z$P)xOB|_7=yUH%+T=hs~gUaJIi;R~nqF zH2La^k+AgCqZ1GFGW1-Xm3%)yq>W|rgV;!k14N^Y@4G1Z9{&qgEdKa~5;&__ZFxd^ z&farsc^zsx-q%qVGm#aFo!Sw*geL_J+5^KwB_d)tm*^qUxrdlQ1Mls+w1)DvMyHGr zi+MnWPNaY@pN#D22xH@2b}dZB@@w|>i~rQXe!y-{S}74Q=D@vBD~3(DPY$&`S)P^c z^9-o*CpM1mmX?tLi`V4g1QDgm8IPGc%aqGp^;MM%C8Jip&8EmH15% za|VT#iYBybG-B~>%3>2#@i;I^?7~}IZapwaElxIcECo-`2agI_Yj4$n+Wfu(!ztkD zNiS7+&;xQeorLoIf}%1u(L>?rpSdt<(*`D?Lo);{(RmcSLQ7Bold4%YHYK6O<`wOFPJw&1=QDTH}pUX7|HBYa-Mpz|?Xua~aHUC%gpo6Mb2xB^jY05wk z`1n0b?PW?ECg;*&Mqv-dEhbP??kPky`ew5H^FQiz9N>S8gmcjX41H!yeXncz8F3qY zOlwL~ZCT;OgUVD)<9HhFZbKHoDv5uXB8!MF0Sg6cp?(p##3_|@y_4~ml7*PkSNZSW z315(7!@96g8%UZwUN@mFFfVT#Jv|YsWC?U<F0(uJMiRif~s3kS% zMfm)JfFedKGM;GkD$K(Qi<1n&>mumhH@_o8sAe`-pSNOTFa5f=SoX?CQX2wjnM`a0 z&f;jhC(mytF~SPom$B6m4Nj2uPaZ$}vzH=sS6L40ho(&5n|1ANpUR?YS+K4oj3jg} zxVuj@f9IBESacNt8CaO`n;$}Em!ov*HB$aWuH}O{os<8*4eAjMzP=L+{I%CWw~`jWJLO+H~yt(2~Lni)MtJV9MTj z8_mjw7@D=toeAVqGT)tFa@*dE7=O2ddNR6JpF$<@jEbYbhz6n^T$)zd4I0&MSZZ0ToUYP34Cae91&?ka4RqSVv&LKecUYcBF0}s&RR6&g zUOF`Rz`Wk+c?@JqxKTY^&HFWF8}ru(duV42dhOZcinUPtGXCl2` zq#xCe_=tUcSx`YytsDwukXRT1Pw(f6@e$s>78=5!(`--Vre&}3yKFx|+oPkwj#x%n z9T=Qm3F(3;7L3sb{P@3@* zbS~u~Z#4o5sy3}E>Q{WAJ||X&sS2&@ckO`E5j{N=WJmxcP73los=i68s2ous)N72M za2rYucBSH88ZAn5#R9ep4LFg7px35Rbyutj*l|Ah^$yQ7=(Kwu3`L$3#8|Kgs&ht& zc#FJ7YuSnL#5~-a392d)AM<%xT*aJw;cTPoNG`ZAm<)H(8venC$kjEHLGvw!7Fldh z%G*pKC_2(SwxlR*It{OM)tu!E={bP8O#;n@D8yB_t$~}F)xun!KflAJEf3-klCu6F zP6hq7djCIy1YQ}xXhAskFE?FVkvNdx7Il`bbXH?%9r4}oc}Ff9*RY1<$GQTE28#_J zR2m97I;Q&cV}6^fTVAM>#afhH94fr-j!9n^FIS_-VSV5NHGJR(z(p#Wy<&5A#1IMs zNQ8x*oevNdYmRUjw7H!gw|xEku^Dx_?T;^|@qtW_zz52`46X3Yjj z4G1qvFhZtqWexb7qn|Y8`zM1su{?j>!T&cLW;KguP!a!~E)*|fGCn@>zdHa)H{~i2 zMdt@~DZ;B_NVEX&RWCk6Zxqbb@9k`Zm?#In zjz^X&@o2J;pMr(~Vv`3ffB5q<&`Zp7X^dd-%WHxrfX7Q`a@9 zMSLV!-)4#z{wXb8)LEv*M`**Kv=%OVBH!Es5x#jbeuHTb?IWLuMh5^>R44f@o^PXunrSmB{~}amLnD z%mH)w2tot`Of^c#s7IHT4RDjQ3W~{P=F+YKAD@RL?!}dtctSIKR;I>A9iHPmdxsm& zmVAD%B&4BFR_~TjA7yX)gC?OoUr!ups(&Ixu=YGnwS0xg>-W?PEHE+HI{B+ZyMId( zRAZAQr(X0pJpMn`^WTLRHjP0!z(0sEl2-GV#$4=I+SnCwud-yR;s=qL2kJM~4aq?@ zxz4h@#ZltD*tQR1iMN2hN9i<@M$eO=6Ye`gp6fps+mwu-jaytF%q1uYp&&2O&?&A{Y~c*~?m0;YqVAqX z-YAyCLthYuGhn4(<|3;B8jMnK(gGz$pa;N;elgxu1$0+zJKcTN6Sam~&S54haBspLAKqCMVz zIXrIfu)Rj=+_pbr&~V7cs2V3cE0b-Ajlr)^DPP^TY#3Dk87(%s_-F`!_fdcE3A~dL zEj|)2)t7lB+Eu$ujQ3_j%q#IQ7wT62noUX&?=>hqQ6%wiSW}5j#Q#KN3EY%HgCn`@ zXZN^hZi>A@5aEcv?isxOp%b%`=j16xYfE)v%vHsi@4JNm+Um{sq4@gm_6=h27haf^ z&%?iWW0gj~6jsuX&G*ZDn^`W#Cl7n5j>Z{765|g3-wTJp%|(&gUw>f3EC!j6=TZ|} zDfyI*@P7_6VC+40g)NCzl#T3`L#xJWmzbZR{BIuquN>dbs!Bmq1Wvf$ZG!sDJ*b6a zZwpg&`DzQjK~CO;0-;&)Dp++ppwqt}3AD!yqWM26i0H!%LK*J~c5j+Lb^5rP0@3n) z$Ku|K%8QuFPBsa{zdu+1GuQw1`P87+POma$e<6IrfB(nfmEz<}7t~_5%8!R!U7o9` zn*7W!N0VdVQYTDxpFiHCU!8p_DwxowVxGN{u%wff{FhSdpC7glG>fR9|0&ui=v}0i z-nLgc0!wg9-hIRM7KKf;bT1qV{iF%P^j;!(c>P9mDDeMt|LYQg9R)MU`uYXPneEub z81$LR_azni3qtK^EUp;u^4|)p>Po3*O<|xypcc$5WJ&(ZX!e5BqHC2VXylnAjo06w zp(IC={A~$p{?r8OzmM4Ktum|RiC6uAAD~)qTR${d9(yVhySl-(GDN-=8-vs*vOXN^ z`#u$uvzzeBmYwo|6Os)ILJRT*RI`inI49Jm)f;eN4IqN_)+I%QgNTVD)ta#IFqC09{fj)eU?R~nnmSZd5hT3REhTGaOlG|;uwug;w<}a*v)~%|CHi? z7rN+JI@>W{!F};_YpOpLA+_PPZ)H-l3PK|b5Ht@~@&gdP!JS%`yPG_2Sk*P0%Mfgm zL0zwWZ(+yvz6Bqv2)Fi4vHs>XUJJ6Pd95?#wx#w<$>kD@RVo#&0}bbVhlAaIDTW5d zrkVQdEdVC;k&ZsK+s-{AwX?vi5Yk`ENH4lSo&j%uDOcCLv#{IRz4VOL+8)iQ*;zMpRm|JBH% zd%8@5-%{dPUutJtW?hp=_Pn^%Ru8MQDQ**Fz7d+bi=0D0J&<7bO$>2LcwQcnat$@eTmr zstgbCr#PVu(t>yVS)*AOnAjTzK!8OvL$9iLc*yq4Vu&nw(!1yv``+Q7^6Z((7rCPr zAMq?;E=pCgmPM*(ZmV$OWt|B$A(rcB+-1xb8Vt(1$hvt?{CA)Wxnnxj{f*;AR$=%n zm->BwOuEmBl&d4vQ*X@j>%+^K56Y^y6V+Xkzxpd*^q=Xq>#S}J_XbM7)tE;^wIx)2 z>esc*XHSc*D|&?SZcHlA*+&kFzF?Ai+@{%rza)GB-zW>ul zVsc!-ZFbVtT|hv@PsDIkuT^=)4Pd`idFD|TW>L*bm3%?}-{TsXi!tTc1C0>LGgPzv z`t1yViZ!S`Jh3Omm|xRn&8bb)ZbjmKO5dp?!|uH0xAmT-QJ355j6y)v>IjE3{T~sL zxpJi#-=kX%t_c0lY1_}Q$8GSgn*Gg{PtSL2ujw@{1eM0jH6ve#Eur7lBY%IT<96F& z1g8{#WH-x}NM)TU@C}+IU2dxR;%~%lHbt>_U2DN#^E5D3n&Q%Kvr{@>Ge?IX)ZI0y zTxo<-8$l)-*fYtg1vs0i-TF-~6aKA#Z~p3DR;lQ-4Wz_XG;jX4^i1>43S?hZkn=II zl$BQ{Rm^$!1eOTa<9EfFzPUcv}MogNY~RKLruB)Q}` znvrLKr0`bU*y^gZBr_;54N_yy8fn=f@~(e=^2=Rr73FOaaKI>-D@Mz0kTkA|*g+sA zPc9$-3?GnidLhMJrEIL-&eYc0W;Q$7Zj%LdAuc-@7_C)Jx&hZ}Pug@lF3hjWpUR$o zG`3lJ?4E7!hNtbhLK z;=s-av!zmhXaGEGtsmMC6B$15fooV$Oe!Mtn16#rpqUv+E~Wh*s32lsrc{)7U#zs2 z{^6jutDRj%V3bLN3{n}ep%e9cNg%w#he{CnMgzJMa2s}tA5t_J%~>)xt=d()Ub zGc^H~Y}BvdMdSV~@6n zJdFxfBIy`Y07fIO8UY$>?Y#!jjnFCrQA%_><<@$0mxy)?37^O-w=Tl+xQ(py2>QSS z)+Uj$w6jTr=E~PL&3+5n)Cc*pVx{!fp*<=)msyi6z}HeycSx*vyCGsJiH@sa#;Y%( z?ELhZo~(>llo8gX6E$-$opDP{+11Xs8lIL~veFhR74?PuXbk8s=uYg-w~~rHS@|H% zrWYQAhvh|p>QcI5v4h}QRqryx^|n)C#@|Flr;jE@+nrZn|B8}^6*~1lO1pC&Y}~raXWrjij*L&naO$|T zRL@)yC1>j?6PACp^HQxnwt8-71hG**xtC~!!#a?a2}2B54Z^ex!vZtConhWvn8sv; z7p6ph3eDlF0z{6S7fy^R^AXZY*hV80r7Pf)dq(4T5RG1mOx3*zl=g9v*+(O5N7S>Z ztiRU~p`d-$FBy;RqOOYl#k?2GS_EPJd7A6rkV)*tQoVga+aO9gKn(8?YQ8c3ieAE> zCHVKt{`=KKE1<-OBY`lHLQXGSbpj&ZepRgR57)04QBNCd2t9h`OY@8pgdIcMqUxP@ zbT&H0_+zx|JKvJ6eXNA}#)&R~kZ3=ll)?@O*Dause#vu$@tbCbsc$Y70uLF>5Z8)u z92;_JUa_lZ;g5Ts4bb;h|3I1Wtt)(Fx{Und2~05YI(1nieO(cGM|*|KYL5H{NGv*6 zh9tLyn7^qA9+c{135FCPM00lHRX-RcDsv*JFI~004o={2Rr9=+d94C!dsN&KHcopS ztH0jm^7iYF^YgHtEwk@hFqkm%DKabQE+X>fVhb3meEG z#6Q=D3}T1n{qFBU?46>#+&(~PIl!Z2>hl$-=A%(jiqO=;EW!tAyC~}ML(lb_qmuS5 zdkrpr@qAa5@F8$h=hm?V%`BLX>jU=E{=I>A*GD-aBj4p%l4BeIqg z$_62d8Yy71J;-{uGcOW4!Lr7{uZdu!B$9Omrh$VBFppBXVM0H-_3xC~BNat*qE=eDJRzhJRxay??~ zo5vEq)&A;oeL%Rv@AIo+_G%7}{P#~`@Gbn;kPKVa!Aw%a@ybLqtFK;hE)5d9?vSM! zt>Npy9LWv@MBnnE+3hs7mSi=q5(g(IryHx%QolcKQa>$lta(|_S99~%c~80T9oA#G zkvcr;?}J^!WnnBl_+HZ}^I`jInq6i}JC^GA)aScmZvXr`dD3klc3t$|FkWs?vhvUk zs|fR)tlay)eQHX??XA(Aox=cNTAEw|?i~D1+DMS!+BvnhFf=hXO-ogU3g&qjeoD`e z=nqlly&Maqc=~vXd^#IJ`x)8^?nfM)=}+mO-ntV2n_z|{4^EndBuLj7-eB!(fMEG0 zXEfX&?Fji%dcVD>l|&6@OaECP--uW9Mfet6eq|Gft20;tIfI63dR}j}xU6^J6?5GU z-5DNMA^Gu1k;)Mj=K$m8V_F-3_Rr9_*VCuBoT!DXT5*JerrQ z|Kq5tG#zH^ihzboB^jaB6>ZchR6&a@r7{kiNJQp)oU86*CjjDWHc1G_*v# zS-koa6()RUq5%esouaVF*4R<%uYq^fk_u&Lyr*x}GHv_&eH+WN<_PUmOmoy{@ydO?6#g?>srrHa|5n zFF!q{IFE^_9qS;;rFy38xG@!*%bw_cr?a7^DEEUx%hm84L54rA=h=u)3WO7dg~$2eaZF)?Pu%GrDo^#{gd(v2_#9|s&kwV ztGq%y+x8h+BK3(up0wU#Its6cqr5*|+ynAA@bD31=|w0^>5SbQ(G;0u@F+xyijBhN zoceKt^+w2;gStRgrtll`U&upq6+YcgIQVof=NSsZ=YB4gz+LJj$=}QqmEtTMy3CX0CoJCxse=ik`Jz1M^VeQm;libT6_s8818v#__1|xy6#2H)~ zrd-v%?`9a;E%;VD+er&c?OnD^ksSppA<~-Q5r;5i1k7Y}CKOfp6$N~z&W(TA0Bl65 zDcR~}C$Gr+<~_e4OLlN#f8_Mr(qe1j)H#`JTOV(EIo<#1g0mKxiASt%YdGU}5UAeH zTT`bcK=i=KQDKt(c#qtz44uSo1GecpD?@NrSVSW_!eHG?Jt57zc7GPE3_o zjK8%S#lJ{`7Xzv!74?p!%AMfAeRL0jgcEX+%P2aPB_z|A4ADZW*{p$=6YcC<0t&Ns zL0v{2#O`C9DmMU=MH%x${c6)s8uP*^<8W-D7RQe`$9?l7L+`I6&ct8Z#3@h( zRRpP1(6tW_4k*>w#?@xW)q2^Bs#!BlHm$w3*}}0U=}=z(;)t{6noIb zLl6|y1Tj=LWO99zLUDTcKS0Phkb1*usH>I--y%)86N`gMB^Qxxl4QYZuw$fM)Z~(b zn7)P)RbJ7E$UQduzPb6@&FrCU8w>vY46E?cxFc!p*H} zG4!n+v9q;C$&&KdU;%?=?hltV=JQ1DjR#wCqpIuHj|ZcVQjDq@Zc`rT^AAr@nATdg ze;jVi->U6w?Rszr2$zebsafEwy>LkS+QPq6@0}0^o{6JwnV>(0AS0SQiD_lKish=#j0W}4JS%O zIgtB>B)gEXK%|uX;YQKGc_J1Smhl(v``jjH*Km<@d=O40jpPW0#FL7|mFZ{hT*IS>avvsoi?LfeRj@EET|{04u$B!7r4I^5hf@)#2=^UR{T5PXCA zZlaV#zs@m7F21nG?GtYEUo>)U< zS?jJQa!$t|gcHEZ@dR(s&HEw&csljaewVPJqJgqABnfJjJ#~QwcZtL8{ZFWjeQ1js z6waNQKWq^^a~JW&Kp6c))Ss)enHf6P2Ihz)^vKQ~tyuaO(w9bttfMNGG18Foq^Ae! zz4S~)+?&8DZ{$>C)}j;?SwC8ZrzSa;E=+%`WT~;$Cemq$_5 z^vrXqys?8V5=3}ty7{xFkg`z+2@+J)caXG8ONjGP(^%~1S|Sy-?UX3er=Hqz}qBC@P^PLKL5I88oYQqv(w8ss|?vM>o z)2lZ*&ATMoSn=59x^@xsYTB&a^Wgm=jyjCcg;c4bV`41?<#h&@ruJXYC0FoiKrP$Zk*C{<+Y%YoBpW^<+mWnna74?8Jm+nU}Jef3@=e^5Y?iu=W4iU)*jtE5#l z>v|uYumjGVQ971iZdY&F&u-g2=dY(Vf3h)(Qxlk`P!6Jh-|4G3c`kAb{8Qw{mT~y$ z>-~EZZs{9UNGjqvPF`$#=G%ftZUy~+d*>Gw<>(kYc#%ST`+M_P##-zjllEOmhyyQw zCUoyl9IBejsf<}{4J0m4-^>N!?7Y=g$}Sp`(k|s-!TJIU(-6CT%go8PY61EB6FPxL zPbfr-`QliX$AFszB$fjPb}))c!0pT_vsW!DCs*LHuUM`Gi%svzu`pQ~$80qA@nQ<} zLBd8Q%gu1?^lLCii2KB#(Sg2EdZsE1TV0h|&%I8#kHWO_rickazA}Q_kfqFTUS>>LU#FO8(A!TNw4nv2yyH_2LSXNwv&R3uGpbrmMg(r`Cou^%;7Vo-bu zh3Vwr0)`V%7PG(FfftdfeQjt$<3Uqqs(KjmRF6XS0&;ypO7Z7!9MsgTld3zLXU9al zM6m=3i8wKtM6u}@xK`GB;9m4ytV$l?X}{Ph`rz^OX13PXrK7faT`Nu>o37j3GFZ(c z>~bshx(d_z-u(Wv3Qqpo&CBzGpJ#JA-t4Y+j=h1C342f{1BuSX_I~GPIFc&ExMb*u z^Q$_n$D>06do}5=DC5)9c4!M6EsKTNn9gM@Rk!yQ7IM6&OU@FQ3VB6_^y(pm;d#e* z;yUhD_$S|`UGuz+V0%v{)sr) zU#}}y=I=_P#x|1DPW~kTm}XzaXx#oH1^X2@lM#)KBfzwiP2fz=0Q_&_&K7x;$AtkE zZz-$Pwm*Z$;c9U0&)={)Qx4XllC6tbn;4z8q@TubeL@ie}8J8Cq7=ZEpqvj z1LbLB!!;Utq*Pz;Uu1yp?8KQ3w|f0UUPQFFqa-|)dRNTyW%WM70-ogsRVSDBa9&+$fUv?_dg5UqG6Id{PZktAAmx1x;08z|=o?S_#3Fk=#KBl+)o&vYk{;xJ zSBd!re25(%9lidhS$@9ZF&TNtke}H%z~s)3f>ybTf#=E`EYRDP z$@BR(4bXvd!f_{cRuW16{if=oSdg@8GZcO>pVt`a?)tQ)`sVTccNUOchd}#vdjC-h zaKsRatV5*j@wnG@qB(>Z2LT9cwf%Ap>T~3R&HphwGgV*H;9yr1H9k^&qRnzXI*Zj$ z?0DLa{=KbR05>d}7+}(8r$8YF*NZp~#}!mFo=;Acy_cR#e)7Iu?EIh;DXfxW6Oqnq zV6x{fm$`a;=QhgvF(b}(UO zbmkK*?;l)^es$mS$Zv>wJ=VU2qhtuZ%n9x z@zWd7?12wqbf)jt09wLMvX}#JT5%nY=WTmQ+l%$hM9a(GnLBaEQPY$4MuSTv4$$wm z-Iz@)9czMJbx;yq`t28QnUA&3C{zuC=lNu5&I-MyK_DpAL1mE1&!8Z=YYpLd-Fg_16M08_I;Mw1x1qTOe^O5 z^fqxU#MpdXem0-R3?0{8t(q)o0MlL6SlQ7nsL&jLNslTFN{B;#xOOC4+6`Vrj!H0| zm8Nu*yRW4#q~mKQ>6Jhd>#MZi+_PfG6Rsx{%F~lJwA-vUBxwI6o1&E_YE7nTrBAKEfWoZO2f!HS6qK+5b!-d!B7~s{$$x>_u%L%3fSK9$w!tQj zB|DeA%~SEwjLFojbv9kEBoF%quP05h;ku@npL>Um!_&3=XRWC*he|B>i>BQF^oKGf z2f>|xaUOpWw_lZADZ+}QSioc+E((UuXrc*f+HzlHkla=3fJnS{{DVI~nqmY&ECe;f zUx~3eD&Aq6?BOd;HW{of`MX8_VR*T?)!D2sC#`27b^k2{ZsxOP)n@UXpzP}$f)ByM z08%nHNn>e)o8MZrzA=VPO;lV$LCJ$2G=m_`^IfzVhUzz%Py6RB`7V1Zl4oE2V^Y3i zAYqx^%A|5ZKcYSBS77T}gUIwi>IWuex2mQanec{sy4ByQGsq%aAd!;ljACJHJ!u_1q#?=rsHr=ittIWd%VqL=Uuu$=XK&muanJN!~Q+? zg726;6ecG4DT`>-gq&~+>e^{Grj(c07br5|Q496T&4v2u2A4ngj=Q1n?XZxjB)O=_ zfX=aUU{&uW9CJDtxNotLa)EhK2Y5AaWKO-ewY>%pM1H_ei6r3-(m9mUJS0{tlOx+| zZY zn0OLkoNU|GB5!HO7FO{=kk%A-o*9+U;pDQ9w@zEsVI0f7`hWGQUQ&Ga>%aP(F2W44 z{37$d?8tYUGUq!TR*}~J_>-emd?L~s13@mi&{SPci*}#O((4p}^0k(ZN(vsCHYb~uv_Y0?8x&V1w1I~^ z)R>E>fq`4{1zU9|DOz(@liMcJH=m{UF$j8!eZ*+-P2?!F74-~776QH%Ov`6-u^dOs zH@h*O;w5@Rx=d{#8Ku}HwsqjxTwM%~>8KOVYjc3q*noA75_Mf6EppkBk%cKu@7Kx1 z_bq#;P2;Gk0{ndIHPlT8s%+R-eeBQ1hS^n#dHGznlg`FG=hr9G@i1_^8?M=yuAs)} z?d9IUzR@#HyZuW>9NoxtFE01ni~WQC+;v_8Uc0*k_Puci&~Q0bNVtULG&9pL^pp=@ z)V~Y&PmQhhax+mEHXCjh2p2-#4S%kO{@_rS^A;bhX7{>KFf}QW@o=i``~Il@^@WBE zE3%S8pW{hOk4x{X;dN_B`N!HF;p65#k&16nnz$Dnl<3UrO<1#o<35BQnyY`^D&gHW z(u}iH`JJOi99i{^C6Y~oxD@x$0H4(Dfmn$e8Az+PoR-|2sAk7>e-pDW2aygIP6l>Q z4GNgySL=UIzqO)=Y=<=r8(?Z1W9t@*l>zM|dcn6uwyZF=ti^)pf%zLUP>As5>|1R; zt>i3<1*X`gS#Z5i#B%8Do$!`$5g#PQ*i3qR$2#g4ZJlF~B@>e|8=tCh4+}~?MxMvJ-S=XYE$f;%kwY@Of&D zT6!av0IR{#d#`vnsiM`@>F_i+u7M=|`J}5jI4WwjwQg^x>NF@Ky;i&|UPM~`L+K5A z>e|J^2iECr#AZ#e(~Gm)g9 zrU^O=Qjt6OS$(Vgrm^NGd5jHlU_)cjct$a~7@y!ua!ZGif_6|5%2l7?=?xOsa|%f) z-RcZJKKov89#5t0-X+8HPm-x@(_S2&s; z{!mHczqTz(d!an!sy1n<#M#uGHYw{29&U*FFNyB?o-8MI;=Z*IE!$WDgEI6RPpE%~xmP$g3 zm)`s>H1+T2rw8KwZohB+Vg2sDdvHGsM&LIQ~Eia`ey82vWf?sBcRZwNv^Qn zz=FugB2~_U=wp=ljLeHjulH6=3QpS%ga?#a7#-m7WxED~x$#l#YjttA!SAecDl7%< zi}QQWpfd>U2~&6l%O!)NVZA_Fn0(^~0clk3@Fxzq7E7@{36lqH_c=2I0e&XxQZOxf zHfpm~*)vM+KFxk=qH{!y4?3pgjz&BLy%wBkmmcG#2vrM+yu&KOhxRa%_n!erU!n!& z1?D4G9KKY1t1S=a@g;X_Z~fvwO*yWXQ<8g4h!9FEQFa%SF+SjBvrj9w;GbLi9T2hm ztEXLcznn5;&ZBW|IbdZ~jYSu}{?s&G^(+^)as8$@|sU3*)-;h~1_v6NyIz*(NE>-@SGSCP3&fbZ^o)|H{@ zV!iHlZfj(;GZeMgP=*f@mmNI6j=)+H4Nw32>sQ)O3-h$!`8)Fq&2Z`;yh<~k(_6{t z0yB9&(K?lb!l!=^HR5EluU1SE;4EW;8&Dx8;|X8dzCAD zHet<_x3UG61zlmfpTE;pJ>#|(`E5+gULH}nvwb>tuyf~|xP21PZ>$&C`k|QRJ04mrS!}M{2kX4KOiC9%@-YvIbbgUzFNs69(5ySc z`3v0X7qsP@0JS>+r#FJeFATx&8Tv2JlWsSBC2|8BPyd1-rrGyJ1<%}nzvh2{dRAx{ znKvK4;wkSP^eFf~84Di>yxStddY&dRzmYWZg;9M>kZ)3xc0fi=a8qPtrf)kW7A4#& zw>WLwEBY9^o`~gA-JypDdv!{WI-_H`}5u4LRfsdZvXt-3>_D-4N@a8A^_+ zD-ORD9-F&hBf-ZbIR{Ww5 z?4-tm_@@DUlqDVVz9 z5<>z!Bin6fK`$V$-RJesf?h@W!70rzl<*o>g-^>+S{IM0Jajbp5k+K|;TqvQ0Tsg8 z#d!`$+)yYv{&_WXHxJ)LWCEHC$`k7ot5x6xi-#J`AGg;8zk9Jc?sZ=j{Ip|O^>I16 z8@1U#=d^i{U+6J$oQs4SazWRu|il-iy&+q2q zZfdF)1OnycV0XTGzV?OX{q}3QSy|f%kqF7+_whYDSt=Zf`=x)58EcbNDpJ;7UK(4S znTsAID`9|x6Nnzr)34H`0RbzaUktRmJk@P8tbssx4D88mTMKsm9@~Jnm&1OHP1xpm zxpfeIzmfiWI#;dDc>nt1IMYvceW&whsY#~ao6jWfLcTU1wNLsjdcYC}JKp&fyHJ_L zVG1}vUc_ZN%_n~Q(X*FYe8)n3=l&+u&cY%>^6b!DjuuK2E$Xko^(!~HX?wen^X)(N z`0GqDrQeT|4!XqIS91b3G0o|!Ri}X0-6rVOOMzI>m-_~tYq>NB8})3h+4uBnXD~XX z|Go9(?$^b27&?5o&zf|bZbaLfqc=b4iA`C3U8p%J3?iExmI8=`m0flAR-~8o z3YbcRZ3Eu&kEgbng=T7;`|I}v#jM$8x4AHUL4Lya+mqXZpN!G#c*`C><}-Ua1rm06 z%U+~~R3;-EYy&FSIU3^$XVGDE3Ev0sb6)03?2*XD;ET?MZluk~8>(46HA~jmI{5-i zXc1)TAt3)=9Wbqo3Wyu~FX50T`Dju_u9Y~FrQB)+r*k&?JcxKF;mF6Z%^X4`I4^f_ zZhm3c0ZSFL1PLY}e;^wnvi?Ygzmc(|!`F2qUZRuV)BXPJ6n~Ov!|&P=PD{e;@?y=-;j#$hHkI05me0Y@g8amjX`go~I>xa!~6#Mz||Md;ChT85-klp^s?Q=#3=TgWf5cm+A$9Z!-EMhdK#B zX7Rz#y|sf!O9oAaUz0w&6aQyb{tou9BE_HnIpC&wx8wca zlf>Ypi_h=v;xex_nt1*7bfTQ>C+hw_ru!4r(jwR660fPd$HEVZB$%HG!B7jLA*xVM zRA83E;i0`GCO7x2H8g2p7bWdcD#GhGCrjF-v#&O~fb@7(0vbsfDQau2x~)FOB3r>u z0XE0m{)+-CyGecm0T;iAgNy}y`FBH}aS&w>L&nHPWTI@K0EOCB+<=)DQZP8V?L@@F z`j?#ZANVyjEF8SCC0%ecn2x8G1XPIaPqP;NEaj=VoyWA(i?)ze9M+>$BFYjeNx1_r zN|zbh9m9;1LtUA}wlmRA%gLC<+wQf{u@`Y)fyY&6vs1vjvDWHzJ)XuHO}ycC^{{@t zAc8%SrCp`pkx^bAkkee96I@xY``Ny3Ds(k_v!|-6@W+p%s!ck#Skw)nG%<-UpWYws znl&X!lS*<-w>OE@6+7I$EOaGQJpoQJ!baama`&t%SN(jSZ&!GGdl&Q~b$kUpw}uaz zCCDV~+BKZEsW4zsQ>qoj_4$A}hwfmK_LU!-8jGBPaS`lauEI@4>2JQrU%7rKBRFdP zeL#}f2ii4N5FnN-Y#mO;fSoQ}c)W;?`@E|}?!mpgy5wXwnaX~Atm$Mr{%tJ9D0_HZ zN~-B*2i47P{bBC~b)!PNJ*U+uyV-OjL{*(3-Gi6!w>#t;Re zqC&fAUQt*$OllyO?Uz)k?yD$dWDQU?7s~wYR0p}CrkyA?FrLbKZ^fNY5HJGT;|(_X zJg%({nA1r?pWm)rP)(@uJq__v&=c_Cy?QtuDsRl={2ujkW%zJ(y%o<%T)ybnGc*tV zg_i)AeLyzk^4{?Fx!Xelab`Ws6XGvwz<(0le_!S{;=&P5WNkkyZ<~L$kVvx^T4FGz zj1`c+^4v~=*fBwgd#LoAeD!-jSAXAsfAPzH8T5NOKKAn)&t>&lYv(A_bUH1{A`)!! zyX*s%BmTL?HbZTg%UrB|9o~UOJ%4?+i{!kO&`W0c@gJr78>mnh!S1^)djM|>`7&! zrVcqhpRrNC;u$AVhLr>a=Sn~4YsiIN{F>P@Dt-gN^alfr`;|FKrsleD9(n;d2tNz+ zMO5Y~s+$zQ3LLjR$@Kk~tN))rO<;)tapEEu4~48tinuA$aRm7iZ_XCGs3fs_vfRsimBe zg*<`2N}jP!y1q`5AR#6n^L|8{}iR*H8AvJCkDnAb=QZwl+GP|}Qb zF~0tRdVJt@G(WN?H~0+kY{xyT?lkqD8I(%#6I}6BAA~n}r?nilu$oQq`P?0>m(%V? zpD(p#n;3}rn#ui1>aMshy5sk-KR&rUrF}Zu>Ge6adC<~PHKCdJm$RQ!4sT?lwnv+V zaaaBEkQDN?_wykb!RCR7MwHKU{-pAKr?e7ImI6$~((O=@G67js`61La-=ML9O#JhOJp1~ zT#&W$4gLS(|NiB!CPks=2;Azb%`}WCTQlXkY+YGVg$wnKxpGL?=R{G4@R9_uMbaX3 z$KuF_zQEzI1s+b#)l?BN za1Jes3<_pY2pTWUNu-v9{JgHBPCqnzS)kP*a#Y)x1+6M}(ESK�z1W9z4xc^ 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⁣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 z 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�L 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

  • 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

    qKCdnUqpVM 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 G)V~0CU~hc@ literal 0 HcmV?d00001 From f1462323fd75ebc7fe9325442e579bdfc5bce3fa Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Fri, 20 Jan 2023 12:07:18 +0000 Subject: [PATCH 025/111] feat: multilang support and enforcement delay --- lib/bot-core.ts | 24 +- lib/create-db.ts | 57 ++- lib/cron.ts | 451 +++++++++++++----- lib/db.ts | 76 ++- lib/telegram/assets/langNew.json | 384 +++++++++++++++ lib/telegram/commands/addEvidence.ts | 51 +- lib/telegram/commands/addEvidenceHelp.ts | 6 +- lib/telegram/commands/fedinfo.ts | 12 +- lib/telegram/commands/getAccount.ts | 2 +- lib/telegram/commands/getChannel.ts | 8 +- lib/telegram/commands/getReports.ts | 26 +- lib/telegram/commands/getRules.ts | 23 +- lib/telegram/commands/greeting.ts | 31 +- lib/telegram/commands/help.ts | 346 ++++---------- lib/telegram/commands/joinfed.ts | 10 +- lib/telegram/commands/leavefed.ts | 4 +- lib/telegram/commands/multilang.ts | 34 ++ lib/telegram/commands/newfed.ts | 14 +- lib/telegram/commands/report.ts | 104 ++-- lib/telegram/commands/setChannel.ts | 16 +- lib/telegram/commands/setChannelFed.ts | 18 +- lib/telegram/commands/setLanguage.ts | 60 +-- lib/telegram/commands/setRules.ts | 15 +- lib/telegram/commands/socialConsensus.ts | 14 +- lib/telegram/commands/start.ts | 76 +-- .../commands/toggleAdminReportable.ts | 3 +- lib/telegram/commands/toggleCaptcha.ts | 24 +- lib/telegram/commands/toggleEnforcement.ts | 32 ++ lib/telegram/commands/toggleWelcome.ts | 8 +- lib/telegram/commands/welcome.ts | 12 +- lib/telegram/index.ts | 84 ++-- types.d.ts | 4 +- 32 files changed, 1352 insertions(+), 677 deletions(-) create mode 100644 lib/telegram/assets/langNew.json create mode 100644 lib/telegram/commands/multilang.ts create mode 100644 lib/telegram/commands/toggleEnforcement.ts diff --git a/lib/bot-core.ts b/lib/bot-core.ts index f1ebf01..dfe01ad 100644 --- a/lib/bot-core.ts +++ b/lib/bot-core.ts @@ -15,23 +15,18 @@ interface RealityBanResult { questionUrl: string } -export const reportUser = async (batchedSend:any, lang: string, hasBanningPermission: boolean, fromUsername: string, UserID: string, platform: string, group: string, inviteURL: string, groupID: string, rules: string, message: string, messageBackup: string, reportedBy: string, isPrivate: boolean): Promise => { +export const reportUser = (batchedSend:any, lang: string, hasBanningPermission: boolean, fromUsername: string, UserID: string, platform: string, group: string, inviteURL: string, groupID: string, rules: string, message: string, messageBackup: string, reportedBy: string, isPrivate: boolean): RealityBanResult => { const minBond = utils.parseUnits('5', 12); // 5 DAI - var fromUsernameUrbit; - if(isPrivate){ - // private group - const hashedUserID = web3.utils.sha3(UserID+process.env.secret); - fromUsernameUrbit = ob.patp(hashedUserID.substring(0,8)) - } const delim = '\u241f'; - const question = isPrivate? fromUsernameUrbit+delim+rules+delim+messageBackup+delim+reportedBy : fromUsername+delim+UserID+delim+platform+delim+group+delim+inviteURL+delim+groupID+delim+rules+delim+message+delim+messageBackup+delim+reportedBy ; - const template_id = Number(isPrivate? process.env.TEMPLATE_ID_PRIVATE: process.env.TEMPLATE_ID) + const question = fromUsername+delim+UserID+delim+platform+delim+group+delim+inviteURL+delim+groupID+delim+rules+delim+message+delim+messageBackup+delim+reportedBy ; + const template_id = lang === 'es'? Number(process.env.TEMPLATE_ID_ES): Number(process.env.TEMPLATE_ID_EN) - const questionId = await askQuestionWithMinBond( + const questionId = askQuestionWithMinBond( batchedSend, question, template_id, - minBond + minBond, + lang ); return { @@ -41,12 +36,12 @@ export const reportUser = async (batchedSend:any, lang: string, hasBanningPermis } -async function askQuestionWithMinBond(batchedSend: any, question: string, template_id: number, minBond: number|BigNumber): Promise { +function askQuestionWithMinBond(batchedSend: any, question: string, template_id: number, minBond: number|BigNumber, lang: string): string { // A question is automatically created in Realitio with an answer in favor of banning the user. //const realityETHV30 = getRealityETHV30(process.env.REALITY_ETH_V30, process.env.PRIVATE_KEY); const openingTs = Math.floor(new Date().getTime()/1000); - const arbitrator = process.env.REALITIO_ARBITRATOR; + const arbitrator = lang === "es" ? process.env.REALITIO_ARBITRATOR_ES : process.env.REALITIO_ARBITRATOR_EN; const timeout = 86400; const reality = process.env.REALITY_ETH_V30; const txnBatchSender = process.env.TRANSACTION_BATCHER_CONTRACT_ADDRESS; @@ -65,7 +60,8 @@ async function askQuestionWithMinBond(batchedSend: any, question: string, templa { type: 'address', value: txnBatchSender }, { type: 'uint256', value: nonce }); - await batchedSend({ + + batchedSend({ args: [ template_id, question, diff --git a/lib/create-db.ts b/lib/create-db.ts index a9e4a08..6308612 100644 --- a/lib/create-db.ts +++ b/lib/create-db.ts @@ -12,26 +12,42 @@ const Database = require('better-sqlite3'); * `address` is the address of the bot assigned to this group. */ await db.exec( - `CREATE TABLE groups ( - platform TEXT, - group_id TEXT, - title TEXT, - channel_id TEXT, - thread_id_rules TEXT, - thread_id_notifications TEXT, - thread_id_welcome TEXT, - invite_url TEXT, - invite_url_channel TEXT, - federation_id TEXT, - federation_id_following TEXT, - greeting_mode BIT, - admins_reportable BIT, - captcha BIT, - privacy_mode BIT, - lang TEXT, - rules TEXT, - PRIMARY KEY (platform, group_id))` - ); + `CREATE TABLE groups ( + platform TEXT, + group_id TEXT, + title TEXT, + channel_id TEXT, + thread_id_rules TEXT, + thread_id_notifications TEXT, + thread_id_welcome TEXT, + invite_url TEXT, + invite_url_channel TEXT, + federation_id TEXT, + federation_id_following TEXT, + greeting_mode BIT, + admins_reportable BIT, + captcha BIT, + enforcement BIT, + lang TEXT, + rules TEXT, + PRIMARY KEY (platform, group_id))` + ); + + /** + * A group can be a telegram chat, a subreddit, etc. + * + * `platform` can be `telegram`, `reddit`, etc. + * `group_id` is the id of the telegram group or the name of the subreddit. + * `address` is the address of the bot assigned to this group. + */ + await db.exec( + `CREATE TABLE groupsMultiLang ( + platform TEXT, + group_id TEXT, + lang TEXT, + invite_url TEXT, + PRIMARY KEY (platform, group_id, lang))` + ); /** * `question_id` is the id of the question in reality.eth @@ -67,6 +83,7 @@ const Database = require('better-sqlite3'); group_id TEXT, rules TEXT, timestamp INTEGER, + msg_id TEXT, PRIMARY KEY (platform, group_id, timestamp))` ); diff --git a/lib/cron.ts b/lib/cron.ts index 0f14b81..a2a49e5 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -3,7 +3,7 @@ import {openDb, getGroupSettings, getRule, getCron, getFederationChannel, getInv import request from "graphql-request"; import {BigNumber} from "ethers"; import TelegramBot from "node-telegram-bot-api"; -import langJson from "./telegram/assets/lang.json"; +import langJson from "./telegram/assets/langNew.json"; import {Wallet} from "@ethersproject/wallet"; const {default: PQueue} = require('p-queue'); import {groupSettings, groupSettingsUnderspecified} from "../types"; @@ -19,6 +19,16 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo // Can put in DB or make template // - language (for new reports) // - rules (for new reports) +const exit = async () => { + await db.close() + await bot.stopPolling({ cancel: true }) +} + +['SIGINT', 'SIGTERM', 'SIGQUIT','EXIT'] + .forEach(signal => process.on(signal, async () => { + await exit() + process.exit(); + })); (async ()=> { const botaddress = (await new Wallet(process.env.PRIVATE_KEY)).address; @@ -27,9 +37,9 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo const privateKey = process.env.PRIVATE_KEY const account = web3.eth.accounts.privateKeyToAccount(privateKey) web3.eth.accounts.wallet.add(account) - const currentTime = Math.min(Math.floor(Date.now()/1000), history.last_timestamp + 5000) - const block = await web3.eth.getBlockNumber() - const currentBlock = Math.min(block+1000,block) + console.log(history) + const currentTime = Math.floor(Date.now()/1000) + let currentBlock = await web3.eth.getBlockNumber() if (!history) history = { last_timestamp: currentTime, @@ -39,12 +49,37 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo console.log(history.last_timestamp) console.log(history.last_block) // hardcode values for tests - //history.last_timestamp = 1671607558 - //history.last_block = 8173661 - const timestampNew = currentTime - const timestampLastUpdated = history.last_timestamp - const reports = {}; + //history.last_timestamp = 1673739955 + //history.last_block = 8312565 + let timestampNew; + let timestampLastUpdated = history.last_timestamp + let realitio_bot_checkpoint = Math.floor(timestampNew / 3600) + while (1){ + timestampNew = Math.floor(Date.now()/1000) + // don't run more than once per minute + if (timestampNew < timestampLastUpdated + 60){ + await delay(60000) + timestampNew = Math.floor(Date.now()/1000) + } + console.log(timestampNew < timestampLastUpdated + 60) + console.log('yoyoyoyo') + const questionDelay = await update(timestampNew, timestampLastUpdated, botaddress); + delayCheck(questionDelay, 0,timestampNew,timestampLastUpdated,botaddress) + // every hour + if (Math.floor(timestampNew / 3600) > realitio_bot_checkpoint){ + realitio_bot_checkpoint = Math.floor(timestampNew / 3600) + await realitio_bot(web3, currentBlock, process.env.REALITY_ETH_V30, process.env.REALITIO_ARBITRATOR); + currentBlock = await web3.eth.getBlockNumber() + } + timestampLastUpdated = timestampNew + setCron(db, currentBlock,timestampNew) + } +})() +const update = async (timestampNew: number, timestampLastUpdated: number,botaddress: string): Promise =>{ + + const reports = {}; + let delayQuestions = "" // dispute final // dispute appealsPossible // dispute disputesAppeal @@ -65,7 +100,7 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo process.env.MODERATE_SUBGRAPH, queryModeration ); - //console.log(JSON.stringify(moderationActions)) + console.log(JSON.stringify(moderationActions)) for (const data of moderationActions.disputesFinal) { const settings = validate(data.moderationInfo.UserHistory.group.groupID); @@ -74,11 +109,14 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo const msgLink = data.moderationInfo.message; const disputeURL = `https://resolve.kleros.io/cases/${BigNumber.from(data.id).toNumber()}`; // check rulings, note down shift since reality uses 0,1 for no, yes and kleros uses 1,2 for no, yes - const message = (data.finalRuling === 2)? 'broke the rules' : 'did not break the rules' + const message = settings.lang === "es" ? (data.finalRuling === 2)? 'infringió las normas' : 'no infringió las normas' : (data.finalRuling === 2)? 'broke the rules' : 'did not break the rules' //console.log(data.finalRuling) try{ - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `The [dispute](${disputeURL}) over *${data.moderationInfo.UserHistory.user.username}*'s [message](${msgLink}) ([backup](${data.moderationInfo.messageBackup})) resolved. *${data.moderationInfo.UserHistory.user.username}* ${message}`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); - //bot.sendMessage(process.env.JUSTICE_LEAGUE, `The [dispute](${disputeURL}) over *${data.moderationInfo.UserHistory.user.username}*'s [message](${msgLink}) ([backup](${data.moderationInfo.messageBackup})) resolved. *${data.moderationInfo.UserHistory.user.username}* ${message}`, {parse_mode: 'Markdown'}); + if (settings.lang === "en") + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `The [dispute](${disputeURL}) over *${data.moderationInfo.UserHistory.user.username}*'s [message](${msgLink}) ([backup](${data.moderationInfo.messageBackup})) resolved. *${data.moderationInfo.UserHistory.user.username}* ${message}`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + else + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `La [disputa](${disputeURL}) sobre el [mensaje](${msgLink}) ([backup](${data.moderationInfo.messageBackup})) de *${data.moderationInfo.UserHistory.user.username}* ha resuelto. *${data.moderationInfo.UserHistory.user.username}* ${message}`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + //bot.sendMessage(process.env.JUSTICE_LEAGUE, `The [dispute](${disputeURL}) over *${data.moderationInfo.UserHistory.user.username}*'s [message](${msgLink}) ([backup](${data.moderationInfo.messageBackup})) resolved. *${data.moderationInfo.UserHistory.user.username}* ${message}`, {parse_mode: 'Markdown'}); handleTelegramUpdate(db, bot,settings, data.moderationInfo,timestampNew, data.finalRuling === 2, true, true); } catch(e){ console.log(e) @@ -96,13 +134,26 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo const disputeURL = `https://resolve.kleros.io/cases/${BigNumber.from(data.id).toNumber()}`; // settings[1] language try{ - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `The dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - const chatname = (await queue.add(async () => {try{const val = await bot.getChat(data.moderationInfo.UserHistory.group.groupID) - return val}catch{}}))?.title - const invite_url = getInviteURL(db,'telegram',data.moderationInfo.UserHistory.group.groupID) - queue.add(async () => {try{await bot.sendMessage(process.env.JUSTICE_LEAGUE, `The dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) in the group [${chatname}](${invite_url}) has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - if(settings.federation_id) - queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `The dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) in the group [${chatname}](${invite_url})has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + const chatobj = (await queue.add(async () => {try{const val = await bot.getChat(data.moderationInfo.UserHistory.group.groupID) + return val}catch{}})) + const chatname = chatobj?.title + const isPrivate = !chatobj.active_usernames + const invite_url = isPrivate ? '' : getInviteURL(db,'telegram',data.moderationInfo.UserHistory.group.groupID) + if (settings.lang === "en"){ + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `The dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + const chatobj = (await queue.add(async () => {try{const val = await bot.getChat(data.moderationInfo.UserHistory.group.groupID) + return val}catch{}})) + if (settings.channelID !== process.env.SUSIE_SUPPORT_EN) + queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_EN, `The dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) in the group [${chatname}](${invite_url}) has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, {message_thread_id: process.env.JUSTICE_LEAGUE_EN, parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if(settings.federation_id) + queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `The dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) in the group [${chatname}](${invite_url})has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + } else { + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `La disputa sobre la [pregunta](${realityURL}) acerca de la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) ha concluido su ronda actual. La conducta de *${data.moderationInfo.UserHistory.user.username}* ${data.currentRuling == 2? 'infringió las normas': 'no infringió las normas'}. Si crees que la decisión es incorrecta, puedes solicitar una [apelación](${disputeURL})`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if (settings.channelID !== process.env.SUSIE_SUPPORT_ES) + queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_ES, `La disputa sobre la [pregunta](${realityURL}) acerca de la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) en el grupo [${chatname}](${invite_url}) ha concluido su ronda actual. La conducta de *${data.moderationInfo.UserHistory.user.username}* ${data.currentRuling == 2? 'infringió las normas': 'no infringió las normas'}. Si crees que la decisión es incorrecta, puedes solicitar una [apelación](${disputeURL})`, {message_thread_id: process.env.JUSTICE_LEAGUE_ES, parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if(settings.federation_id) + queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `La disputa sobre la [pregunta](${realityURL}) acerca de la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) en el grupo [${chatname}](${invite_url}) ha concluido su ronda actual. La conducta de *${data.moderationInfo.UserHistory.user.username}* ${data.currentRuling == 2? 'infringió las normas': 'no infringió las normas'}. Si crees que la decisión es incorrecta, puedes solicitar una [apelación](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + } } catch(e){ console.log(e) } @@ -114,13 +165,25 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; const disputeURL = `https://resolve.kleros.io/cases/${BigNumber.from(data.id).toNumber()}`; try{ - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `Arbitration is requested for the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})). Consequences of the report are lifted for the duration of the [dispute](${disputeURL}) (on Gnosis Chain).`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - const chatname = (await queue.add(async () => {try{const val = await bot.getChat(data.moderationInfo.UserHistory.group.groupID) - return val}catch{}}))?.title - const invite_url = getInviteURL(db,'telegram',data.moderationInfo.UserHistory.group.groupID) - queue.add(async () => {try{await bot.sendMessage(process.env.JUSTICE_LEAGUE, `[Arbitration](${disputeURL}) is requested for the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) in the group [${chatname}](${invite_url}).`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - if(settings.federation_id) - queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `[Arbitration](${disputeURL}) is requested for the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) in the group [${chatname}](${invite_url}).`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + const chatobj = (await queue.add(async () => {try{const val = await bot.getChat(data.moderationInfo.UserHistory.group.groupID) + return val}catch{}})) + const chatname = chatobj?.title + const isPrivate = !chatobj.active_usernames + const invite_url = isPrivate ? '' : getInviteURL(db,'telegram',data.moderationInfo.UserHistory.group.groupID) + const msg_penalty = settings.lang === 'en' ? settings.enforcement? `Consequences of the report are lifted for the duration of the [dispute](${disputeURL}) (on [Gnosis Chain](https://chainlist.org/chain/100)).` : `I recommend that any preliminary penalties due to the report be lifted for the duration of the [dispute](${disputeURL}) (on [Gnosis Chain](https://chainlist.org/chain/100)).` : settings.enforcement? `Las consecuencias de la denuncia se levantan mientras dure la [disputa](${disputeURL}) (en [Gnosis Chain](https://chainlist.org/chain/100)).` : `Recomiendo que se levanten las sanciones preliminares debidas al informe mientras dure la [disputa](${disputeURL}) (en [Gnosis Chain](https://chainlist.org/chain/100)).` + if (settings.lang === "en"){ + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `Arbitration is requested for the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})). ${msg_penalty}`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if (settings.channelID !== process.env.SUSIE_SUPPORT_EN) + queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_EN, `[Arbitration](${disputeURL}) is requested for the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) in the group [${chatname}](${invite_url}).`, {message_thread_id: process.env.JUSTICE_LEAGUE_EN, parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if(settings.federation_id) + queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `[Arbitration](${disputeURL}) is requested for the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) in the group [${chatname}](${invite_url}).`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + } else { + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `Se solicita arbitraje para la [pregunta](${realityURL}) sobre la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})). ${msg_penalty}`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if (settings.channelID !== process.env.SUSIE_SUPPORT_ES) + queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_ES, `Se solicita [arbitraje](${disputeURL}) para la [pregunta](${realityURL}) sobre la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup}) en el grupo [${chatname}](${invite_url}).`, {message_thread_id: process.env.JUSTICE_LEAGUE_EN, parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if(settings.federation_id) + queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `Se solicita [arbitraje](${disputeURL}) para la [pregunta](${realityURL}) sobre la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup}) en el grupo [${chatname}](${invite_url}).`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + } handleTelegramUpdate(db, bot,settings, data.moderationInfo,timestampNew, false, false, true); } catch (e){ console.log(e) @@ -134,13 +197,24 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo const disputeURL = `https://resolve.kleros.io/cases/${BigNumber.from(data.id).toNumber()}`; // settings[1] language try{ - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `An appeal has been funded in the dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})). Juror's voted in the previous round that *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. The contribution funded ${data.RulingFunded == data.currentRuling ? 'the previous round winning option': 'a different option that the previous round'}. If you think the funded option is incorrect, you can win some of their deposit by funding the correct side of the [appeal](${disputeURL})`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - const chatname = (await queue.add(async () => {try{const val = await bot.getChat(data.moderationInfo.UserHistory.group.groupID) - return val}catch{}}))?.title - const invite_url = getInviteURL(db,'telegram',data.moderationInfo.UserHistory.group.groupID) - queue.add(async () => {try{await bot.sendMessage(process.env.JUSTICE_LEAGUE, `An appeal has been funded in the dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) in the group ${chatname}[${invite_url}]. Juror's voted in the previous round that *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. The contribution funded ${data.RulingFunded == data.currentRuling ? 'the previous round winning option': 'a different option that the previous round'}. If you think the funded option is incorrect, you can win some of their deposit by funding the correct side of the [appeal](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - if(settings.federation_id) - queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `An appeal has been funded in the dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) in the group ${chatname}[${invite_url}]. Juror's voted in the previous round that *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. The contribution funded ${data.RulingFunded == data.currentRuling ? 'the previous round winning option': 'a different option that the previous round'}. If you think the funded option is incorrect, you can win some of their deposit by funding the correct side of the [appeal](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + const chatobj = (await queue.add(async () => {try{const val = await bot.getChat(data.moderationInfo.UserHistory.group.groupID) + return val}catch{}})) + const chatname = chatobj?.title + const isPrivate = !chatobj.active_usernames + const invite_url = isPrivate ? '' : getInviteURL(db,'telegram',data.moderationInfo.UserHistory.group.groupID) + if (settings.lang === "en"){ + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `An appeal has been funded in the dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})). Juror's voted in the previous round that *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. The contribution funded ${data.RulingFunded == data.currentRuling ? 'the previous round winning option': 'a different option that the previous round'}. If you think the funded option is incorrect, you can win some of their deposit by funding the correct side of the [appeal](${disputeURL})`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if (settings.channelID !== process.env.SUSIE_SUPPORT_EN) + queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_EN, `An appeal has been funded in the dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) in the group ${chatname}[${invite_url}]. Juror's voted in the previous round that *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. The contribution funded ${data.RulingFunded == data.currentRuling ? 'the previous round winning option': 'a different option that the previous round'}. If you think the funded option is incorrect, you can win some of their deposit by funding the correct side of the [appeal](${disputeURL})`, {message_thread_id: process.env.JUSTICE_LEAGUE_EN, parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if(settings.federation_id) + queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `An appeal has been funded in the dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) in the group ${chatname}[${invite_url}]. Juror's voted in the previous round that *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. The contribution funded ${data.RulingFunded == data.currentRuling ? 'the previous round winning option': 'a different option that the previous round'}. If you think the funded option is incorrect, you can win some of their deposit by funding the correct side of the [appeal](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + } else { + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `Se ha financiado una apelación en la disputa sobre la [pregunta](${realityURL}) acerca de la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${msgLink}) ([backup](${data.moderationInfo.msgBackup})). El jurado votó en la ronda anterior que la conducta de *${data.moderationInfo.UserHistory.user.username}* ${data.currentRuling == 2? 'infringió las normas': 'no infringió las normas'}. La contribución financió ${data.RulingFunded == data.currentRuling ? 'la opción ganadora de la ronda anterior': 'una opción diferente a la de la ronda anterior'}. Si crees que la opción financiada es incorrecta, puedes ganar parte de su depósito financiando la parte correcta del [apelación](${disputeURL})`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if (settings.channelID !== process.env.SUSIE_SUPPORT_ES) + queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_ES, `Se ha financiado una apelación en la disputa sobre la [pregunta](${realityURL}) acerca de la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) en el grupo ${chatname}[${invite_url}]. El jurado votó en la ronda anterior que la conducta de *${data.moderationInfo.UserHistory.user.username}* ${data.currentRuling == 2? 'infringió las normas': 'no infringió las normas'}. La contribución financió ${data.RulingFunded == data.currentRuling ? 'la opción ganadora de la ronda anterior': 'una opción diferente a la de la ronda anterior'}. Si crees que la opción financiada es incorrecta, puedes ganar parte de su depósito financiando la parte correcta del [apelación](${disputeURL})`, {message_thread_id: process.env.JUSTICE_LEAGUE_ES, parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if(settings.federation_id) + queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `Se ha financiado una apelación en la disputa sobre la [pregunta](${realityURL}) acerca de la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) en el grupo ${chatname}[${invite_url}]. El jurado votó en la ronda anterior que la conducta de *${data.moderationInfo.UserHistory.user.username}* ${data.currentRuling == 2? 'infringió las normas': 'no infringió las normas'}. La contribución financió ${data.RulingFunded == data.currentRuling ? 'la opción ganadora de la ronda anterior': 'una opción diferente a la de la ronda anterior'}. Si crees que la opción financiada es incorrecta, puedes ganar parte de su depósito financiando la parte correcta del [apelación](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + } } catch(e){ console.log(e) } @@ -157,47 +231,78 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo } */ - for(const data of moderationActions.realityQuestionAnsweredFinalized){ - const settings = validate(data.moderationInfo.UserHistory.group.groupID); - // settings[1] language - try{ - //bot.sendMessage(settings[0], `The reality question ${data.id} is finalized with ${data.currentAnswer}`); - const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; - - //bot.sendMessage(settings.channelID, `The [report](${realityURL}) is finalized.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); - //bot.sendMessage(process.env.JUSTICE_LEAGUE, `The [report](${realityURL}) is finalized.`, {parse_mode: 'Markdown'}); - // finalize - handleTelegramUpdate(db, bot, settings, data.moderationInfo, timestampNew, data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001", true, false); - } catch(e){ - console.log(e) - } +for(const data of moderationActions.realityQuestionAnsweredFinalized){ + const settings = validate(data.moderationInfo.UserHistory.group.groupID); + // settings[1] language + try{ + //bot.sendMessage(settings[0], `The reality question ${data.id} is finalized with ${data.currentAnswer}`); + //const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; + //bot.sendMessage(settings.channelID, `The [report](${realityURL}) is finalized.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); + //bot.sendMessage(process.env.JUSTICE_LEAGUE, `The [report](${realityURL}) is finalized.`, {parse_mode: 'Markdown'}); + // finalize + handleTelegramUpdate(db, bot, settings, data.moderationInfo, timestampNew, data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001", true, false); + } catch(e){ + console.log(e) } - - for(const data of moderationActions.realityQuestionAnsweredNotFinalized){ - //console.log(data.moderationInfo.UserHistory.group) - const settings = validate(data.moderationInfo.UserHistory.group.groupID); - // settings[1] language - try{ - const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; - const answer = data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001" ? "yes" : "no"; - //console.log('answeredbeg') - //console.log(data) - //console.log(data.moderationInfo.UserHistory) - //console.log('answered') - - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) violate the [rules](${data.moderationInfo.rules})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - const chatname = (await queue.add(async () => {try{const val = await bot.getChat(data.moderationInfo.UserHistory.group.groupID) - return val}catch{}}))?.title +} +for(const data of moderationActions.realityQuestionAnsweredNotFinalized){ + //console.log(data.moderationInfo.UserHistory.group) + const settings = validate(data.moderationInfo.UserHistory.group.groupID); + // settings[1] language + try{ + const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; + const answer = data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001" ? (settings.lang === 'en'? "yes": 'si') : "no"; + //console.log('answeredbeg') + if (settings.lang === 'en'){ + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) violate the [rules](${data.moderationInfo.rulesUrl})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + const chat = (await queue.add(async () => {try{const val = await bot.getChat(data.moderationInfo.UserHistory.group.groupID) + return val}catch{}})) + const chatname = chat?.title + const isPrivate = !chat.active_usernames const invite_url = getInviteURL(db,'telegram',data.moderationInfo.UserHistory.group.groupID) - queue.add(async () => {try{await bot.sendMessage(process.env.JUSTICE_LEAGUE, `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) in the group [${chatname}](${invite_url}) violate the [rules](${data.moderationInfo.rules})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - - if(settings.federation_id) - queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) in the group [${chatname}](${invite_url}) violate the [rules](${data.moderationInfo.rules})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - handleTelegramUpdate(db, bot,settings, data.moderationInfo,timestampNew, data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001", false, false); - } catch(e){ - console.log(e) + if (!isPrivate){ + if (settings.channelID !== process.env.SUSIE_SUPPORT_EN) + queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_EN, `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) in the group [${chatname}](${invite_url}) violate the [rules](${data.moderationInfo.rulesUrl})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if(settings.federation_id) + queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) in the group [${chatname}](${invite_url}) violate the [rules](${data.moderationInfo.rulesUrl})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + } + }else{ + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `La pregunta\n\n"¿Ha infringido el usuario *${data.moderationInfo.UserHistory.user.username}* las [reglas](${data.moderationInfo.rulesUrl}) mediante conductas relacionadas con el [mensaje](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup}))?\"\n\nse responde con un *${answer}*.\n\n¿Crees que esta respuesta es verdadera? Si no es así, puedes [corregir](${realityURL}) la respuesta.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + const chat = (await queue.add(async () => {try{const val = await bot.getChat(data.moderationInfo.UserHistory.group.groupID) + return val}catch{}})) + const chatname = chat?.title + const isPrivate = !chat.active_usernames + const invite_url = getInviteURL(db,'telegram',data.moderationInfo.UserHistory.group.groupID) + if (!isPrivate){ + if (settings.channelID !== process.env.SUSIE_SUPPORT_ES) + queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_ES, `La pregunta\n\n"¿Ha infringido el usuario *${data.moderationInfo.UserHistory.user.username}* en el grupo [${chatname}](${invite_url}) las [reglas](${data.moderationInfo.rulesUrl}) mediante conductas relacionadas con el [mensaje](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup}))?\"\n\nse responde con un *${answer}*.\n\n¿Crees que esta respuesta es verdadera? Si no es así, puedes [corregir](${realityURL}) la respuesta.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if(settings.federation_id) + queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) in the group [${chatname}](${invite_url}) violate the [rules](${data.moderationInfo.rulesUrl})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + } } + handleTelegramUpdate(db, bot, settings, data.moderationInfo, timestampNew, data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001", false, false); + if(settings.enforcement){ + delayQuestions += `\"${data.id},\"` + } + } catch(e){ + console.log(e) } +} + +for(const data of moderationActions.realityQuestionAnsweredFinalized){ + const settings = validate(data.moderationInfo.UserHistory.group.groupID); + // settings[1] language + try{ + //bot.sendMessage(settings[0], `The reality question ${data.id} is finalized with ${data.currentAnswer}`); + //const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; + //bot.sendMessage(settings.channelID, `The [report](${realityURL}) is finalized.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); + //bot.sendMessage(process.env.JUSTICE_LEAGUE, `The [report](${realityURL}) is finalized.`, {parse_mode: 'Markdown'}); + // finalize + handleTelegramUpdate(db, bot, settings, data.moderationInfo, timestampNew, data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001", true, false); + } catch(e){ + console.log(e) + } +} // promise queue example @@ -210,7 +315,7 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo if(!sherrif) continue //console.log(sherrif) - queue.add(async () => {try{await bot.sendMessage(data.group.groupID, `There's a new sheriff in town 👑🥇🤠[${sherrif.user.username}](tg://user?id=${sherrif.user.id})🤠🥇👑`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(data.group.groupID, `${langJson[settings.lang].reputation.sheriff} 🥇🤠[${sherrif.user.username}](tg://user?id=${sherrif.user.id})🤠🥇`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); } catch(e){ console.log(e) } @@ -224,7 +329,7 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo return val}catch{}}) if(!deputysherrif) continue - queue.add(async () => {try{await bot.sendMessage(data.group.groupID, `There's a new deputy sheriff in town 🥈[${deputysherrif.user.username}](tg://user?id=${deputysherrif.user.id})🥈`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(data.group.groupID, `${langJson[settings.lang].reputation.deputy} 🥈[${deputysherrif.user.username}](tg://user?id=${deputysherrif.user.id})🥈`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); } catch(e){ console.log(e) } @@ -240,26 +345,56 @@ const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCo continue let message = "" if (data.status === "GoodSamaritan"){ - message = "🎖 ***Good Samaritan Award***🎖\n\nThe Good Samaritan award is this group's highest honor, given to members who performed exemplary deeds of service for their group or their fellow members. Thank you for your service 🙏" + message = langJson[settings.lang].reputation.samaritan } else if (data.status === "NeighborhoodWatch"){ - message = "🤝 ***Neighborhood Watch Recognition*** 🤝\n\n The Neighborhood Watch recognition is given to members who help protect their community. Thank you for your service 🙏" + message = langJson[settings.lang].reputation.NeighborhoodWatch } else if (data.status === "BoyWhoCriedWolf"){ - message = "Have you ever heard of the fable of 💩 the boy who cried wolf 💩?\n\nBe careful, too many unanswered reports could hurt your reputation, " + message = langJson[settings.lang].reputation.BoyWhoCriedWolf } - console.log(data) if(data.status !== "CommunityMember") queue.add(async () => {try{await bot.sendMessage(data.group.groupID, `${message} [${userUpdate.user.username}](tg://user?id=${userUpdate.user.id})`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); } catch(e){ console.log(e) } } - await queue.onIdle() - await realitio_bot(web3, history.last_block, process.env.REALITY_ETH_V30, process.env.REALITIO_ARBITRATOR); - setCron(db, currentBlock,currentTime) - return; -})() + return delayQuestions.substring(0,delayQuestions.length-1); +} + +const delay = (delayInms) => { + return new Promise(resolve => setTimeout(resolve, delayInms)); + } + +const delayCheck = async (realityQuestions: string, lastPageUpdated: number, timestampNew: number, timestampLastUpdated: number, botaddress: string) => { + const queryModeration = getQueryDelay(lastPageUpdated, realityQuestions, timestampLastUpdated, botaddress, timestampNew) + // 5 min delay + await delay(60000) + //console.log(queryModeration); + //console.log('graphtime'); + //console.log(queryModeration) + const moderationActionsDelay = await request( + process.env.MODERATE_SUBGRAPH, + queryModeration + ); + + for(const data of moderationActionsDelay.realityQuestionAnsweredNotFinalizedDelayed){ + //console.log(data.moderationInfo.UserHistory.group) + const settings = validate(data.moderationInfo.UserHistory.group.groupID); + // settings[1] language + try{ + //const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; + //const answer = data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001" ? (settings.lang === 'en'? "yes": 'si') : "no"; + //console.log('answeredbeg') + //console.log(data) + //console.log(data.moderationInfo.UserHistory) + //console.log('answered') + } catch(e){ + console.log(e) + } + handleTelegramUpdate(db, bot,settings, data.moderationInfo,timestampNew, data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001", false, false); + } +} const validate = (chatId: string): groupSettings=> { const defaultSettings: groupSettings = { @@ -269,7 +404,7 @@ const validate = (chatId: string): groupSettings=> { greeting_mode: false, captcha: false, admin_reportable: false, - privacy_mode: true, + enforcement: false, thread_id_rules: '', thread_id_welcome: '', thread_id_notifications: '', @@ -277,7 +412,7 @@ const validate = (chatId: string): groupSettings=> { federation_id_following: '' } var groupSettings : groupSettingsUnderspecified = getGroupSettings(db, 'telegram', chatId) - groupSettings.rules = getRule(db, 'telegram', chatId, Math.floor(Date.now()/1000)) + groupSettings.rules = getRule(db, 'telegram', chatId, Math.floor(Date.now()/1000))?.rules const fullSettings = { lang: groupSettings?.lang ?? defaultSettings.lang, @@ -286,7 +421,7 @@ const validate = (chatId: string): groupSettings=> { greeting_mode: groupSettings?.greeting_mode ?? defaultSettings.greeting_mode, admin_reportable: groupSettings?.admin_reportable ?? defaultSettings.admin_reportable, captcha: groupSettings?.captcha ?? defaultSettings.captcha, - privacy_mode: groupSettings?.privacy_mode ?? defaultSettings.privacy_mode, + enforcement: groupSettings?.enforcement ?? defaultSettings.enforcement, thread_id_rules: groupSettings?.thread_id_rules ?? defaultSettings.thread_id_rules, thread_id_welcome: groupSettings?.thread_id_welcome ?? defaultSettings.thread_id_rules, thread_id_notifications: groupSettings?.thread_id_notifications ?? defaultSettings.thread_id_notifications, @@ -298,20 +433,36 @@ const validate = (chatId: string): groupSettings=> { const calcPenalty = (ban_level: number, timestamp_finalized: number): number => { if(ban_level == 1) - return timestamp_finalized + 120 + return timestamp_finalized + 86400 else if (ban_level == 2) return timestamp_finalized + 604800 + else if (ban_level == 3) + return timestamp_finalized + 2678400 else return timestamp_finalized + 31536000 } -const calcPenaltyPhrase = (ban_level: number): string => { - if(ban_level == 1) - return 'first time and is subject to a 1 day' +const calcPenaltyPhrase = (settings: groupSettings, ban_level: number, enforcement: boolean, finalize: boolean): string => { + + if (settings.lang === 'es'){ + if(ban_level == 1) + return finalize? enforcement? 'primera vez y está sujeta a un baneo de 1 día' : 'primera vez y se recomienda una prohibición de 1 día' : 'primera vez y se le recomienda un silencio de 1 día por el resto del período del informe' else if (ban_level == 2) - return 'second time and is subject to a 1 week' + return finalize? enforcement? 'segunda vez y está sujeto a una prohibición de 1 semana' : 'segunda vez y se recomienda una prohibición de 1 semana': 'segunda vez y se le recomienda un silencio de 1 día para el resto del periodo del informe' + else if (ban_level == 3) + return finalize? enforcement? 'tercera vez y está sujeto a una prohibición de 1 mes' : 'tercera vez y se recomienda una prohibición de 1 mes' : 'tercera vez y se le recomienda un silencio de 1 día por el resto del período del informe' else - return 'atleast three times and is subject to a 1 year' + return finalize? enforcement? 'al menos cuatro veces y está sujeto a una prohibición de 1 año' : 'al menos cuatro veces y se le recomienda una prohibición de 1 mes' : 'al menos cuatro veces y se le recomienda un silencio de 1 día para el resto del período del informe.' + } else { + if(ban_level == 1) + return finalize? enforcement? 'first time and is subject to a 1 day ban' : 'first time and is recommended a 1 day ban' : 'first time and is recommended a 1 day mute for the remainder of the report period' + else if (ban_level == 2) + return finalize? enforcement? 'second time and is subject to a 1 week ban' : 'second time and is recommended a 1 week ban': 'second time and is recommended a 1 day mute for the remainder of the report period' + else if (ban_level == 3) + return finalize? enforcement? 'third time and is subject to a 1 month ban' : 'third time and is recommended a 1 month ban' : 'third time and is recommended a 1 day mute for the remainder of the report period' + else + return finalize? enforcement? 'atleast four times and is subject to a 1 year ban' : 'atleast four times and is recommended a 1 year ban' : 'four times and is recommended a 1 day mute for the remainder of the report period' + } } const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, moderationInfo: any, timestampNew: number, restrict: boolean, finalize: boolean, disputed: boolean) => { @@ -340,67 +491,89 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, } const ban_level_current = calculateHistory.length + console.log(calculateHistory) + const groups = settings.federation_id? getGroupsInAndFollowingFederation(db,'telegram',settings.federation_id) : [moderationInfo.UserHistory.group.groupID] if (restrict){ // TODO federation subscriptions - const groups = settings.federation_id? getGroupsInAndFollowingFederation(db,'telegram',settings.federation_id) : [moderationInfo.UserHistory.group.groupID] if (ban_level_current > ban_level_history){ const parole = calcPenalty(ban_level_current,timestampNew) - if(finalize){ - // if message reported timestamp is before the most recent finalized ban / penality, users deserve a second chance, no action taken - // philosophy is only escalate the penalties after the user is warned with a temporary ban. - // this report changed penalties, recalculate all - //console.log(moderationInfo.UserHistory.group.groupID) - for (const group of groups){ - queue.add(async () => {try{await bot.banChatMember(group.group_id, moderationInfo.UserHistory.user.userID, {until_date: parole})}catch{}}); - } - } else if(!finalize){ - const options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false, until_date: parole}; - for (const group of groups){ - queue.add(async () => {try{await bot.restrictChatMember(group.group_id, moderationInfo.UserHistory.user.userID, options)}catch{}}); + if (settings.enforcement){ + if(finalize){ + // if message reported timestamp is before the most recent finalized ban / penality, users deserve a second chance, no action taken + // philosophy is only escalate the penalties after the user is warned with a temporary ban. + // this report changed penalties, recalculate all + //console.log(moderationInfo.UserHistory.group.groupID) + for (const group of groups){ + queue.add(async () => {try{await bot.banChatMember(group.group_id, moderationInfo.UserHistory.user.userID, {until_date: parole})}catch{}}); + } + } else if(!finalize){ + const options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false, until_date: parole}; + for (const group of groups){ + queue.add(async () => {try{await bot.restrictChatMember(group.group_id, moderationInfo.UserHistory.user.userID, options)}catch{}}); + } } } - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}) for the ${calcPenaltyPhrase(ban_level_current)} ban.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + const msg_enforcement = settings.lang === 'es'? `la conducta de *${moderationInfo.UserHistory.user.username}* por este [mensaje](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) mensaje viola las [reglas](${moderationInfo.rulesUrl}) por ${calcPenaltyPhrase(settings, ban_level_current, settings.enforcement, finalize)}.` : `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}) for the ${calcPenaltyPhrase(settings, ban_level_current, settings.enforcement, finalize)}.` + queue.add(async () => {try{await bot.sendMessage(settings.channelID, msg_enforcement, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); } else{ - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messsageBackup})) violated the [rules](${moderationInfo.rulesUrl}). The conduct occured before *${moderationInfo.UserHistory.user.username}*'s latest effective ban. The next time ${moderationInfo.UserHistory.user.username} breaks the rules, the consequences are more severe.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true})}catch{}}); + const i = calculateHistory.findIndex(e => e.question_id === moderationInfo.id); + if (i > -1) { + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messsageBackup})) violated the [rules](${moderationInfo.rulesUrl}) for the ${calcPenaltyPhrase(settings, ban_level_current, settings.enforcement, finalize)}.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true})}catch{}}); + } else + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messsageBackup})) violated the [rules](${moderationInfo.rulesUrl}). The conduct occured before *${moderationInfo.UserHistory.user.username}*'s latest confirmed report, so the user is recommended to get a second chance --- they should have been penalized already.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true})}catch{}}); } } else if (ban_level_current < ban_level_history){ let liftbans = true; + let timestamp_most_recent = 0 + for (const ban_level of calculateHistory) - if (ban_level.timestamp_active > 0) - liftbans = false + if (timestamp_most_recent< ban_level.timestamp_active) + timestamp_most_recent = ban_level. timestamp_active + + if (calcPenalty(calculateHistory.length, timestamp_most_recent) > timestampNew) + liftbans = false if(liftbans){ - const permissions = await queue.add(async () => {try{const val = await bot.getChat(moderationInfo.UserHistory.group.groupID).permissions - return val}catch{}}) - if(!permissions) - return - queue.add(async () => {try{await bot.restrictChatMember(moderationInfo.UserHistory.group.groupID, moderationInfo.UserHistory.user.userID, permissions)}catch{}}); - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}* has no other active reports. All bans are lifted.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); - } else - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}* has other active reports, and is still restricted.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + if (settings.enforcement) + for (const group of groups){ + if(group.group_id == moderationInfo.UserHistory.group.groupID){ + const permissions = await queue.add(async () => {try{const val = await bot.getChat(moderationInfo.UserHistory.group.groupID).permissions + return val}catch{}}) + if(!permissions) + return + queue.add(async () => {try{await bot.restrictChatMember(moderationInfo.UserHistory.group.groupID, moderationInfo.UserHistory.user.userID, permissions)}catch{}}); + } + } + const msg_update = settings.lang === "es" ? `*${moderationInfo.UserHistory.user.username}* has no other active reports. All bans should be lifted.` : `*${moderationInfo.UserHistory.user.username}* no tiene otros informes activos. Todas las prohibiciones deben ser levantadas.` + queue.add(async () => {try{await bot.sendMessage(settings.channelID, msg_update,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + } else { + const msg_update = settings.lang === "es" ? `*${moderationInfo.UserHistory.user.username}* has other active reports and should remain restricted.` : `*${moderationInfo.UserHistory.user.username}* tiene otros informes activos y debe permanecer restringido.` + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}* has other active reports and should remain restricted.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + } } } catch(e){ console.log(e) } } +const moderationInfoContent = ` id +message +messageBackup +moderationType +rulesUrl +UserHistory{ + countBrokeRulesArbitrated + group { + groupID + } + user { + username + userID + } +}`; + const getQuery = (lastPageUpdated: number, timestampLastUpdated: number, botaddress: string, timestampNew: number): string => { - const moderationInfoContent = ` id - message - messageBackup - moderationType - rulesUrl - UserHistory{ - countBrokeRulesArbitrated - group { - groupID - } - user { - username - userID - } - }`; const moderationInfo = `moderationInfo { ${moderationInfoContent} }`; @@ -440,7 +613,7 @@ return `{ timeServed ${moderationInfo} } - realityQuestionAnsweredNotFinalized: realityChecks(first: 1000, skip: ${lastPageUpdated*1000}, where: {deadline_gt: ${timestampNew}, dispute: null, timestampLastUpdated_gt: ${timestampLastUpdated}, moderationInfo_: {askedBy: "${botaddress}"}}) { + realityQuestionAnsweredNotFinalized: realityChecks(first: 1000, skip: ${lastPageUpdated*1000}, where: {deadline_gt: ${timestampNew}, dispute: null, timestampLastUpdated_gt: ${timestampLastUpdated}, timestampLastUpdated_lt: ${timestampNew}, moderationInfo_: {askedBy: "${botaddress}"}}) { id currentAnswer timestampLastUpdated @@ -479,4 +652,18 @@ return `{ } }`; } + +const getQueryDelay = (lastPageUpdated: number, questions: string, timestampLastUpdated: number, botaddress: string, timestampNew: number): string => { + const moderationInfo = `moderationInfo { + ${moderationInfoContent} + }`; +return `{ + realityQuestionAnsweredNotFinalizedDelayed: realityChecks(first: 1000, skip: ${lastPageUpdated*1000}, where: {id_in:[${questions}], deadline_gt: ${timestampNew}, dispute: null, timestampLastUpdated_gt: ${timestampLastUpdated}, timestampLastUpdated_lt: ${timestampNew},moderationInfo_: {askedBy: "${botaddress}"}}) { + id + currentAnswer + timestampLastUpdated + ${moderationInfo} + } + }`; +} export {calcPenalty} \ No newline at end of file diff --git a/lib/db.ts b/lib/db.ts index 825b542..f95f706 100644 --- a/lib/db.ts +++ b/lib/db.ts @@ -91,6 +91,19 @@ const setInviteURL = (db: any, platform: string, groupId: string, inviteUrl: str } } +const setMultilangGroup = (db: any, platform: string, groupId: string, inviteUrl: string, lang: string) => { + try{ + const stmt = db.prepare( + `INSERT INTO groupsMultiLang (platform, group_id, invite_url, lang) + VALUES (?, ?, ?, ?) + ON CONFLICT (platform, group_id, lang) DO UPDATE SET + invite_url = ?;`); + const info = stmt.run(platform, groupId, inviteUrl, lang, inviteUrl); + } catch(err) { + console.log("db error: setMultilangGroup, "+err); + } +} + const setInviteURLChannel = (db: any, platform: string, groupId: string, inviteUrlChannel: string) => { try{ const stmt = db.prepare( @@ -205,7 +218,6 @@ const setGreetingMode = (db: any, platform: string, groupId: string, greeting_mo console.log("db error: set setGreetingMode "+err); } } - const setCaptchaMode = (db: any, platform: string, groupId: string, captcha_mode: number) => { try{ const stmt = db.prepare( @@ -219,6 +231,19 @@ const setCaptchaMode = (db: any, platform: string, groupId: string, captcha_mode } } +const setEnforcementMode = (db: any, platform: string, groupId: string, enforcement_mode: number) => { + try{ + const stmt = db.prepare( + `INSERT INTO groups (platform, group_id, enforcement) + VALUES (?, ?, ?) + ON CONFLICT (platform, group_id) DO UPDATE SET + enforcement = ?;`); + const info = stmt.run(platform, groupId, enforcement_mode, enforcement_mode); + } catch(err) { + console.log("db error: setCaptchaMode "+ err); + } +} + const setAdminReportableMode = (db: any, platform: string, groupId: string, admin_reportable_mode: number) => { try{ const stmt = db.prepare( @@ -318,6 +343,15 @@ const getInviteURL = (db: any, platform: string, groupId: string) => { } } +const getMultilangGroup = (db: any, platform: string, groupId: string, lang: string) => { + try{ + const stmt = db.prepare('SELECT invite_url FROM groupsMultiLang WHERE platform = ? AND group_id = ? AND lang = ?'); + return stmt.get(platform, groupId, lang)?.invite_url || ''; + } catch(err) { + console.log("db error: getMultilangGroup, "+err); + } +} + const getInviteURLChannel = (db: any, platform: string, groupId: string) => { try{ const stmt = db.prepare('SELECT invite_url_channel FROM groups WHERE platform = ? AND group_id = ?'); @@ -391,7 +425,7 @@ const getGroupSettings = (db: any, platform: string, groupId: string): groupSett greeting_mode: result?.greeting_mode, captcha: result?.captcha, admin_reportable: result?.admins_reportable, - privacy_mode: result?.privacy_mode, + enforcement: result?.enforcement, federation_id: result?.federation_id, federation_id_following: result?.federation_id_following, } @@ -568,8 +602,11 @@ const getLocalBanHistory = (db: any, platform: string, userId: string, group_id: const banLevel2 = getLocalBanHistoryInduction(db,platform,userId,group_id,banLevel1.timestamp, finalized) if(!banLevel2) return [base, banLevel1] + const banLevel3 = getLocalBanHistoryInduction(db,platform,userId,group_id,banLevel2.timestamp, finalized) + if(!banLevel3) + return [base, banLevel1, banLevel2] - return [base, banLevel1, banLevel2] + return [base, banLevel1, banLevel2, banLevel3] } const getLocalBanHistoryBase = (db: any, platform: string, userId: string, group_id: string, finalized: boolean) => { @@ -613,8 +650,11 @@ const getFederatedBanHistory = (db: any, platform: string, userId: string, feder const banLevel2 = getFederatedBanHistoryInduction(db,platform,userId,federation_id,banLevel1.timestamp, finalized) if(!banLevel2) return [base, banLevel1] - + const banLevel3 = getFederatedBanHistoryInduction(db,platform,userId,federation_id,banLevel2.timestamp, finalized) + if(!banLevel3) return [base, banLevel1, banLevel2] + + return [base, banLevel1, banLevel2, banLevel3] } const getFederatedBanHistoryBase = (db: any, platform: string, userId: string, federation_id: string, finalized: boolean) => { @@ -670,8 +710,10 @@ const getFederatedFollowingBanHistory = (db: any, platform: string, userId: stri const banLevel2 = getFederatedFollowingBanHistoryInduction(db,platform,userId,group_id,federation_id,banLevel1.timestamp, finalized) if(!banLevel2) return [base, banLevel1] - - return [base, banLevel1, banLevel2] + const banLevel3 = getFederatedFollowingBanHistoryInduction(db,platform,userId,group_id,federation_id,banLevel1.timestamp, finalized) + if(!banLevel3) + return [base, banLevel1, banLevel2] + return [base, banLevel1, banLevel2, banLevel3] } const getFederatedFollowingBanHistoryBase = (db: any, platform: string, userId: string, group_id: string, federation_id: string, finalized: boolean) => { @@ -836,14 +878,26 @@ const setRules = (db:any, platform: string, groupId: string, rules: string, time } } +const setRulesCustom = (db:any, platform: string, groupId: string, rules: string, timestamp: number, msg_id: string) => { + try{ + const stmt = db.prepare( + `INSERT INTO rules (platform, group_id, rules, timestamp, msg_id) + VALUES (?, ?, ?, ?, ?);`); + const info = stmt.run(platform, groupId, rules, timestamp, msg_id); + } catch(err) { + console.log("db error: setRulesCustom"); + console.log(err); + } +} + -const getRule = (db:any, platform: string, groupId: string, timestamp: number): string => { +const getRule = (db:any, platform: string, groupId: string, timestamp: number): any => { try{ - const stmt = db.prepare(`SELECT rules + const stmt = db.prepare(`SELECT * FROM rules WHERE platform = ? and group_id = ? and timestamp < ? ORDER BY timestamp DESC;`); - return stmt.get(platform, groupId,timestamp)?.rules; + return stmt.get(platform, groupId,timestamp); } catch(err){ console.log("db error: getRule " + err); } @@ -911,10 +965,14 @@ export { setInviteURLChannel, getThreadIDWelcome, getGroupSettings, + getMultilangGroup, + setMultilangGroup, setThreadIDWelcome, setAllowance, getAllowance, getTitle, + setRulesCustom, + setEnforcementMode, setReport, setFederation, getFederatedBanHistoryBase, diff --git a/lib/telegram/assets/langNew.json b/lib/telegram/assets/langNew.json new file mode 100644 index 0000000..3caba85 --- /dev/null +++ b/lib/telegram/assets/langNew.json @@ -0,0 +1,384 @@ +{ + "en":{ + "reputation": { + "sheriff": "There's a new sheriff in town", + "deputy": "There's a new deputy sheriff in town", + "samaritan": "🎖 ***Good Samaritan Award***🎖\n\nThe Good Samaritan award is this group's highest honor, given to members who performed exemplary deeds of service for their group or their fellow members. Thank you for your service 🙏", + "BoyWhoCriedWolf": "Have you ever heard of the fable of 💩 the boy who cried wolf 💩?\n\nBe careful, too many unanswered reports could hurt your reputation", + "NeighborhoodWatch": "🤝 ***Neighborhood Watch Recognition*** 🤝\n\n The Neighborhood Watch recognition is given to members who help protect their community. Thank you for your service 🙏" + }, + "notifications": { + "getfed": "The notifications for this group's federation are sent to this [channel]", + "notset": "Notifications channel for this group is not set. Ask an admin to `/setchannel`", + "get": "I send moderation notifications to this [channel]", + "set": "/setchannel must be followed by a channel id. If you need more help, ", + "invalid": "/setchannel must be followed by a valid channel.", + "invalid2": "is not a valid channel.", + "admin": "You are not an authorized admin of the channel.", + "invite": "I need permissions to invite users to the channel.", + "confirm1": "Moderation notifications will now be sent to this [channel]", + "confirm2": "This channel will now relay moderation notifications for" + }, + "fed": { + "specify" : "Please specify a federation eg. `/joinfed `.", + "nofed": "No federation set.", + "notfound": "Federation not found. Use /fedinfo in a group whose federation you want to join to find its ID.", + "joined": "Your group is now part of the federation", + "following": "Your group is now following the federation", + "leave": "Your group has left the federation.", + "create": "Create your federation", + "create2": "DM me for help with your federation : )", + "exists": "Your federation already exists:", + "name": "Please name your federation, `/newfed My New Federation`", + "created": "Your new federation is created.\n\nIt is highly recommended to create a notification channel for your federation with `/setfedchannel` so moderation can easily be monitored throughout the federation in one place.\n\nYou can add groups to your federation by sending `/joinfed", + "notfound2": "No federation found. Please first create a federation with `/newfed`", + "specify2": "/setchannelfed must be followed by a channel id. If you need more help", + "invalid": "/setchannelfed must be followed by a valid channel.", + "invalid2": "is not a valid channel.", + "auth": "You are not an authorized admin of the channel.", + "confirm1": "Moderation notifications for the federation will now be sent to this [channel]", + "confirm2": "This channel will now relay moderation notifications for the federation" + }, + "enforcement":{ + "off": "I now only recommend penalties (1 day, 1 week, 1 year).", + "on": "I now enforce penalties (1 day, 1 week, 1 year bans)." + }, + "captcha": { + "on": "Captcha is on.", + "off": "Captcha is off." + }, + "getAccount": "Bot address", + "info": { + "evidence": "Which user is the report about?", + "noevidence": "There are no reports to add evidence to in your group.", + "get": "Get Report Info", + "DM": "DM me for report info : )", + "report1": "broke the rules atleast", + "report2": "time(s), and is banned until", + "fed": "Federal reports for " + }, + "rules" : "User conduct is moderated according to these [rules]", + "rulesUpdated" : "Rules [updated]", + "lang" : { + "select" : "Select a supported language", + "confirm": "Idioma cambiado a español.", + "rules": "The Kleros Moderate Community Guidelines apply as the default [rules]", + "setrules": "You can set new rules with /setrules. Crafting precise rules is challenging, you can ask me for /help." + }, + "addevidence" : { + "allowance": "Daily evidence allowance exhausted.", + "ID": "Evidence ID unspecified.", + "submitted": "Evidence [submitted]", + "explain": "Evidence Submitted with explanation", + "error1": "must be followed by a", + "id": "Evidence Group ID", + "errorId": "The ID is not active or does not exist.", + "msg1": "Active IDs", + "msg2": "reported for message sent", + "Chat": "Chat", + "Author": "Author", + "Date": "Date", + "Message": "Message", + "location": "location", + "longitude": "longitude", + "latitude": "latitude", + "History": "History", + "Poll": "Poll", + "Question": "Question", + "Option": "Option", + "Evidence": "Evidence", + "MessageSent": "Message Sent", + "Desc1": "Check the bot account of the chat with /getaccount to make it matches the submission address of this automated piece of evidence, to ensure its authenticity.", + "Desc2": "The attached file is a backup record of a message sent in the chat," + }, + "multilang": { + "es": "Spanish group set", + "error": "/multilang must be followed by an invite URL" + }, + "greeting": { + "multilang": "Este grupo representa a la comunidad de lengua inglesa. La comunidad de lengua española se encuentra en este [grupo]", + "greeting0": "Hi 👋 Welcome", + "greeting1": "Welcome, this group is moderated with [Kleros Moderate](https://kleros.io/moderate/). Please make sure to follow the [community rules]", + "greeting2": "Users who break the rules can be reported by replying to a message with the command `/report`.", + "captcha": "I agree to follow the rules." + }, + "error": { + "admin": "Admin only.", + "adminbot": "I need admin rights.", + "topics": "I need permissions to manage topics.", + "reply": "Must be used in reply.", + "txn": "Does the bot address have enough funds to pay the transaction? An unexpected error has occurred", + "url": "Invalid URL" + }, + "report": { + "expired": "Live and let live. This message is more than one week old. Next time try to make the report sooner.", + "reported": "The message is already [reported]", + "anon": "User is anonymous. Ask admins to disable anonymouse admins to moderate admin behavior.", + "bot": "Bots can't be reported.", + "errorAdmin": "Admin reports are disabled. Admin reporting can be enabled with `/adminreportable`", + "norules": "No rules found for this message.", + "noallowance": "You have exhausted your daily report allowance." + }, + "getReports" :{ + "noReports": "No reports for user ", + "broke": "broke the rules.", + "nobreak": "did not break the rules.", + "reportFinal": "final", + "reportCurrent": "current", + "noActiveReports": "There are no active answered reports.", + "specificUser": "To find all reports for a specific user, reply to their message with `/info`.", + "reportMessage": "Active Answered Reports", + "reportMessage1": "reported for message sent", + "reportMessage2": "backup", + "reportMessage3": "Report", + "reportMessage4": "current answer", + "ReportsFor": "Local reports for" + }, + "socialConsensus" : { + "confirm": "confirm", + "reportConfirm": "Report confirmed.", + "consensus1": "Reports require atleast 3 confirmations.", + "consensus2": "Should", + "consensus3": "be reported for breaking the [rules]", + "consensus4": "due to conduct over this [message]", + "consensus5": "backup" + }, + "disputeFinal":{ + "msg": "The dispute over 's message (backup) resolved.", + "dispute": "dispute", + "message": "message", + "backup": "backup" + }, + "brokeRules": " broke the rules", + "notBrokeRules": " did not break the rules.", + "disputeAppealPossible":{ + "msg1": "The dispute over 's message (backup) has concluded it's current round.", + "dispute": "dispute", + "message": "message", + "backup": "backup", + "msg1Fed": "The dispute over 's message (backup) in the group has concluded it's current round.", + "disputeFed": "dispute", + "messageFed": "message", + "backupFed": "backup", + "msg2": "If you think the decision is incorrect, you can request an appeal", + "appeal": "appeal" + }, + "start": { + "start1": "Hi! My community moderation tools are at your service. [DM]", + "start2": " me to find out more about how to use me to my full potential : )\n\n - /setrules to change the default [rules]", + "start3": "\n - /report messages by reply.\n\nI inform the group about content moderation outcomes and deliver a reccomendation for the admin to take action. My recommended penalties (1 day, 1 week, 1 year) can automatically apply by turning on the /enforce setting.\n\n", + "private": "Hi! My name is Susie, nice to meet you : )\n\nI am a [Kleros Moderate](https://kleros.io/moderate) community manager at your service. Use /help to learn how to use me to my full potential.\n\nJoin @SusieSupport to get information on all the latest updates.", + "add": "Add me to your group!", + "already": "Already started." + }, + "welcome": { + "welcome": "Hi, I'm Susie, a [Kleros Moderate](https://kleros.io/moderate/) bot.\n\nI need permission from an admin to /start.\n\nHow do I help resolve content moderation questions?\n\n1. I ask \"Did a user break the rules?\" on the crowdsourcing platform [Reality.Eth](https://realityeth.github.io/).\n2. Anyone can answer by leaving a bond (xDai on Gnosis Chain).\n3. Anyone can dispute the answer and [Kleros](https://kleros.io/), the decentralized court, resolves the question.\n\nTo learn more, read my [documentation](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie), ask a question in @SusieSupport, or [DM](https://t.me/${process.env.BOT_USERNAME}?start=help) me for help : )" + }, + "defaultRules": "https://ipfs.kleros.io/ipfs/Qme3Qbj9rKUNHUe9vj9rqCLnTVUCWKy2YfveQF8HiuWQSu/Kleros%20Moderate%20Community%20Rules.pdf", + "index": { + "supergroup": "Hi! I'm Susie, a moderation and group management bot. I can only manage supergroups. To promote this group to a supergroup, make the group public or promote any member to a full admin and try to /start me again.", + "channel": "The channel id is ${myChatMember.chat.id}", + "topicMode": "Started topic mode", + "topicError": "Susie cannot manage groups in topic mode with out permission to manage topics. Please ask an admin to enable this permission to allow Susie to continue help moderating your community. Then try to /start." + }, + "help": { + "DM": "Get Help (DM)", + "DM2": "DM me for help : )", + "help": "*Help*\n\nHi! My name is Susie. I'm a [Kleros Moderate](https://kleros.io/moderate) bot, here to help you manage your groups!\n\nAs groups grow, so do their moderation problems. We're all busy people who don't have time to monitor groups 24/7. Users often complain about admin abuse and have no recourse. Who moderates the moderator? Presenting [Kleros Moderate](https://kleros.io/moderate), a crowd-sourced content moderation tool using [Reality.eth](https://reality.eth.limo/) and [Kleros](https://kleros.gitbook.io/docs/) on [Gnosis Chain](https://www.gnosis.io/).\n\nWhen users are reported, a question is created on Reality.Eth asking 'did the user break the rules?'. The question can be answered yes/no with a bond (5 DAI). When Susie is an admin, successful reports result in penalties, otherwise Susie recommends admins to take action but does not ban any users herself.\n\n- 1st Report: 1 day ban\n- 2nd Report: 1 week ban\n- 3rd Report: 1 year ban\n\nAnswers to reports can be disputed, creating a case in the Kleros court.\n\nHelpful commands:\n - /start: Starts me. You probably already used this.\n - /help: Sends this message to tell you more about myself.\n\nSelect a feature to learn more. My [documentation](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator) is also helpful, or ask a question in @SusieSupport." +, "back": "back", + "Greeting1": "👋 *Greeting* 👋\n\nWelcome your members with a greeting informing them of the group rules.\n\n*Admin commands:*\n- `/welcome` : Toggles on/off welcomes messages.\n- `/captcha` : Toggles on/off rules captcha.\n\nAfter 5 minutes, the previous welcome messages will get deleted\n\nCaptchas remain for up to 5 minutes. If a user forgets to respond within 5 minutes, they should rejoin the group to prompt a new captcha.", + "Language1": "🗣️ *Languages* 🗣️\n\nSusie's replies can be changed to one of the languages below.\n- EN (English)\n- ES (Español)\n\n*Admin commands*: \n- `/lang`: Set your preferred language.\n\nContent moderation requires a nuanced understanding of context and language. Setting a language not only changes Susie's responses, but also specifies language skilled jurors.\n\nPlease make sure to set the appropriate language for your community for effective moderation.", + "Topics1": "ℹ️ *Topics* ℹ️\n\nTopics allow large groups to focus discussion in dedicated **topic** chats. Susie supports topics. When changing a group to topic mode, you will need to /start Susie again.\n\n*Admin commands*:\n- `/start`: Start topic mode.", + "Evidence1": "🔍 *Evidence* 🔍\n\nTo prevent important messages from deletion, pre-emptively, messages can be saved as evidence.\n\nNote that Susie uses a proxy contract to efficiently batch reports. In case of dispute over authenticity, evidence submitted by the Kleros Moderate bot is time stamped in chat. Moreover, this timestamp should be consistent with any evidence submitted by the bot address through the transaction batching contract.\n\n*User commands*:\n- `/evidence` : Reply to a message to add it as evidence.\n- `/getaccount`: Gets bot and transaction batcher addresses.", + "Report1": "🚨 *Report* 🚨\n\nWhen users are reported, a question is created on Reality.Eth asking 'did the user break the rules?'. The question can be answered yes/no with a bond (5 DAI). Successful reports result in penalties,\n\n- 1st Report: 1 day ban\n- 2nd Report: 1 week ban\n- 3rd Report: 1 year ban\n\nWhen Susie is not an admin, she only reccomends the admins to take action.\n\nAnswers to reports can be disputed, creating a case in the Kleros court.\n\n*User commands*:\n- `/report` : Reply to a message to report it\n- `/info`: Returns active reports\n- `/info` : Returns active reports for user", + "Rules1": "📄 *Rules* 📄\n\nEvery groups starts with [default rules](https://ipfs.kleros.io/ipfs/QmYYcNfEYLtxPM8fof4wf9Tqj7gBGMDMmNnBqZKR1zSczX/Kleros%20Moderate%20Community%20Guidelines%20v1.pdf). Crafting precise policies can be challenging.\n\n***Rule Writing Tips***:\n\n- Start with a preamble defining the group culture.\n- Number each rule.\n- Be specific.\n\n***Bad Example***:\n\n- Users must not send immoral messages\n- Users must not send unethical messages\n\nThese rules are too abstract and do not describe the culture nor context of the group.\n\n***Good Example***:\n\nAs a vegan community, we adopt these rules with the goals of sharing lifestyle tips (recipes, sustainable clothing, etc) in an environment of mutual respect.\n\n1. Users must not encourage immoral behavior eg. encouraging meat consumption.\n2. Users must not engage in unethical behavior eg. stealing credit for vegan recipies.\n\nThese rules include a define the group culture in the preamble, are numbered, and are specific.\n\n*User commands*:\n- `/rules`: Returns current rules\n*Admin commands*:\n- `/setrules` : Sets the rules to the the url\n- `/setrules` : Sets the rules to a replied message", + "Court1": "`⚖️ *Court* ⚖️\n\nContent moderation questions are resolved by the [Kleros Court](https://kleros.gitbook.io/docs/) with a jury of moderators. If the jury made a mistake, the case can be appealed, drawing a larger pool of jurors and providing an opportunity to provide more context, analysis, and arguments.\n\nIf you would like a chance to serve as a jury member, get PNK ([Gnosis Chain](https://swapr.eth.link/#/swap?chainId=100) or [Mainnet](https://app.uniswap.org/#/swap?outputCurrency=0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d&inputCurrency=ETH)) and [stake](https://court.kleros.io/) in the Kleros court.\n\nTo discuss the merits of a dispute, see @klerosjuror.`", + "Lawyer1": "🧑‍⚖️ *Find a Lawyer* 🧑‍⚖️\n\nDisputes over reported behavior can be complicated and nuanced. Often, disputes resolve on the merits of the message and rules alone. In some cases, disputes are better resolved by presenting the court with analysis and arguments.\n\nIf you would like to offer your services as a lawyer or solicit services, please join this [group](https://t.me/+9fvGGkGfSZ1hZDBk).", + "Privacy1": "🕵️ *Privacy* 🕵️\n\nEffective moderation depends on access to the full context of a reported message. To provide context, users can request Susie to save messages to submit as evidence on their behalf. Susie manages moderation private and public groups differently,\n\n- In *private* groups, moderators depend on evidence submissions alone.\n- In *public* groups, Susie invites moderators to join the group and investigate message context.", + "Notifications1": "🔔 *Notifications* 🔔\n\nSusie sends notifications about moderation actions and report updates. These notifications are restricted to a separate chat in topic mode. In regular Telegram groups, notifications can be sent to a notification channel to avoid cluttering the main chat.\n\nHow to enable notification channels:\n\n1. Make a channel\n2. Add Susie\n3. Susie will send a channel ID\n4. Use that channel ID to set notifications with /setchannel in the original group\n\n*User commands*:\n- `/notifications`: Returns current notification channel\n*Admin commands*:\n- `/setchannel` : Sets the notification channel to the specified channel id\n- `/setfedchannel` : Sets the notification channel for your federation to the specified channel id", + "Federations1": "🌐 *Federations*\n\nModerating a single group is hard, but managing multiple is even harder? Do you have to ban spammers manually, in all your groups?\n\nNo more! With federations, Susie can enforce a ban on a user in all federate groups.\n\n*User commands*:\n- `/fedinfo`: Returns current federation\n*Admin commands*:\n- `/newfed`: Creates a federation\n- `/joinfed`: Joins the current group to a Federation", + "Gnosis1": "⛓️ *Gnosis Chain* ⛓️\n\nSusie uses [xDAI](https://docs.gnosischain.com/about/tokens/xdai), a stable coin, on [Gnosis Chain](https://www.gnosis.io/). Don't know what that means? It means Susie uses a cheap and fast public ledger to coordinate moderation fairly and transparently.\n\nDon't have any xDAI on Gnosis Chain? No problem, there's a (cheap, fast) [bridge](https://bridge.connext.network/?receivingChainId=100&receivingAssetId=0x0000000000000000000000000000000000000000) for that. \n\nWhat's crypto? I heard about that on the news, I don't want anything to do with crypto. No problem, you can ask for help from freelance moderators in @SusieSupport.\n\nDon't have any cryptocurrency? No problem, there's a convinient [fiat on-ramp](https://www.mtpelerin.com/buy-xdai) (credit card or bank transfer) to buy DAI on Gnosis Chain.\n\nNeed help adding the Gnosis Chain network to your wallet? Don't worry, there's a [guide](https://docs.gnosischain.com/tools/wallets/metamask#2-configure) for that.\n\nNeed more help? Don't worry, there's a @SusieSupport group for that", + "Greeting": "👋 Greeting", + "Language": "🗣️ Language", + "Topics": "ℹ️ Topics", + "Evidence": "🔍 Evidence", + "Report": "🚨 Report", + "Rules": "📄 Rules", + "Court": "⚖️ Court", + "Lawyer": "🧑‍⚖️ Lawyer", + "Privacy": "🕵️ Privacy", + "Notifications": "🔔 Notifications", + "Federations": "🌐 Federation", + "Gnosis": "⛓️ Gnosis" + } + }, + "es":{ + "reputation": { + "sheriff": "Hay un nuevo sheriff en la ciudad", + "deputy": "Hay un nuevo ayudante del sheriff en la ciudad", + "samaritan": "🎖 ***Premio al Buen Samaritano***🎖\n\nEl premio al Buen Samaritano es el máximo galardón de este grupo y se concede a los miembros que realizan actos ejemplares de servicio a su grupo o a sus compañeros. Gracias por su servicio 🙏", + "BoyWhoCriedWolf": "¿Has oído alguna vez la fábula del 💩 niño que gritó lobo 💩?\n\nTen cuidado, demasiadas denuncias sin respuesta podrían dañar tu reputación", + "NeighborhoodWatch": "🤝 ***Reconocimiento a la vigilancia vecinal*** 🤝\n\n El reconocimiento Neighborhood Watch se otorga a los miembros que ayudan a proteger su comunidad. Gracias por su servicio 🙏" + }, + "notifications": { + "getfed": "Las notificaciones para la federación de este grupo se envían a este [canal].", + "notset": "El canal de notificaciones para este grupo no está configurado. Pida a un administrador `/setchannel`.", + "get": "Envío notificaciones de moderación a este [canal]" + }, + "fed": { + "specify" : "Especifique una federación, por ejemplo `/joinfed `.", + "nofed": "No hay federación establecida.", + "notfound": "Federación no encontrada. Utilice /fedinfo en un grupo a cuya federación desee unirse para encontrar su ID.", + "joined": "Su grupo ya forma parte de la federación", + "following": "Su grupo sigue ahora a la federación", + "leave": "Su grupo ha abandonado la federación.", + "create": "Cree su federación", + "create2": "DM mí para obtener ayuda con su federación : )", + "exists": "Su federación ya existe:", + "name": "Nombre su federación, `/newfed Mi nueva federación`.", + "created": "Su nueva federación está creada.\n\nEs muy recomendable crear un canal de notificación para su federación con `/setfedchannel` para que la moderación pueda ser fácilmente supervisada en toda la federación en un solo lugar.\n\nPuede añadir grupos a su federación enviando `/joinfed" + }, + "getAccount": "Bot dirección", + "info": { + "evidence": "¿De qué usuario trata el informe?", + "noevidence": "No hay informes a los que añadir pruebas en tu grupo.", + "get": "Obtener información del informe", + "DM": "DM mí para información de informe : )", + "report1": "rompió las reglas al menos", + "report2": "vece(s) y está prohibido hasta que", + "fed": "Informes federales para " + }, + "captcha": { + "on": "Captcha está activado.", + "off": "Captcha está desactivado." + }, + "getReports" :{ + "noReports": "No hay informes para el usuario ", + "broke": "rompió las reglas.", + "nobreak": "no rompió las reglas.", + "reportFinal": "final", + "reportCurrent": "actual", + "noActiveReports": "No hay informes de respuesta activos.", + "specificUser": "Para encontrar todos los informes de un usuario concreto, responde a su mensaje con `/info`.", + "reportMessage": "Informes con respuesta activa", + "reportMessage1": "denunciado por mensaje enviado", + "reportMessage2": "backup", + "reportMessage3": "Informe", + "reportMessage4": "respuesta actual", + "ReportsFor": "Informes locales para" + }, + "rules" : "La conducta de los usuarios se modera de acuerdo con las siguientes [reglas]", + "rulesUpdated" : "Normas [actualizadas]", + "lang" : { + "select" : "Seleccione un idioma compatible", + "confirm": "Language changed to english.", + "rules": "Se aplican por defecto las Directrices de la Comunidad Moderada de Kleros [normas]", + "setrules": "Puedes establecer nuevas reglas con /setrules. Elaborar reglas precisas es un reto, puedes pedirme ayuda (/help)." + }, + "addevidence" : { + "allowance": "Se han agotado las pruebas diarias.", + "ID": "pruebas ID sin especificar.", + "submitted": "Pruebas [cargadas]", + "explain": "Pruebas presentadas con explicaciones", + "errorId": "El ID no está activo o no existe.", + "Chat": "Charla", + "Author": "Autor", + "Date": "Fecha", + "Message": "Mensaje", + "location": "ubicación", + "longitude": "longitud", + "latitude": "latitud", + "History": "Historia", + "Poll": "Encuesta", + "Question": "Pregunta", + "Option": "Opción", + "Evidence": "Pruebas", + "MessageSent": "Mensaje enviado", + "Desc1": "Comprueba que la cuenta bot del chat con /getaccount coincide con la dirección de envío de esta prueba automatizada, para asegurarte de su autenticidad.", + "Desc2": "El archivo adjunto es un registro de copia de seguridad de un mensaje enviado en el chat," + }, + "multilang": { + "en": "Grupo inglés conectado", + "error": "/multilang debe ir seguido de una URL de invitación" + }, + "greeting": { + "multilang": "This group represents the Spanish language community. The English language community can be found in this [group]", + "greeting0": "Hola 👋 Bienvenido", + "greeting1": "Este grupo está moderado por [Kleros Moderate](https://kleros.io/moderate/). Por favor, asegúrese de seguir las [reglas de la comunidad]", + "greeting2": "Los usuarios que incumplan las normas pueden ser denunciados respondiendo a un mensaje con el comando `/report`.", + "captcha": "Acepto seguir las normas." + }, + "error": { + "admin": "Sólo para administradores.", + "reply": "Debe utilizarse en la respuesta.", + "adminbot": "Necesito derechos de administrador para aplicar sanciones (1 día, 1 semana, 1 año).", + "topics": "Necesito permisos para gestionar temas.", + "txn": "¿La dirección del bot tiene fondos suficientes para pagar la transacción? Se ha producido un error inesperado", + "url": "URL inválido" + }, + "report": { + "expired": "Vive y deja vivir. Este mensaje es de hace más de una semana. La próxima vez intenta hacer el informe antes.", + "anon": "El usuario es anónimo. Pide a los administradores que deshabiliten los administradores anónimos para moderar el comportamiento de los administradores.", + "bot": "Los bots no pueden ser denunciados.", + "admin": "Los informes de administración están desactivados. Los informes de administración pueden activarse con `/adminreportable`.", + "reported": "El mensaje ya está [notificado]", + "norules": "No se han encontrado reglas para este mensaje.", + "noallowance": "Ha agotado su asignación diaria de informes." + }, + "socialConsensus" : { + "confirm": "confirmar", + "reportConfirm": "Usuario reportado", + "consensus2": "Ha infringido el usuario ", + "consensus3": "las [reglas]", + "consensus4": "mediante conductas relacionadas con el [mensaje]", + "consensus5": "backup" + }, + "index": { + "supergroup": "Hola, soy Susie, un bot de moderación y gestión de grupos. Sólo puedo gestionar supergrupos. Para promover este grupo a un supergrupo, haz público el grupo o promueve a cualquier miembro a administrador completo e intenta /start me de nuevo.", + "channel": "El ID del canal es ${myChatMember.chat.id}", + "topicMode": "Modo de tema iniciado", + "topicError": "Susie no puede gestionar grupos en modo tema si no tiene permiso para gestionar temas. Pide a un administrador que habilite este permiso para que Susie pueda seguir ayudando a moderar tu comunidad. A continuación, intente /start." + }, + "start": { + "start1": "Hola! Mis herramientas de moderación comunitaria están a tu servicio. Envíame un [DM]", + "start2": " para saber más sobre cómo aprovechar todo mi potencial. : )\n\n - /setrules para cambiar las [reglas]", + "start3": "\n - /report mensajes por respuesta.\n\nInformo al grupo sobre los resultados de la moderación de contenidos y entrego una reccomendación para que el admin tome medidas.\n\nPromoverme a un admin para aplicar las sanciones reccomendadas automáticamente. Mis sanciones recomendadas (1 día, 1 semana, 1 año) pueden aplicarse automáticamente activando la opción /enforce.", + "private": "Hola, me llamo Susie, encantada de conocerte : )\n\nSoy una [Kleros Moderate](https://kleros.io/moderate) community manager a tu servicio. Utiliza /help para aprender a utilizarme en todo mi potencial.\n\nÚnete a mi canal de noticias @KlerosModerateNews para informarte de todas las últimas actualizaciones.", + "add": "Añádeme a tu grupo!" + }, + "welcome": { + "welcome": "Hola, soy Susie, un bot [Kleros Moderate](https://kleros.io/moderate/). Necesito permiso de un administrador para /start. \n\n¿Cómo ayudo a resolver preguntas sobre moderación de contenidos?\n\n1.Pregunto \"¿Un usuario ha infringido las normas?\" en la plataforma de crowdsourcing [Reality.Eth](https://realityeth.github.io/).\n2. Cualquiera puede responder dejando un bono (xDai en Gnosis Chain).\n3. Cualquiera puede impugnar la respuesta y [Kleros](https://kleros.io/), el tribunal descentralizado, resuelve la pregunta.\n\nPara saber más, lee mi [documentación](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie), haz una pregunta en @SusieSupport, o [DM](https://t.me/${process.env.BOT_USERNAME}?start=help) para obtener ayuda." + }, + "defaultRules": "https://ipfs.kleros.io/ipfs/QmSHAjfD1MYPtyopFoXcUQ5Ny3sfs5re1yz3h3TZ5qGDsp/Kleros%20Moderate%20Normas%20comunitarias.pdf", + "help": { + "DM": "Obtener ayuda (DM)", + "DM2": "DM de ayuda : )", + "help": "*Ayuda*\n\nHi! Me llamo Susie. Soy un [Kleros Moderate](https://kleros.io/moderate) bot, aquí para ayudarles a gestionar sus grupos!\n\nA medida que los grupos crecen, también lo hacen sus problemas de moderación. Todos estamos muy ocupados y no tenemos tiempo para supervisar los grupos 24 horas al día, 7 días a la semana. Los usuarios suelen quejarse de los abusos de los administradores y no tienen ningún recurso. ¿Quién modera al moderador? Presentamos [Kleros Moderate](https://kleros.io/moderate), una herramienta de moderación de contenidos de origen colectivo que utiliza [Reality.eth](https://reality.eth.limo/) y [Kleros](https://kleros.gitbook.io/docs/) con [Gnosis Chain](https://www.gnosis.io/).\n\nCuando los usuarios son denunciados, se crea una pregunta en Reality.Eth preguntando \"¿el usuario rompió las reglas?\". La pregunta puede responderse sí/no con un bono (5 DAI). Cuando Susie es una admin, los reportes exitosos resultan en penalizaciones, de lo contrario Susie recomienda a los admins que tomen acción pero no banea a ningún usuario ella misma.\n\n- 1º Report: 1 día de prohibición\n- 2º Report: 1 semana de prohibición\n- 3º Report: 1 año de prohibición\n\nLas respuestas a los informes pueden impugnarse, creando un caso en el tribunal de Kleros.\n\nComandos útiles:\n - /start: Empieza yo. Probablemente ya usaste esto.\n - /help: Envía este mensaje para contarte más cosas sobre mí.\n\nSeleccione una función para obtener más información. Mi [documentación](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator) también es útil, o haz una pregunta en @SusieSupport." +, "back": "back", + "Greeting1": "👋 *Saludos* 👋\n\nDa la bienvenida a tus miembros con un saludo informándoles de las reglas del grupo.\n\n*Comandos de administrador:*\n- `/welcome` : Activa/desactiva los mensajes de bienvenida.\n- `/captcha` : Activa/desactiva el captcha de las reglas.\n\nDespués de 5 minutos, los mensajes de bienvenida anteriores se borrarán.\n\nLos captchas permanecen hasta 5 minutos. Si un usuario se olvida de responder en 5 minutos, debe volver a unirse al grupo para solicitar un nuevo captcha.", + "Language1": "🗣️ *Idiomas* 🗣️\n\nLas respuestas de Susie se pueden cambiar a uno de los siguientes idiomas.\n- EN (English)\n- ES (Español)\n\n*Comandos de administración*: \n- `/lang` : Establezca su idioma preferido.\n\nLa moderación de contenidos requiere una comprensión matizada del contexto y el lenguaje. Establecer un idioma no sólo cambia las respuestas de Susie, sino que también especifica el idioma de los jurados cualificados.\n\nPor favor, asegúrese de establecer el idioma apropiado para su comunidad para una moderación efectiva.", + "Topics1": "ℹ️ *Temas* ℹ️\n\nLos temas permiten a los grandes grupos centrar el debate en chats dedicados a **temas**. Susie es compatible con los temas. Cuando cambie un grupo a modo de tema, necesitará /iniciar Susie de nuevo.\n\n*Comandos de administrador*:\n- `/start`: Inicia el modo por temas.", + "Evidence1": "🔍 *Evidencia* 🔍\n\nPara evitar que se borren mensajes importantes, de forma preventiva, los mensajes pueden guardarse como pruebas.\nNNTen en cuenta que Susie utiliza un contrato proxy para procesar eficazmente los informes por lotes. En caso de disputa sobre la autenticidad, las pruebas presentadas por el bot Kleros Moderate llevan un sello de tiempo en el chat. Además, esta marca de tiempo debe ser coherente con cualquier evidencia presentada por la dirección bot a través del contrato de procesamiento por lotes de transacciones.\n\n*Comandos de usuario*:\n- `/evidence` : Responde a un mensaje para añadirlo como evidencia.\n- `/getaccount`: Obtiene direcciones de bots y batchers de transacciones.", + "Report1": "🚨 *Report* 🚨\n\nCuando los usuarios son denunciados, se crea una pregunta en Reality.Eth preguntando \"¿el usuario rompió las reglas?\". La pregunta puede responderse sí/no con un bono (5 DAI). Los reportes exitosos resultan en penalizaciones,\n\n- 1er Reporte: 1 día de suspensión- 2º Informe: 1 semana de prohibición: 1 año de baneo\n\nCuando Susie no es admin, solo recomienda a los admins que tomen medidas.\n\nLas respuestas a los reportes pueden ser disputadas, creando un caso en la corte de Kleros.\n\n*Comandos de usuario*:\n- `/report` : Responde a un mensaje para denunciarlo- `/info`: Devuelve los informes activos- `/info` : Devuelve los informes activos del usuario", + "Rules1": "📄 *Reglas* 📄\n\nTodos los grupos empiezan con [reglas por defecto](https://ipfs.kleros.io/ipfs/QmSHAjfD1MYPtyopFoXcUQ5Ny3sfs5re1yz3h3TZ5qGDsp/Kleros%20Moderate%20Normas%20comunitarias.pdf). Elaborar políticas precisas puede ser todo un reto.\n\n*Consejos para redactar reglas***:\n\n- Empieza con un preámbulo que defina la cultura del grupo.\n- Numera cada regla.\n- Sé específico.\n\n*Mal ejemplo***:\n\n- Los usuarios no deben enviar mensajes inmorales\n- Los usuarios no deben enviar mensajes poco éticos.\n\nEstas reglas son demasiado abstractas y no describen la cultura ni el contexto del grupo.\n\n*Buen ejemplo***:\n\nComo comunidad vegana, adoptamos estas reglas con el objetivo de compartir consejos de estilo de vida (recetas, ropa sostenible, etc.) en un entorno de respeto mutuo.\n\n1. Los usuarios no deben fomentar comportamientos inmorales, por ejemplo, fomentar el consumo de carne.\n2. Los usuarios no deben tener un comportamiento poco ético, por ejemplo, robar el crédito por recetas veganas.\n\nEstas reglas incluyen una definición de la cultura del grupo en el preámbulo, están numeradas y son específicas\n\ncomandos útiles:\n- `/rules`: Devuelve las reglas actuales.\n*Comandos de administrador*:\n- `/setrules` : Establece las reglas a la url\n- `/setrules` : Establece las reglas a un mensaje respondido.", + "Court1": "`⚖️ *Corte* ⚖️\n\nLas cuestiones de moderación de contenidos las resuelve el [Kleros Court](https://kleros.gitbook.io/docs/) con un jurado de moderadores. Si el jurado cometió un error, el caso puede ser apelado, atrayendo a un grupo más grande de miembros del jurado y proporcionando la oportunidad de proporcionar más contexto, análisis y argumentos.\n\nSi desea tener la oportunidad de servir como miembro del jurado, obtenga PNK ([Gnosis Chain](https://swapr.eth.link/#/swap?chainId=100) o [Mainnet](https://app.uniswap.org/#/swap?outputCurrency=0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d&inputCurrency=ETH)) y [stake](https://court.kleros.io/) en el tribunal de Kleros.\n\nPara discutir el fondo de una disputa, consulte @klerosjuror.`", + "Lawyer1": "🧑‍⚖️ *Buscar un Abogado* 🧑‍⚖️\n\nLas disputas sobre el comportamiento denunciado pueden ser complicadas y llenas de matices. A menudo, las disputas se resuelven únicamente sobre el fondo del mensaje y las normas. En algunos casos, las disputas se resuelven mejor presentando al tribunal análisis y argumentos.\n\nSi desea ofrecer sus servicios como abogado o solicitar servicios, únase a este [grupo](https://t.me/+9fvGGkGfSZ1hZDBk).", + "Privacy1": "🕵️ *Privacidad* 🕵️\n\nUna moderación eficaz depende del acceso al contexto completo de un mensaje denunciado. Para proporcionar el contexto, los usuarios pueden solicitar a Susie que guarde los mensajes para presentarlos como pruebas en su nombre. Susie gestiona la moderación de los grupos privados y públicos de forma diferente,\n\n- En los grupos *privados*, los moderadores dependen únicamente del envío de pruebas.\n- En los grupos *públicos*, Susie invita a los moderadores a unirse al grupo e investigar el contexto del mensaje.", + "Notifications1": "🔔 *Notificaciones* 🔔\n\nSusie envía notificaciones sobre acciones de moderación y actualizaciones de informes. Estas notificaciones están restringidas a un chat separado en modo tema. En grupos regulares de Telegram, las notificaciones pueden ser enviadas a un canal de notificación para evitar saturar el chat principal.\n\nCómo habilitar canales de notificación:\n\n1. Crea un canal\n2. Añade a Susie\n3. Susie enviará un ID de canal\n4. Utiliza ese ID de canal para establecer notificaciones con /setchannel en el grupo original\n\n*Comandos de usuario*:\n- `/notificaciones`: Devuelve el canal de notificaciones actual\n*Comandos de administrador*:\n- `/setchannel` : Establece el canal de notificaciones en el id de canal especificado\n- `/setfedchannel` : Establece el canal de notificaciones para su federación en el id de canal especificado", + "Federations1": "🌐 *Federaciones*\n\nModerar un solo grupo es difícil, ¿pero gestionar varios lo es aún más? ¿Tienes que bloquear manualmente a los spammers en todos tus grupos? Con las federaciones, Susie puede aplicar una prohibición a un usuario en todos los grupos federados.\n\n*Comandos de usuario*:\n- `/fedinfo`: Devuelve la federación actual: Crea una federación- `/joinfed`: Une el grupo actual a una federación", + "Gnosis1": "⛓️ *Gnosis Chain* ⛓️\n\nSusie usa [xDAI](https://docs.gnosischain.com/about/tokens/xdai), una moneda estable, en [Gnosis Chain](https://www.gnosis.io/). ¿No sabes lo que eso significa? Significa que Susie utiliza un libro de contabilidad público barato y rápido para coordinar la moderación de forma justa y transparente. \n\n¿No tienes ningún xDAI en Gnosis Chain? No hay problema, hay un (barato, rápido) [puente](https://bridge.connext.network/?receivingChainId=100&receivingAssetId=0x0000000000000000000000000000000000000000) para eso. \n\n¿Qué es crypto? He oído hablar de eso en las noticias, no quiero tener nada que ver con crypto. No hay problema, puedes pedir ayuda a los moderadores independientes en @SusieSupport.\n\n¿No tienes ninguna criptodivisa? No hay problema, hay una conveniente [fiat on-ramp](https://www.mtpelerin.com/buy-xdai) (tarjeta de crédito o transferencia bancaria) para comprar DAI en Gnosis Chain.\n\n¿Necesitas ayuda para añadir la red Gnosis Chain a tu cartera? No te preocupes, hay una [guía](https://docs.gnosischain.com/tools/wallets/metamask#2-configure) para eso.\n\n¿Necesitas más ayuda? No te preocupes, hay un grupo @SusieSupport para eso.", + "Greeting": "👋 Saludos", + "Language": "🗣️ Idiomas", + "Topics": "ℹ️ Temas", + "Evidence": "🔍 Evidencia", + "Report": "🚨 Report", + "Rules": "📄 Reglas", + "Court": "⚖️ Corte", + "Lawyer": "🧑‍⚖️ Abogado", + "Privacy": "🕵️ Privacidad", + "Notifications": "🔔 Notificaciones", + "Federations": "🌐 Federaciones", + "Gnosis": "⛓️ Gnosis" + } + } +} \ No newline at end of file diff --git a/lib/telegram/commands/addEvidence.ts b/lib/telegram/commands/addEvidence.ts index 7a2f3df..cca07de 100644 --- a/lib/telegram/commands/addEvidence.ts +++ b/lib/telegram/commands/addEvidence.ts @@ -6,7 +6,7 @@ import { setAllowance, getAllowance, getActiveEvidenceGroupId , existsQuestionId import fetch from 'node-fetch'; import { getQuestionsNotFinalized } from "../../graph"; import { groupSettings } from "../../../types"; -import langJson from "../assets/lang.json"; +import langJson from "../assets/langNew.json"; const _contract = require('../../abi/Realitio_v2_1_ArbitratorWithAppeals.json') const Web3 = require('web3') const web3 = new Web3(process.env.WEB3_PROVIDER_URL) @@ -35,7 +35,7 @@ const processCommand = async (queue: any, bot: any, settings: groupSettings, msg const evidenceJsonPath = await uploadEvidenceJson(settings.lang, msg, evidencePath,isPrivate); try{ queue.add(async () => {try{ - const resp = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].addevidence.submitted}(https://ipfs.kleros.io${evidencePath}).`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}) + const resp = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].addevidence.submitted}(https://ipfs.kleros.io${evidencePath}).`, msg.is_topic_message? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}) return resp.message_id}catch{}}); } catch(e){ console.log(e) @@ -112,11 +112,12 @@ const uploadLocationEvidence = async (lang: string, msg: TelegramBot.Message, is const enc = new TextEncoder(); var author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' ID:'+msg.reply_to_message.from.id ; var chatmsg = `${msg.chat.title} (${langJson[lang].addevidence.Chat} ID: ${msg.chat.id})` - if(isPrivate){ - const hashedUserID = web3.utils.sha3(String(msg.from.id)+process.env.secret); - author = ob.patp(hashedUserID.substring(0,8)) - chatmsg = `Private Telegram Group` - } const fileName = `${langJson[lang]["addevidence"].location}.txt`; + //if(isPrivate){ + // const hashedUserID = web3.utils.sha3(String(msg.reply_to_message.from.id)+process.env.secret); + // author = ob.patp(hashedUserID.substring(0,8)) + // chatmsg = `Private Telegram Group` + //} + const fileName = `${langJson[lang].addevidence.location}.txt`; var chatHistory = `${chatmsg} ${langJson[lang].addevidence.Author}: ${author} (${(new Date(msg.reply_to_message.date*1000)).toISOString()}) @@ -129,7 +130,7 @@ if (match){ var remainderMatch = match[1].split(' ') remainderMatch.shift(); const reason = remainderMatch.join(' ') - textReason = reason.length > 0? `Evidence Submitted with explanation: ${reason}` : '' + textReason = reason.length > 0? `${langJson[lang].addevidence.explain}: ${reason}` : '' } chatHistory += `\n\n${textReason}`; @@ -141,11 +142,11 @@ chatHistory += `\n\n${textReason}`; const uploadPollEvidence = async (lang: string, msg: TelegramBot.Message, isPrivate: boolean): Promise => { var author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' ID:'+msg.reply_to_message.from.id ; var chatmsg = `${msg.chat.title} (${langJson[lang].addevidence.Chat} ID: ${msg.chat.id})` - if(isPrivate){ - const hashedUserID = web3.utils.sha3(String(msg.from.id)+process.env.secret); + /*if(isPrivate){ + const hashedUserID = web3.utils.sha3(String(msg.reply_to_message.from.id)+process.env.secret); author = ob.patp(hashedUserID.substring(0,8)) chatmsg = `Private Telegram Group` - } + }*/ const enc = new TextEncoder(); const fileName = `${langJson[lang].addevidence.Poll}.txt`; var chatHistory = `${chatmsg} @@ -177,11 +178,11 @@ ${langJson[lang].addevidence.Message} (${langJson[lang].addevidence.Poll}): \n const uploadTextEvidence = async (lang: string, msg: TelegramBot.Message, isPrivate: boolean): Promise => { var author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' ID:'+msg.reply_to_message.from.id ; var chatmsg = `${msg.chat.title} (${langJson[lang].addevidence.Chat} ID: ${msg.chat.id})` - if(isPrivate){ - const hashedUserID = web3.utils.sha3(String(msg.from.id)+process.env.secret); + /*if(isPrivate){ + const hashedUserID = web3.utils.sha3(String(msg.reply_to_message.from.id)+process.env.secret); author = ob.patp(hashedUserID.substring(0,8)) chatmsg = `Private Telegram Group` - } + }*/ const enc = new TextEncoder(); const match = msg.text.match(regexpFull); @@ -190,7 +191,7 @@ const uploadTextEvidence = async (lang: string, msg: TelegramBot.Message, isPriv var remainderMatch = match[1].split(' ') remainderMatch.shift(); const reason = remainderMatch.join(' ') - textReason = reason.length > 0? `Evidence Submitted with explanation: ${reason}` : '' + textReason = reason.length > 0? `${langJson[lang].addevidence.explain}: ${reason}` : '' } const fileName = `${langJson[lang].addevidence.Message}.txt`; const chatHistory = `${chatmsg} @@ -209,24 +210,24 @@ ${textReason}`; const uploadEvidenceJson = async (lang: string, msg: TelegramBot.Message, evidenceItem: string, isPrivate: boolean): Promise => { var author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' ID:'+msg.reply_to_message.from.id ; var chatmsg = `${msg.chat.title} (${langJson[lang].addevidence.Chat} ID: ${msg.chat.id})` - if(isPrivate){ - const hashedUserID = web3.utils.sha3(String(msg.from.id)+process.env.secret); + /*if(isPrivate){ + const hashedUserID = web3.utils.sha3(String(msg.reply_to_message.from.id)+process.env.secret); author = ob.patp(hashedUserID.substring(0,8)) chatmsg = 'Private Telegram Group' - } + }*/ const _name = `Kleros Moderator Bot: ${langJson[lang].addevidence.Chat} ${langJson[lang].addevidence.History}`; const match = msg.text.match(regexpFull); var remainderMatch = match[1].split(' ') remainderMatch.shift(); const reason = remainderMatch.join(' ') console.log(reason) - const textReason = reason.length > 0? `Evidence Submitted with explanation: ${reason}` : '' + const textReason = reason.length > 0? `${langJson[lang].addevidence.explain}: ${reason}` : '' const enc = new TextEncoder(); if (!botAddress) botAddress = process.env.TRANSACTION_BATCHER_CONTRACT_ADDRESS const _description = `${langJson[lang].addevidence.Desc1}. - Chat: ${chatmsg} + ${langJson[lang].addevidence.Chat}: ${chatmsg} ${langJson[lang].addevidence.Author}: ${author} ${langJson[lang].addevidence.Date}: (${(new Date(msg.reply_to_message.date*1000)).toUTCString()}). ${textReason}`; @@ -266,7 +267,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, myQueue = queue if (!msg.reply_to_message) { try{ - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `/evidence ${langJson[settings.lang].errorReply}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `/evidence ${langJson[settings.lang].error.reply}`, msg.is_topic_message? {message_thread_id: msg.message_thread_id}:{}) return val}catch{}}) if(!resp) return @@ -278,7 +279,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, } const match = msg.text.match(regexpFull); - const opts = msg.chat.is_forum? { + const opts = msg.is_topic_message? { parse_mode: 'Markdown', message_thread_id: msg.message_thread_id, reply_markup: { @@ -307,7 +308,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, //TODO Evidence IDs and button callback UX if (!match || match.length < 2){ try{ - const msgresponse = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `You did not specify an evidence group.`, opts) + const msgresponse = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].addevidence.ID, opts) return val}catch{}}) if(!msgresponse) return @@ -317,7 +318,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, } //const questions = await getQuestionsNotFinalized(botAddress) //bot.sendMessage(msg.chat.id, `Did you mean `+ JSON.stringify(questions)); - //bot.sendMessage(msg.chat.id, `/addevidence ${langJson[settings.lang].addevidence.error1} ${langJson[settings.lang].addevidence.id}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{}) + //bot.sendMessage(msg.chat.id, `/addevidence ${langJson[settings.lang].addevidence.error1} ${langJson[settings.lang].addevidence.id}`, msg.is_topic_message? {message_thread_id: msg.message_thread_id}:{}) //const errorMsg = await errorMessage(db, lang, bot, msg); //await bot.sendMessage(msg.chat.id, errorMsg, {parse_mode: "Markdown", disable_web_page_preview: true}); return; @@ -343,7 +344,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), 3, 14, Math.ceil( new Date().getTime() / 1000)); } else if ((Math.ceil( new Date().getTime() / 1000) < reportAllowance.timestamp_refresh + 5760) && reportAllowance.evidence_allowance == 0 ){ try{ - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorAllowance) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].addevidence.allowance) return val}catch{}}); if(!resp) return diff --git a/lib/telegram/commands/addEvidenceHelp.ts b/lib/telegram/commands/addEvidenceHelp.ts index b6f7199..2277936 100644 --- a/lib/telegram/commands/addEvidenceHelp.ts +++ b/lib/telegram/commands/addEvidenceHelp.ts @@ -1,6 +1,6 @@ import * as TelegramBot from "node-telegram-bot-api"; import {getRule} from "../../db"; -import langJson from "../assets/lang.json"; +import langJson from "../assets/langNew.json"; import { getUsersWithQuestionsNotFinalized } from "../../db"; import { groupSettings } from "../../../types"; @@ -12,7 +12,7 @@ const regexp = /\/addevidencehelp/ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { const groupId = getUsersWithQuestionsNotFinalized(db, 'telegram', msg.text.substring(22)) if (!groupId || groupId.length === 0){ - queue.add(() => bot.sendMessage(msg.chat.id, `There are no reports to add evidence to in your group.`)); + queue.add(() => {try{bot.sendMessage(msg.chat.id, langJson[settings.lang].info.noevidence)}catch{}}); return } var inline_keyboard_evidence = [] @@ -37,7 +37,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, inline_keyboard: inline_keyboard_evidence } } - queue.add(() => bot.sendMessage(msg.chat.id, `Let me help you find the report you want to add evidence to. Which user is the report about?`,opts)); + queue.add(() => {try{bot.sendMessage(msg.chat.id, langJson[settings.lang].info.evidence,opts)}catch{}}); } export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/fedinfo.ts b/lib/telegram/commands/fedinfo.ts index 8e185e2..284fb35 100644 --- a/lib/telegram/commands/fedinfo.ts +++ b/lib/telegram/commands/fedinfo.ts @@ -1,7 +1,7 @@ import * as TelegramBot from "node-telegram-bot-api"; import { groupSettings } from "../../../types"; import {getFederationName,getGroupFederation,getGroupFederationFollowing} from "../../db"; -import langJson from "../assets/lang.json"; +import langJson from "../assets/langNew.json"; const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); var myBot; @@ -27,12 +27,16 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, let resp; if (fed_id || fed_id_following){ const name = getFederationName(db, 'telegram', fed_id ?? fed_id_following); - resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `This group is ${fed_id? 'in': 'following'} the *${name}* federation with id \`${fed_id ?? fed_id_following}\``, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) - return val}catch{}}) + if (settings.lang === 'en') + resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `This group is ${fed_id? 'in': 'following'} the *${name}* federation with id \`${fed_id ?? fed_id_following}\``, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) + return val}catch{}}) + else if (settings.lang === 'es') + resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `Este grupo ${fed_id? 'está en la': 'sigue a la '} federación *${name}* con id \`${fed_id ?? fed_id_following}\``, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) + return val}catch{}}) if(!resp) return } else - resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `No federation set.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) + resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].fed.nofed, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) return val}catch{}}); if(!resp) return diff --git a/lib/telegram/commands/getAccount.ts b/lib/telegram/commands/getAccount.ts index 0f24ba3..76e8aef 100644 --- a/lib/telegram/commands/getAccount.ts +++ b/lib/telegram/commands/getAccount.ts @@ -13,7 +13,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, try{ if (!address) address = (await new Wallet(process.env.PRIVATE_KEY)).address - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${langJson[settings.lang].getAccount}*: ${address}\n\n*Transaction Batch Address*: ${process.env.TRANSACTION_BATCHER_CONTRACT_ADDRESS}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}:{parse_mode: "Markdown"})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${langJson[settings.lang].getAccount}*: ${address}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}:{parse_mode: "Markdown"})}catch{}}); } catch(e){ console.log('gettaccount error. '+e) } diff --git a/lib/telegram/commands/getChannel.ts b/lib/telegram/commands/getChannel.ts index 2ef2053..fc016f3 100644 --- a/lib/telegram/commands/getChannel.ts +++ b/lib/telegram/commands/getChannel.ts @@ -1,6 +1,6 @@ import * as TelegramBot from "node-telegram-bot-api"; import {getRule, getInviteURLChannel, getFederatedInviteURLChannel, getChannelID} from "../../db"; -import langJson from "../assets/lang.json"; +import langJson from "../assets/langNew.json"; import { groupSettings } from "../../../types"; const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); @@ -23,20 +23,20 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, const channel_invite = getInviteURLChannel(db, 'telegram', String(msg.chat.id)); if(settings.federation_id || settings.federation_id_following){ const inviteurl = getFederatedInviteURLChannel(db, 'telegram', settings.federation_id); - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `The notifications for this group's federation are sent to this [channel](${inviteurl}).`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].notifications.getFed}(${inviteurl}).`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}) return val}catch{}}); if(!resp) return myCache.set(resp.message_id, msg.chat.id) } if(!channel_invite && !msg.chat.is_forum){ - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `Notifications channel for this group is not set. Ask an admin to \`/setchannel\`.`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].notifications.notset,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id}:{parse_mode: "Markdown"}) return val}catch{}}); if(!resp) return myCache.set(resp.message_id, msg.chat.id) } else { - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `I notify this [channel](${channel_invite}) about moderation activity.`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id, disable_web_page_preview: true}:{parse_mode: "Markdown", disable_web_page_preview: true}) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].notifications.get}(${channel_invite}).`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id, disable_web_page_preview: true}:{parse_mode: "Markdown", disable_web_page_preview: true}) return val}catch{}}); if(!resp) return diff --git a/lib/telegram/commands/getReports.ts b/lib/telegram/commands/getReports.ts index 0531e8b..aa55d77 100644 --- a/lib/telegram/commands/getReports.ts +++ b/lib/telegram/commands/getReports.ts @@ -1,9 +1,8 @@ import * as TelegramBot from "node-telegram-bot-api"; const escape = require('markdown-escape') -import langJson from "../assets/lang.json"; +import langJson from "../assets/langNew.json"; import {getReportsUserInfo ,getActiveReportsInfo,getReportsUserInfoFederation, getInviteURL,getLocalBanHistory, getFederatedBanHistory, getFederatedFollowingBanHistory, getTitle} from "../../db"; import { groupSettings } from "../../../types"; -import {calcPenalty} from "../../cron" const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); var myBot; @@ -15,7 +14,6 @@ myCache.on("expired",function(key,value){ * /getreports */ const regexp = /\/info/ - const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botid: number, msg: any) => { if (!myBot) myBot = bot @@ -30,7 +28,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, inline_keyboard: [ [ { - text: 'Get Report Info', + text: langJson[settings.lang].info.get, url: `https://t.me/${process.env.BOT_USERNAME}?start=getreport${msg.chat.id}${(msg.reply_to_message && !msg.reply_to_message.forum_topic_created)? msg.reply_to_message.from.id: ''}${(settings.federation_id ?? settings.federation_id_following + 'following') ?? ''}` } ] @@ -42,14 +40,14 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, inline_keyboard: [ [ { - text: 'Get Report Info', + text: langJson[settings.lang].info.get, url: `https://t.me/${process.env.BOT_USERNAME}?start=getreport${msg.chat.id}${(msg.reply_to_message && !msg.reply_to_message.forum_topic_created)? msg.reply_to_message.from.id: ''}${(settings.federation_id ?? settings.federation_id_following) ?? ''}` } ] ] } } - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `DM me for report info : )`, opts) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].info.DM, opts) return val}catch{}}); if(!resp) return @@ -91,7 +89,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, if (ban_level > 0){ const date_lastreport = new Date(banHistory[ban_level-1].timestamp*1000).toUTCString() const date_parole = new Date(1000*calcPenalty(ban_level, max_timestamp)).toUTCString() - reportMessage += `*${escape(fromUsername)}* broke the rules atleast ${ban_level} time(s), and is banned until ${date_parole}.\n\n` + reportMessage += `*${escape(fromUsername)}* ${langJson[settings.lang].info.report1} ${ban_level} ${langJson[settings.lang].info.report2} ${date_parole}.\n\n` } reportMessage += `*${langJson[settings.lang].getReports.ReportsFor} ${escape(fromUsername)}*:\n\n`; if (reports.length === 0){ @@ -106,7 +104,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, }); if(federation_id){ const reportsFederation = getReportsUserInfoFederation(db, 'telegram', user_id, federation_id,group_id); - reportMessage += `\n*Federal reports for ${escape(fromUsername)}*:\n\n` + reportMessage += `\n*${langJson[settings.lang].info.fed} ${escape(fromUsername)}*:\n\n` if (reportsFederation.length == 0){ reportMessage += `${langJson[settings.lang].getReports.noReports}.\n` } @@ -146,4 +144,16 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, } } + +const calcPenalty = (ban_level: number, timestamp_finalized: number): number => { + if(ban_level == 1) + return timestamp_finalized + 86400 + else if (ban_level == 2) + return timestamp_finalized + 604800 + else if (ban_level == 3) + return timestamp_finalized + 2678400 + else + return timestamp_finalized + 31536000 +} + export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/getRules.ts b/lib/telegram/commands/getRules.ts index 46259fb..63d2f5a 100644 --- a/lib/telegram/commands/getRules.ts +++ b/lib/telegram/commands/getRules.ts @@ -1,6 +1,6 @@ import * as TelegramBot from "node-telegram-bot-api"; import {getRule} from "../../db"; -import langJson from "../assets/lang.json"; +import langJson from "../assets/langNew.json"; import { groupSettings } from "../../../types"; const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); @@ -20,11 +20,22 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, myBot = bot if (!myQueue) myQueue = queue - getRule(db,'telegram', msg.chat.id,Math.floor(Date.now()/1000)) - const msgresponse = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].rules}(${settings.rules}).`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id, disable_web_page_preview: false}:{parse_mode: "Markdown", disable_web_page_preview: false}) - return val}catch{}}); - if(!msgresponse) - return; + const ruleObj = getRule(db,'telegram', String(msg.chat.id),Math.floor(Date.now()/1000)) + var msgresponse; + if (ruleObj?.msg_id){ + const MsgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + ruleObj.msg_id; + console.log(MsgLink) + msgresponse = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].rules}(${MsgLink}).`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id, disable_web_page_preview: false}:{parse_mode: "Markdown", disable_web_page_preview: false}) + return val}catch{}}); + if(!msgresponse) + return; + } else { + console.log(msg) + msgresponse = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].rules}(${settings.rules}).`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id, disable_web_page_preview: false}:{parse_mode: "Markdown", disable_web_page_preview: false}) + return val}catch{}}); + if(!msgresponse) + return; + } myCache.set(msgresponse.message_id, msg.chat.id) } diff --git a/lib/telegram/commands/greeting.ts b/lib/telegram/commands/greeting.ts index 2b60886..04ebf5f 100644 --- a/lib/telegram/commands/greeting.ts +++ b/lib/telegram/commands/greeting.ts @@ -1,6 +1,7 @@ import * as TelegramBot from "node-telegram-bot-api"; -import langJson from "../assets/lang.json"; +import langJson from "../assets/langNew.json"; import {groupSettings} from "../../../types"; +import {getMultilangGroup} from "../../db" const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); @@ -11,11 +12,20 @@ myCache.on("expired",function(key,value){ myQueue.add(async () => {try{await myBot.deleteMessage(value, key)}catch{}}); }); -const callback = async (queue: any, bot: any, settings: groupSettings, msg: any) => { +const callback = async (db: any, queue: any, bot: any, settings: groupSettings, msg: any) => { if (!myBot) myBot = bot if (!myQueue) myQueue = queue + + console.log('WELCOME!') + const lang_code = msg?.from?.language_code + let msg_greeting = '' + if (true || lang_code !== settings.lang && (lang_code === 'en' || lang_code === 'es')){ + const invite_url = getMultilangGroup(db, 'telegram',String(msg.chat.id), 'en') + if (invite_url) + msg_greeting = '\n\n'+langJson[settings.lang].greeting.multilang+'('+invite_url+').\n\n' + } try{ const opts = { parse_mode: 'Markdown', @@ -24,7 +34,7 @@ const callback = async (queue: any, bot: any, settings: groupSettings, msg: any) inline_keyboard: [ [ { - text: 'I agree to follow the rules.', + text: langJson[settings.lang].greeting.captcha, callback_data: '5|'+String(msg.from.id) } ] @@ -39,22 +49,25 @@ const callback = async (queue: any, bot: any, settings: groupSettings, msg: any) inline_keyboard: [ [ { - text: 'I agree to follow the rules.', + text: langJson[settings.lang].greeting.captcha, callback_data: '5|'+String(msg.from.id) } ] ] } }; + const msg_greeting_full = `${langJson[settings.lang].greeting.greeting0} [${msg.from.first_name}](tg://user?id=${msg.from.id}). ${msg_greeting} ${langJson[settings.lang].greeting.greeting1}(${settings.rules}). ${langJson[settings.lang].greeting.greeting2}` + console.log('full') + console.log(msg_greeting_full) let msg_welcome; if(settings.captcha){ const options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false}; - queue.add(async () => {try{await bot.restrictChatMember(msg.chat.id, msg.from.id, options)}catch{}}); - msg_welcome = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `Hi 👋 Welcome [${msg.from.first_name}](tg://user?id=${msg.from.id}). ${langJson[settings.lang].greeting2}(${settings.rules}).`, msg.chat.is_forum? optsThread: opts) - return val}catch{}}); + queue.add(async () => {try{await bot.restrictChatMember(msg.chat.id, msg.from.id, options)}catch (e){console.log(e)}}); + msg_welcome = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, msg_greeting_full, msg.chat.is_forum? optsThread: opts) + return val}catch(e){console.log(e)}}); } else if (settings.greeting_mode){ - msg_welcome = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `Hi 👋 Welcome [${msg.from.first_name}](tg://user?id=${msg.from.id}). ${langJson[settings.lang].greeting2}(${settings.rules}).`, msg.chat.is_forum? {message_thread_id: settings.thread_id_welcome,disable_web_page_preview: true}: {disable_web_page_preview: true}) - return val}catch{}}); + msg_welcome = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, msg_greeting_full, msg.chat.is_forum? {message_thread_id: settings.thread_id_welcome,disable_web_page_preview: true}: {disable_web_page_preview: true}) + return val}catch(e){console.log(e)}}); } if(!msg_welcome) return diff --git a/lib/telegram/commands/help.ts b/lib/telegram/commands/help.ts index c05b7e6..3520d9a 100644 --- a/lib/telegram/commands/help.ts +++ b/lib/telegram/commands/help.ts @@ -1,5 +1,5 @@ import * as TelegramBot from "node-telegram-bot-api"; -import langJson from "../assets/lang.json"; +import langJson from "../assets/langNew.json"; import { groupSettings } from "../../../types"; /* @@ -8,45 +8,18 @@ import { groupSettings } from "../../../types"; const regexp = /\/help/ const helpgnosis = (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { + const lang_code = msg?.from?.language_code try{ - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `⛓️ *Gnosis Chain* ⛓️ - -Susie uses [xDAI](https://docs.gnosischain.com/about/tokens/xdai), a stable coin, on [Gnosis Chain](https://www.gnosis.io/). Don't know what that means? It means Susie uses a cheap and fast decentralized tool to coordinate moderation fairly and transparently. - -What's crypto? I heard about that on the news, I don't want anything to do with crypto. No problem, you can ask for help from freelance moderators in @KlerosModerateGuildOfJustice. - -Don't have any xDAI on Gnosis Chain? No problem, there's a (cheap, fast) [bridge](https://bridge.connext.network/?receivingChainId=100&receivingAssetId=0x0000000000000000000000000000000000000000) for that. - -Don't have any cryptocurrency? No problem, there's a convinient [fiat on-ramp](https://www.mtpelerin.com/buy-xdai) (credit card or bank transfer) to buy DAI on Gnosis Chain. - -Need help adding the Gnosis Chain network to your wallet? Don't worry, there's a [guide](https://docs.gnosischain.com/tools/wallets/metamask#2-configure) for that. - -Need more help? Don't worry, there's a @SusieSupport group for that` - ,{parse_mode: 'Markdown', disable_web_page_preview: true})}catch{}}) + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[lang_code].help.Gnosis1,{parse_mode: 'Markdown', disable_web_page_preview: true})}catch{}}) } catch(e){ console.log(e) } } const helpnotifications = (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { + const lang_code = msg?.from?.language_code try{ - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `🔔 *Notifications* 🔔 - -Susie sends notifications about moderation actions and report updates. These notifications are restricted to a separate chat in topic mode. In regular Telegram groups, notifications can be sent to a notification channel to avoid cluttering the main chat. - -How to enable notification channels: - -1. Make a channel -2. Add Susie -3. Susie will send a channel ID -4. Use that channel ID to set notifications with \`/setchannel\` in the original group - -*User commands*: -- \`/notifications\`: Returns current notification channel -*Admin commands*: -- \`/setchannel\` : Sets the notification channel to the specified channel id -- \`/setfedchannel\` : Sets the notification channel for your federation to the specified channel id` - ,{parse_mode: 'Markdown', disable_web_page_preview: true})}catch{}}) + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[lang_code].help.Notifications1,{parse_mode: 'Markdown', disable_web_page_preview: true})}catch{}}) //queue.add(async () => {try{await bot.sendVideo(msg.chat.id, `https://ipfs.kleros.io/ipfs/QmaWKFxR8TNzWW1xDuzXe4XFE5wCFJVuFP6AKCQ3LRAQqB/Screen%20Recording%202022-12-13%20at%209.19.17%20PM(1).mp4`)); } catch(e){ console.log(e) @@ -55,6 +28,64 @@ How to enable notification channels: const callback = (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { + const lang_code = msg?.from?.language_code === "es" ? "es" : "en" + + const opts = { + parse_mode: 'Markdown', + disable_web_page_preview: true, + reply_markup: { + inline_keyboard: [ + [ + { + text: langJson[lang_code].help.Greeting, + callback_data: `3|greeting` + }, { + text: langJson[lang_code].help.Language, + callback_data: `3|language` + }, { + text: langJson[lang_code].help.Topics, + callback_data: `3|topics` + } + ], + [ + { + text: langJson[lang_code].help.Evidence, + callback_data: `3|addevidence` + }, { + text: langJson[lang_code].help.Report, + callback_data: `3|report` + }, { + text: langJson[lang_code].help.Rules, + callback_data: `3|rules` + } + ], + [ + { + text: langJson[lang_code].help.Court, + callback_data: `3|court` + }, { + text: langJson[lang_code].help.Lawyer, + callback_data: `3|lawyer` + }, { + text: langJson[lang_code].help.Privacy, + callback_data: `3|open` + } + ],[ + { + text: langJson[lang_code].help.Notifications, + callback_data: `3|notifications` + }, { + text: langJson[lang_code].help.Federations, + callback_data: `3|federation` + }, { + text: langJson[lang_code].help.Gnosis, + callback_data: `3|web2.5` + } + ] + ] + } + } + if (msg.chat.type !== "private"){ const opts = msg.chat.is_forum? { message_thread_id: msg.message_thread_id, @@ -63,7 +94,7 @@ const callback = (queue: any, db: any, settings: groupSettings, bot: any, botId: inline_keyboard: [ [ { - text: 'Get Help (DM)', + text: langJson[lang_code].help.DM, url: `https://t.me/${process.env.BOT_USERNAME}?start=help` } ] @@ -75,20 +106,22 @@ const callback = (queue: any, db: any, settings: groupSettings, bot: any, botId: inline_keyboard: [ [ { - text: 'Get Help (DM)', + text: langJson[lang_code].help.DM, url: `https://t.me/${process.env.BOT_USERNAME}?start=help` } ] ] } } - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `DM me for help : )`, opts)}catch{}}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[lang_code].help.DM2, opts)}catch{}}); return; - } - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, message,opts)}catch{}}); + } else + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[lang_code].help.help,opts)}catch{}}); } const respond = (queue: any, settings: groupSettings, bot: any, helpType: string, callbackQuery: TelegramBot.CallbackQuery) => { + const lang_code = callbackQuery?.from?.language_code + const optsResponse = { chat_id: callbackQuery.message.chat.id, message_id: callbackQuery.message.message_id, @@ -108,224 +141,102 @@ const respond = (queue: any, settings: groupSettings, bot: any, helpType: string inline_keyboard: [ [ { - text: '👋 Greeting', + text: langJson[lang_code].help.Greeting, callback_data: `3|greeting` }, { - text: '🗣️ Language', + text: langJson[lang_code].help.Language, callback_data: `3|language` }, { - text: 'ℹ️ Topics', + text: langJson[lang_code].help.Topics, callback_data: `3|topics` } ], [ { - text: '🔍 Evidence', + text: langJson[lang_code].help.Evidence, callback_data: `3|addevidence` }, { - text: '🚨 Report', + text: langJson[lang_code].help.Report, callback_data: `3|report` }, { - text: '📄 Rules', + text: langJson[lang_code].help.Rules, callback_data: `3|rules` } ], [ { - text: '⚖️ Court', + text: langJson[lang_code].help.Court, callback_data: `3|court` }, { - text: '🧑‍⚖️ Lawyer', + text: langJson[lang_code].help.Lawyer, callback_data: `3|lawyer` }, { - text: '🕵️ Privacy', + text: langJson[lang_code].help.Privacy, callback_data: `3|open` } ],[ { - text: '🔔 Notifications', + text: langJson[lang_code].help.Notifications, callback_data: `3|notifications` }, { - text: '🌐 Federation', + text: langJson[lang_code].help.Federations, callback_data: `3|federation` }, { - text: '⛓️ Gnosis', + text: langJson[lang_code].help.Gnosis, callback_data: `3|web2.5` } ] ]}, optsResponse)}catch{}}); - queue.add(async () => {try{await bot.editMessageText(message,optsResponse)}catch{}}) + queue.add(async () => {try{await bot.editMessageText(langJson[lang_code].help.help,optsResponse)}catch{}}) } switch(helpType){ case 'greeting': { - queue.add(async () => {try{await bot.editMessageText(`👋 *Greeting* 👋 - -Welcome your members with a greeting informing them of the group rules - -*Admin commands:* -- \`/welcome\` : Toggles on/off welcomes messages. -- \`/captcha\` : Toggles on/off rules captcha. - -When a new person joins, or after 5 minutes, the previous welcome messages will get deleted\n\nCaptchas remain for up to 5 minutes. If a user forgets to respond within 5 minutes, they should rejoin the group to prompt a new captcha. - `,optsResponse)}catch{}}) + queue.add(async () => {try{await bot.editMessageText(langJson[lang_code].help.Greeting1,optsResponse)}catch{}}) break; } case 'language': { - queue.add(async () => {try{await bot.editMessageText(`🗣️ *Languages* 🗣️ - -Susie's replies can be changed to one of the languages below. - -- EN (English) -- ES (Español) *soon* - -*Admin commands*: -- \`/setlang\` : Set your preferred language. - -Content moderation requires a nuanced understanding of context and language. Setting a language not only changes Susie's responses, but also specifies language skilled jurors. - -Please make sure to set the appropriate language for your community for effective moderation.` - ,optsResponse)}catch{}}) + queue.add(async () => {try{await bot.editMessageText(langJson[lang_code].help.Language1,optsResponse)}catch{}}) break; } case 'topics': { - queue.add(async () => {try{await bot.editMessageText(`ℹ️ *Topics* ℹ️ - -Topics allow large (>200 member) groups to focus discussion in dedicated **topic** chats. Susie supports topics. When changing a group to topic mode, you will need to /start Susie again. - -*Admin commands*: -- \`/start\`: Start topic mode.` - ,optsResponse)}catch{}}) + queue.add(async () => {try{await bot.editMessageText(langJson[lang_code].help.Topics1,optsResponse)}catch{}}) break; } case 'addevidence': { - queue.add(async () => {try{await bot.editMessageText(`🔍 *Evidence* 🔍 - -To prevent important messages from deletion, pre-emptively, messages can be saved as evidence. - -Note that Susie uses a proxy contract to efficiently batch reports. In case of dispute over authenticity, evidence submitted by the Kleros Moderate bot is time stamped in chat. Moreover, this timestamp should be consistent with any evidence submitted by the bot address through the transaction batching contract. - -*User commands*: -- \`/evidence\` : Reply to a message to add it as evidence. -- \`/getaccount\`: Gets bot and transaction batcher addresses.` - ,optsResponse)}catch{}}) + queue.add(async () => {try{await bot.editMessageText(langJson[lang_code].help.Evidence1,optsResponse)}catch{}}) break; } case 'report': { - queue.add(async () => {try{await bot.editMessageText(`🚨 *Report* 🚨 - -As groups grow, so do their moderation problems. We're all busy people who don't have time to monitor groups 24/7. Users often complain about admin abuse and have no recourse. Who moderates the moderator? - -Presenting [Kleros Moderate](https://kleros.io/moderate), a crowd-sourced content moderation tool using [Reality.eth](https://reality.eth.limo/) and [Kleros](https://kleros.gitbook.io/docs/) on [Gnosis Chain](https://www.gnosis.io/). - -When users are reported, a question is created on Reality.Eth asking 'did the user break the rules?'. The question can be answered yes/no with a bond (5 DAI). Successful reports result in penalties, - -- 1st Report: 1 day ban -- 2nd Report: 1 week ban -- 3rd Report: 1 year ban - -Answers to reports can be disputed, creating a case in the Kleros court. Refer to the [docs](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator) to learn more. - -*User commands*: -- \`/report\` : Reply to a message to report it -- \`/info\`: Returns active reports -- \`/info\` : Returns active reports for user` - ,optsResponse)}catch{}}) + queue.add(async () => {try{await bot.editMessageText(langJson[lang_code].help.Report1,optsResponse)}catch{}}) break; } case 'rules': { - queue.add(async () => {try{await bot.editMessageText(`⚖️ *Rules* ⚖️ - -The Kleros Moderate Community Guidelines apply as the [default rules]((https://ipfs.kleros.io/ipfs/QmYYcNfEYLtxPM8fof4wf9Tqj7gBGMDMmNnBqZKR1zSczX/Kleros%20Moderate%20Community%20Guidelines%20v1.pdf)). Crafting precise policies can be challenging, if you are certain in setting a new policy, you can set new rules with /setrules - -*User commands*: -- \`/rules\`: Returns current rules -*Admin commands*: -- \`/setrules\` : Sets the rules to the the url -- \`/setrules\` : Sets the rules to a replied message` - ,optsResponse)}catch{}}) + queue.add(async () => {try{await bot.editMessageText(langJson[lang_code].help.Rules1,optsResponse)}catch{}}) break; } case 'notifications': { - queue.add(async () => {try{await bot.editMessageText(`🔔 *Notifications* 🔔 - -Susie sends notifications about moderation actions and report updates. These notifications are restricted to a separate chat in topic mode. In regular Telegram groups, notifications can be sent to a notification channel to avoid cluttering the main chat. - -How to enable notification channels: - -1. Make a channel -2. Add Susie -3. Susie will send a channel ID -4. Use that channel ID to set notifications with /setchannel in the original group - -*User commands*: -- \`/notifications\`: Returns current notification channel -*Admin commands*: -- \`/setchannel\` : Sets the notification channel to the specified channel id -- \`/setfedchannel\` : Sets the notification channel for your federation to the specified channel id` - ,optsResponse)}catch{}}) + queue.add(async () => {try{await bot.editMessageText(langJson[lang_code].help.Notifications1,optsResponse)}catch{}}) break; } case 'federation': { - queue.add(async () => {try{await bot.editMessageText(`🌐 *Federations* - -Moderating a single group is hard, but managing multiple is even harder? Do you have to ban spammers manually, in all your groups? - -No more! With federations, Susie can enforce a ban on a user in all federate groups. - -*User commands*: -- \`/fedinfo\`: Returns current federation -*Admin commands*: -- \`/newfed\`: Creates a federation -- \`/joinfed\`: Joins the current group to a Federation` - ,optsResponse)}catch{}}) + queue.add(async () => {try{await bot.editMessageText(langJson[lang_code].help.Federations1,optsResponse)}catch{}}) break; } case 'web2.5': { - queue.add(async () => {try{await bot.editMessageText(`⛓️ *Gnosis Chain* ⛓️ - -Susie uses [xDAI](https://docs.gnosischain.com/about/tokens/xdai), a stable coin, on [Gnosis Chain](https://www.gnosis.io/). Don't know what that means? It means Susie uses a cheap and fast public ledger to coordinate moderation fairly and transparently. - -Don't have any xDAI on Gnosis Chain? No problem, there's a (cheap, fast) [bridge](https://bridge.connext.network/?receivingChainId=100&receivingAssetId=0x0000000000000000000000000000000000000000) for that. - -What's crypto? I heard about that on the news, I don't want anything to do with crypto. No problem, you can ask for help from freelance moderators in @KlerosModerateGuildOfJustice. - -Don't have any cryptocurrency? No problem, there's a convinient [fiat on-ramp](https://www.mtpelerin.com/buy-xdai) (credit card or bank transfer) to buy DAI on Gnosis Chain. - -Need help adding the Gnosis Chain network to your wallet? Don't worry, there's a [guide](https://docs.gnosischain.com/tools/wallets/metamask#2-configure) for that. - -Need more help? Don't worry, there's a @SusieSupport group for that` + queue.add(async () => {try{await bot.editMessageText(langJson[lang_code].help.Gnosis1 ,optsResponse)}catch{}}) break; } case 'court': { - queue.add(async () => {try{await bot.editMessageText(`⚖️ *Court* ⚖️ - -Disputes are resolved by the [Kleros Court](https://kleros.gitbook.io/docs/) with a randomly selected jury. If the jury made a mistake, the case can be appealed, drawing a larger pool of random jurors and providing an opportunity to provide more context, analysis, and arguments. - -If you would like a chance to serve as a jury member, buy PNK ([Gnosis Chain](https://swapr.eth.link/#/swap?chainId=100) or [Mainnet](https://app.uniswap.org/#/swap?outputCurrency=0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d&inputCurrency=ETH)) and [stake](https://court.kleros.io/) in the curation subcourt of the Kleros Court on Gnosis Chain. - -To discuss the merits of a dispute, see @klerosjuror.` - ,optsResponse)}catch{}}) + queue.add(async () => {try{await bot.editMessageText(langJson[lang_code].help.Court1,optsResponse)}catch{}}) break; } case 'lawyer': { - queue.add(async () => {try{await bot.editMessageText(`🧑‍⚖️ *Find a Lawyer* 🧑‍⚖️ - -Disputes over reported behavior can be complicated and nuanced. Often, disputes resolve on the merits of the message and rules alone. In some cases, disputes are better resolved by presenting the court with analysis and arguments. - -If you would like to offer your services as a lawyer or solicit services, please join this [group](https://t.me/+9fvGGkGfSZ1hZDBk). - -` - ,optsResponse)}catch{}}) + queue.add(async () => {try{await bot.editMessageText(langJson[lang_code].help.Lawyer1,optsResponse)}catch{}}) break; } case 'open': { - queue.add(async () => {try{await bot.editMessageText(`🕵️ *Privacy* 🕵️ - -Effective moderation depends on access to the full context of a reported message. To provide context, users can request Susie to save messages to submit as evidence on their behalf. Susie manages moderation private and public groups differently, - -- In *private* groups, reports are created using psuedonyms for users involved. -- In *public* groups, reports are created using original usernames. Susie also creates open invitations for moderators to join the group and investigate reports.` + queue.add(async () => {try{await bot.editMessageText(langJson[lang_code].help.Privacy1 ,optsResponse)}catch{}}) break; //Susie is [open source](https://github.com/kleros/kleros-moderate). Feel free to make an issue, feature request, bug report, comments, suggests, PRs, forks, etc : ) @@ -340,73 +251,6 @@ Effective moderation depends on access to the full context of a reported message } } -const message = `*Help*\n\nHi! My name is Susie. I'm a [Kleros Moderate](https://kleros.io/moderate) bot, here to help you manage your groups! - -I have lots of handy features, such as crowd-sourced user reporting. - -Helpful commands: - - /start: Starts me. You've probably already used this. - - /help: Sends this message and I'll tell you more about myself. - -Select a feature to learn more. My [documentation](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator) is also helpful, or ask a question in @SusieSupport. You can follow news and updates in @KlerosModerateNews.`; - //Important: I moderate groups by crowd-sourcing community input with Gnosis Chain. Make sure you or some community members get DAI on Gnosis Chain to participate actively. -const opts = { - parse_mode: 'Markdown', - disable_web_page_preview: true, - reply_markup: { - inline_keyboard: [ - [ - { - text: '👋 Greeting', - callback_data: `3|greeting` - }, { - text: '🗣️ Language', - callback_data: `3|language` - }, { - text: 'ℹ️ Topics', - callback_data: `3|topics` - } - ], - [ - { - text: '🔍 Evidence', - callback_data: `3|addevidence` - }, { - text: '🚨 Report', - callback_data: `3|report` - }, { - text: '📄 Rules', - callback_data: `3|rules` - } - ], - [ - { - text: '⚖️ Court', - callback_data: `3|court` - }, { - text: '🧑‍⚖️ Lawyer', - callback_data: `3|lawyer` - }, { - text: '🕵️ Privacy', - callback_data: `3|open` - } - ], - [ - { - text: '🔔 Notifications', - callback_data: `3|notifications` - }, { - text: '🌐 Federation', - callback_data: `3|federation` - }, { - text: '⛓️ Gnosis', - callback_data: `3|web2.5` - } - ] - ] - } -} - export {regexp, callback, respond, helpgnosis, helpnotifications}; \ No newline at end of file diff --git a/lib/telegram/commands/joinfed.ts b/lib/telegram/commands/joinfed.ts index 3cdd6bc..73082a2 100644 --- a/lib/telegram/commands/joinfed.ts +++ b/lib/telegram/commands/joinfed.ts @@ -1,7 +1,7 @@ import * as TelegramBot from "node-telegram-bot-api"; import { groupSettings } from "../../../types"; import {joinFederation,followFederation,getFederationName} from "../../db"; -import langJson from "../assets/lang.json"; +import langJson from "../assets/langNew.json"; const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); var myBot; @@ -23,7 +23,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, if (!myQueue) myQueue = queue if (!match[1]){ - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(settings.channelID, `Please specify a federation eg. \`/joinfed \`.`,msg.chat.is_forum? { + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(settings.channelID, langJson[settings.lang].fed.specify,msg.chat.is_forum? { message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}) return val}catch{}}); @@ -33,7 +33,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, } else{ const name = getFederationName(db, 'telegram',match[1]) if (!name){ - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(settings.channelID, `Federation not found. Use /fedinfo in a group whose federation you want to join to find its ID.`,msg.chat.is_forum? { + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(settings.channelID, langJson[settings.lang].fed.notfound,msg.chat.is_forum? { message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}:{parse_mode: 'Markdown'}) return val}catch{}}); @@ -42,11 +42,11 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, myCache.set(resp.message_id, msg.chat.id) } else if (msg.from.id == match[1]){ - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `Your group is now part of the *${name}* federation.`,msg.chat.is_forum? {message_thread_id: msg.message_thread_id,parse_mode: 'Markdown'}:{parse_mode: 'Markdown'})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].fed.joined} *${name}*.`,msg.chat.is_forum? {message_thread_id: msg.message_thread_id,parse_mode: 'Markdown'}:{parse_mode: 'Markdown'})}catch{}}); joinFederation(db, 'telegram', String(msg.chat.id), match[1]) } else{ - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `Your group is now following the *${name}* federation.`,msg.chat.is_forum? {message_thread_id: msg.message_thread_id,parse_mode: 'Markdown'}:{parse_mode: 'Markdown'})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].fed.following} *${name}*.`,msg.chat.is_forum? {message_thread_id: msg.message_thread_id,parse_mode: 'Markdown'}:{parse_mode: 'Markdown'})}catch{}}); followFederation(db, 'telegram', String(msg.chat.id), match[1]) } } diff --git a/lib/telegram/commands/leavefed.ts b/lib/telegram/commands/leavefed.ts index f468e1c..034bb5d 100644 --- a/lib/telegram/commands/leavefed.ts +++ b/lib/telegram/commands/leavefed.ts @@ -1,7 +1,7 @@ import * as TelegramBot from "node-telegram-bot-api"; import { groupSettings } from "../../../types"; import {leaveFederation} from "../../db"; -import langJson from "../assets/lang.json"; +import langJson from "../assets/langNew.json"; /* * /joinfed @@ -11,7 +11,7 @@ const regexp = /\/leavefed/ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: string, msg: any, match: string[]) => { try{ leaveFederation(db, 'telegram', String(msg.chat.id), String(msg.from.id)) - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, 'Your group has left the federation.', msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{})}catch{}}) + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[settings.lang].fed.leave, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}:{})}catch{}}) } catch(e){ console.log(e) } diff --git a/lib/telegram/commands/multilang.ts b/lib/telegram/commands/multilang.ts new file mode 100644 index 0000000..3ea5ee7 --- /dev/null +++ b/lib/telegram/commands/multilang.ts @@ -0,0 +1,34 @@ +import * as TelegramBot from "node-telegram-bot-api"; +import {groupSettings} from "../../../types"; +import {setMultilangGroup} from "../../db"; +import langJson from "../assets/langNew.json"; +const NodeCache = require( "node-cache" ); +const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); + +/* + * /multilang [lang code] [invite url] + */ +const regexp = /\/multilang/ +const regexpFull = /\/multilang (.+)/ + +const callback = async (queue: any, db: any, settings: groupSettings, bot: TelegramBot, botId: string, msg: any, match: string[], batchedSend: any) => { + try { + const newmatch = msg.text.match(regexpFull); + if (!newmatch || newmatch.length < 2){ + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].multilang.error, {parse_mode: "Markdown", disable_web_page_preview: true}) + return val}catch{}}); + if(!resp) + return + myCache.set(resp.message_id, msg.chat.id) + return; + } + console.log(newmatch) + const lang_sibling = settings.lang === 'en' ? 'es' : 'en' + setMultilangGroup(db, 'telegram', String(msg.chat.id), newmatch[1], lang_sibling); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[settings.lang].multilang[lang_sibling], {parse_mode: "Markdown", disable_web_page_preview: true})}catch{}}); + } catch (error) { + console.log(error); + } +} + +export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/newfed.ts b/lib/telegram/commands/newfed.ts index cdbd5a4..661f8df 100644 --- a/lib/telegram/commands/newfed.ts +++ b/lib/telegram/commands/newfed.ts @@ -1,7 +1,7 @@ import * as TelegramBot from "node-telegram-bot-api"; import { groupSettings } from "../../../types"; import {setFederation,getFederationName} from "../../db"; -import langJson from "../assets/lang.json"; +import langJson from "../assets/langNew.json"; const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); var myBot; @@ -30,7 +30,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, inline_keyboard: [ [ { - text: 'Create your federation', + text: langJson[settings.lang].fed.create, url: `https://t.me/${process.env.BOT_USERNAME}?start=newfed` } ] @@ -42,14 +42,14 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, inline_keyboard: [ [ { - text: 'Create your federation', + text: langJson[settings.lang].fed.create, url: `https://t.me/${process.env.BOT_USERNAME}?start=newfed` } ] ] } } - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `DM me for help with your federation : )`, opts) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].fed.create2, opts) return val}catch{}}); if (!resp) return resp @@ -59,20 +59,20 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, const name = getFederationName(db, 'telegram',String(msg.from.id)); console.log(name) if (name){ - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `Your federation *${name}* with id \`${msg.from.id}\` already exists.`,msg.chat.is_forum? { + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `${langJson[settings.lang].fed.exists} *${name}* id \`${msg.from.id}\` `,msg.chat.is_forum? { message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}:{parse_mode: 'Markdown'})}catch{}}); return } if (!match[1]){ - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `Please name your federation eg: \`/newfed My New Federation\``,msg.chat.is_forum? { + queue.add(async () => {try{await bot.sendMessage(settings.channelID, langJson[settings.lang].fed.name,msg.chat.is_forum? { message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}:{parse_mode: 'Markdown'})}catch{}}); return } else{ const name = match[1].substring(0,65) setFederation(db, 'telegram',name, String(msg.from.id)) - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `Your new federation is called *${match[1].substring(0,65)}* with id ${msg.from.id}. You can add groups to your federation by sending \`/joinfed ${msg.from.id}\` in each group.\n\nIt is highly reccomended to create a notification channel for your federation with \`/setfedchannel\` so moderation can easily be monitored throughout the federation in one place.`,msg.chat.is_forum? { + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `${langJson[settings.lang].fed.created} ${msg.from.id}\``,msg.chat.is_forum? { message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'}:{parse_mode: 'Markdown'})}catch{}}); } diff --git a/lib/telegram/commands/report.ts b/lib/telegram/commands/report.ts index 0d2bf65..38c4dea 100644 --- a/lib/telegram/commands/report.ts +++ b/lib/telegram/commands/report.ts @@ -3,14 +3,11 @@ import {setInviteURL, getInviteURL, getRule,getAllowance, setAllowance, addRepor import { groupSettings } from "../../../types"; import {upload} from "./addEvidence" import {reportUser} from "../../bot-core"; -import langJson from "../assets/lang.json"; -const Web3 = require('web3') -const web3 = new Web3(process.env.WEB3_PROVIDER_URL) +import langJson from "../assets/langNew.json"; /* * /report */ -const ob = require('urbit-ob') const regexp = /\/report\s?(.+)?/ // cacheIndex => groupID,reported message id => [pending report message id] const NodeCache = require( "node-cache" ); @@ -35,16 +32,22 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b if (!myQueue) myQueue = queue if (!msg.reply_to_message) { - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `/report ${langJson[settings.lang].errorReply}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].error.reply, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) return val}catch{}}); if (!resp) return resp myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return; } + const channelUserSusie = await queue.add(async () => {try{const val = await bot.getChatMember(msg.chat.id, botId) + return val}catch(e){console.log(e)}}); + if(!channelUserSusie) + return + + const isAdmin = channelUserSusie.status === "administrator" - if (msg.reply_to_message.date < Date.now()/1000-86400*7){ - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `Live and let live. This message is more than one week old. The future is asynchronous, but we believe moderation should not be punitive. Next time try to make the report sooner.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + if (isAdmin && msg.reply_to_message.date < Date.now()/1000-86400*7){ + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].report.expired, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) return val}catch{}}); if (!resp) return resp @@ -57,10 +60,10 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b if (msg.reply_to_message.from.is_bot){ let resp; if(msg.reply_to_message.from.username === "GroupAnonymousBot") - resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `User is anonymous. Ask admins to disable anonymouse admins to moderate admin behavior.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].report.anon, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) return val}catch{}}); else - resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.errorModBot}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.bot}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) return val}catch{}}); if (!resp) return resp @@ -71,11 +74,11 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b if(!settings.admin_reportable){ report = await queue.add(async () => {try{const val = await bot.getChatMember(msg.chat.id,msg.reply_to_message.from.id) return val}catch{}}) - if (!report) - return report + if (!report) + return if(report.status === "administrator" || report.status === "creator"){ - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.errorAdmin}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) - return val}catch{}}); + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.admin}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + return val}catch(e){console.log(e)}}); if (!resp) return resp myCacheGarbageCollection.set(resp.message_id, msg.chat.id) @@ -95,9 +98,12 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return; }*/ - const reportedQuestionId = getQuestionId(db, 'telegram', String(msg.chat.id), reportedUserID, String(msg.reply_to_message.message_id)); + const msgId = (msg.chat.is_forum? (msg.is_topic_message? String(msg.message_thread_id)+'/': '1/') : '')+String(msg.reply_to_message.message_id) + + const reportedQuestionId = getQuestionId(db, 'telegram', String(msg.chat.id), reportedUserID, msgId); if (reportedQuestionId){ - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.reported}(https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${reportedQuestionId})`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true}) + console.log(msg) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.reported}(https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${reportedQuestionId})`, (msg.is_topic_message)? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true}) return val}catch{}}); if (!resp) return resp @@ -106,8 +112,7 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b } - - const rules = getRule(db, 'telegram', String(msg.chat.id), msg.reply_to_message.date); + const rules = getRule(db, 'telegram', String(msg.chat.id), isAdmin ? msg.reply_to_message.date: Math.floor(Date.now()/1000))?.rules; if (!rules){ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].report.norules, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) @@ -127,17 +132,17 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b const msgBackup = 'https://ipfs.kleros.io'+evidencepath; // TODO report const reportAllowance = getAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id)); + console.log(reportAllowance) const reporter = await queue.add(async () => {try{const val = await bot.getChatMember(msg.chat.id,msg.from.id) - return val}catch{}}) - if (!reporter) - return reporter - if(!settings.admin_reportable && (reporter.status === "administrator" || reporter.status === "creator")){ - console.log(report.status) + return val}catch(e){console.log(e)}}) + if((reporter.status === "administrator" || reporter.status === "creator")){ + console.log(reporter.status) } else if (!reportAllowance){ setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), 2, 15, currentTimeMs); } else if (currentTimeMs < reportAllowance.timestamp_refresh + 28800 && reportAllowance.report_allowance == 0 ){ - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].report.noallowance, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) - return val}catch{}}); + console.log(msg) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].report.noallowance, (msg.chat.is_forum && msg.is_topic_message)? String(msg.message_thread_id): {}) + return val}catch (e){console.log(e)}}); if (!resp) return resp myCacheGarbageCollection.set(resp.message_id, msg.chat.id) @@ -148,6 +153,8 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b const newRefreshTimestamp = reportAllowance.timestamp_refresh + Math.floor((currentTimeMs - reportAllowance.timestamp_refresh)/28800)*28800; setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), Math.min(newReportAllowance,3), Math.min(newEvidenceAllowance,15), newRefreshTimestamp); } + console.log(msg) + console.log(msgId) const opts = { parse_mode: 'Markdown', reply_to_message_id: msg.reply_to_message.message_id, @@ -158,7 +165,7 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b [ { text: langJson[settings.lang].socialConsensus.confirm + ' (1/3)', - callback_data: '2|'+String(msg.reply_to_message.from.id)+'|'+String(msg.reply_to_message.message_id)+'|'+String(msg.from.id) + callback_data: '2|'+String(msg.reply_to_message.from.id)+'|'+msgId+'|'+String(msg.reply_to_message.date)+'|'+String(msg.from.id) } ] ] @@ -176,10 +183,29 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b console.log(e) } } -const reportMsg = async (queue: any, settings: groupSettings, db: any, bot: any, msg: any, fromUsername: string, reportedUserID: string, rules: string, msgId: string, msgBackup: string, reportedBy: string, batchedSend: any) => { +const reportMsg = async (queue: any, settings: groupSettings, db: any, bot: any, msg: any, fromUsername: string, reportedUserID: string, rules: string, msgId: string, msgBackup: string, reportedBy: string, msgDate: string, batchedSend: any) => { try { - var inviteURL = myCache.get(msg.chat.id) - if (!inviteURL){ + + const reportedQuestionId = getQuestionId(db, 'telegram', String(msg.chat.id), reportedUserID, msgId); + if (reportedQuestionId){ + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.reported}(https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${reportedQuestionId})`, (msg.chat.is_forum && msg.is_topic_message)? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true}) + return val}catch{}}); + if (!resp) + return resp + myCacheGarbageCollection.set(resp.message_id, msg.chat.id) + return; + } + + const chatobj = await queue.add(async () => {try{const val = await bot.getChat(msg.chat.id) + return val}catch{}}); + if (!chatobj) + return + const isPrivate: boolean = !chatobj.active_usernames; + var inviteURL = isPrivate ? '': myCache.get(msg.chat.id) + if (!isPrivate && !inviteURL){ + inviteURL = 'https://t.me/'+chatobj.active_usernames[0] + // TODO Handle private, but invites allowed + /* inviteURL = getInviteURL(db, 'telegram', String(msg.chat.id)); if (!inviteURL){ inviteURL = await queue.add(async () => {try{const val = await bot.exportChatInviteLink(msg.chat.id) @@ -188,21 +214,18 @@ const reportMsg = async (queue: any, settings: groupSettings, db: any, bot: any, return setInviteURL(db, 'telegram', String(msg.chat.id), inviteURL); } + */ myCache.set(msg.chat.id, inviteURL) } - const msgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/'+`${msg.chat.is_forum? msg.is_topic_message? msg.message_thread_id: 1 : ''}/`+msg.reply_to_message.message_id; + const msgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + `/${msgId}`; const cachedEvidenceIndex = myCache.get("evidence"+msg.chat.id); const evidenceIndex = cachedEvidenceIndex? cachedEvidenceIndex+1:getRecordCount(db, 'telegram', String(msg.chat.id))+1 myCache.set("evidence"+msg.chat.id, evidenceIndex); - const chatobj = await queue.add(async () => {try{const val = await bot.getChat(msg.chat.id) - return val}catch{}}); - if (!chatobj) - return - const isPrivate: boolean = !chatobj.active_usernames; - const {questionId, questionUrl: appealUrl} = await reportUser( + + const {questionId, questionUrl: appealUrl} = reportUser( batchedSend, settings.lang, false, @@ -218,14 +241,17 @@ const reportMsg = async (queue: any, settings: groupSettings, db: any, bot: any, reportedBy, isPrivate); - addReport(db, questionId, 'telegram', String(msg.chat.id), reportedUserID, fromUsername , (msg.chat.is_forum? `${msg.message_thread_id}/`:'')+String(msg.reply_to_message.message_id), msg.reply_to_message.date,evidenceIndex, msgBackup); - - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `[${fromUsername}](tg://user?id=${reportedUserID})'s conduct due to this [message](${msgLink}) ([backup](${msgBackup})) is reported for breaking the [rules](${rules}).\n\nDid *${fromUsername}* break the rules? The [question](${appealUrl}) can be answered with a minimum bond of 5 DAI. Need assistance answering the question? [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpgnosis) me for help : )\n\nTo save a record, reply to messages you want saved with \`/evidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: settings.thread_id_notifications , parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + addReport(db, questionId, 'telegram', String(msg.chat.id), reportedUserID, fromUsername , msgId, Number(msgDate),evidenceIndex, msgBackup); + console.log(msgLink) + if (settings.lang === "en") + queue.add(async () => {try{bot.sendMessage(settings.channelID, `[${fromUsername}](tg://user?id=${reportedUserID})'s conduct due to this [message](${msgLink}) ([backup](${msgBackup})) is reported for breaking the [rules](${rules}).\n\nDid *${fromUsername}* break the rules? The [question](${appealUrl}) can be answered with a minimum bond of 5 DAI. Need assistance answering the question? [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpgnosis) me for help : )\n\nTo save a record, reply to messages you want saved with \`/evidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: settings.thread_id_notifications , parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + else if (settings.lang === "es") + queue.add(async () => {try{bot.sendMessage(settings.channelID, `La conducta de [${fromUsername}](tg://user?id=${reportedUserID}) a este [mensaje](${msgLink}) ([backup](${msgBackup})) es denunciada por infringir las [reglas](${rules}).\n\nHa infringido el usuario *${fromUsername}* las reglas? La [pregunta](${appealUrl}) puede responderse con un bono mínimo de 5 DAI. Necesitas ayuda para responder a la pregunta? [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpgnosis) me para obetener ayuda : )\n\nPara guardar un registro, responda a los mensajes que desee guardar con \`/evidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: settings.thread_id_notifications , parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); return questionId; } catch (e) { console.log(e); try{ - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].errorTxn}. ${e.reason}. `,msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].error.txn}. ${e.reason}. `,msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {})}catch{}}); } catch(e){ console.log(e) } diff --git a/lib/telegram/commands/setChannel.ts b/lib/telegram/commands/setChannel.ts index 4c8b561..ffec88f 100644 --- a/lib/telegram/commands/setChannel.ts +++ b/lib/telegram/commands/setChannel.ts @@ -1,7 +1,7 @@ import * as TelegramBot from "node-telegram-bot-api"; import {groupSettings} from "../../../types"; import {setChannelID, setInviteURLChannel} from "../../db"; -import langJson from "../assets/lang.json"; +import langJson from "../assets/langNew.json"; const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); var myBot; @@ -28,7 +28,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: Teleg myQueue = queue const newmatch = msg.text.match(regexpFull); if (!newmatch || newmatch.length < 2){ - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `/setchannel must be followed by a channel id. [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpnotifications) me if you need more help : )`, {parse_mode: "Markdown", disable_web_page_preview: true}) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].notifications.set} [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpnotifications) me : )`, {parse_mode: "Markdown", disable_web_page_preview: true}) return val}catch{}}); if(!resp) return @@ -41,7 +41,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: Teleg if(!channel) return if(channel.type !== "channel"){ - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, '/setchannel must be followed by a valid channel.') + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].notifications.invalid) return val}catch{}}); if(!resp) return @@ -50,7 +50,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: Teleg } } catch(e){ try{ - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${newmatch[1]} is not a valid channel.`) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${newmatch[1]} ${langJson[settings.lang].notifications.invalid2}`) return val}catch{}}); if(!resp) return @@ -65,7 +65,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: Teleg if(!channelUser) return if(channelUser.status !== "administrator" && channelUser.status !== "creator"){ - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, 'You are not an authorized admin of the channel.') + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].notifications.admin) return val}catch{}}); if(!resp) return @@ -85,7 +85,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: Teleg return; } if(!channelUserSusie.can_invite_users){ - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, 'Susie must be able to invite users to the channel.') + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].notifications.invite) return val}catch{}}); if(!resp) return @@ -98,8 +98,8 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: Teleg return setInviteURLChannel(db, 'telegram', String(msg.chat.id), invite_url_channel); setChannelID(db, 'telegram', String(msg.chat.id), newmatch[1]); - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `Moderation notifications will now be sent to this [channel](${invite_url_channel}).`, {parse_mode: "Markdown", disable_web_page_preview: true})}catch{}}); - queue.add(async () => {try{await bot.sendMessage(newmatch[1], `This channel will now relay moderation notifications for ${msg.chat.title}`, {parse_mode: "Markdown"})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].notifications.confirm1}(${invite_url_channel}).`, {parse_mode: "Markdown", disable_web_page_preview: true})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(newmatch[1], `${langJson[settings.lang].notifications.confirm2} ${msg.chat.title}`, {parse_mode: "Markdown"})}catch{}}); } catch (error) { console.log(error); } diff --git a/lib/telegram/commands/setChannelFed.ts b/lib/telegram/commands/setChannelFed.ts index abec3e4..ac4dada 100644 --- a/lib/telegram/commands/setChannelFed.ts +++ b/lib/telegram/commands/setChannelFed.ts @@ -2,7 +2,7 @@ import * as TelegramBot from "node-telegram-bot-api"; import {groupSettings} from "../../../types"; import {setFederationChannelID, setFederationInviteURLChannel,getFederationName} from "../../db"; import {validateUrl} from "./setRules"; -import langJson from "../assets/lang.json"; +import langJson from "../assets/langNew.json"; const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); var myBot; @@ -25,7 +25,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, myQueue = queue const name = getFederationName(db,'telegram',String(msg.from.id)) if (!name){ - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `No federation found. Please first create a federation with \`/newfed\``,msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown', disable_web_page_preview: true} : {parse_mode: 'Markdown', disable_web_page_preview: true}) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].fed.notfound2,msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown', disable_web_page_preview: true} : {parse_mode: 'Markdown', disable_web_page_preview: true}) return val}catch{}}); if(!resp) return @@ -35,7 +35,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, const newmatch = msg.text.match(regexpFull); if (!newmatch || newmatch.length < 2){ console.log(msg) - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `/setchannelfed must be followed by a channel id. [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpnotifications) me if you need more help : )`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown', disable_web_page_preview: true} : {parse_mode: 'Markdown', disable_web_page_preview: true}) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].fed.specify2} [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpnotifications) me : )`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown', disable_web_page_preview: true} : {parse_mode: 'Markdown', disable_web_page_preview: true}) return val}catch{}}); if(!resp) return @@ -48,7 +48,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, if(!channel) return if(channel.type !== "channel"){ - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, '/setchannelfed must be followed by a valid channel.', msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].fed.invalid, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) return val}catch{}}); if(!resp) return @@ -57,7 +57,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, } } catch(e){ try{ - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${newmatch[1]} is not a valid channel.`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${newmatch[1]} ${langJson[settings.lang].fed.invalid2}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) return val}catch{}}); if(!resp) return @@ -72,7 +72,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, if(!channelUser) return if(channelUser.status !== "administrator" && channelUser.status !== "creator"){ - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, 'You are not an authorized admin of the channel.',msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].fed.auth,msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) return val}catch{}}); if(!resp) return @@ -92,7 +92,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, return; } if(!channelUserSusie.can_invite_users){ - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, 'Susie must be able to invite users to the channel.',msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].notifications.invite,msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: 'Markdown'} : {parse_mode: 'Markdown'}) return val}catch{}}); if(!resp) return @@ -105,8 +105,8 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, return setFederationInviteURLChannel(db, 'telegram', String(msg.from.id), invite_url_channel); setFederationChannelID(db, 'telegram', String(msg.from.id), newmatch[1]); - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `Moderation notifications for the federation will now be sent to this [channel](${invite_url_channel}).`, {parse_mode: "Markdown"})}catch{}}); - queue.add(async () => {try{await bot.sendMessage(newmatch[1], `This channel will now relay moderation notifications for the federation *${name}*`, {parse_mode: "Markdown"})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].fed.confirm1}(${invite_url_channel}).`, {parse_mode: "Markdown"})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(newmatch[1], `${langJson[settings.lang].fed.confirm2} *${name}*`, {parse_mode: "Markdown"})}catch{}}); } catch (error) { console.log(error); } diff --git a/lib/telegram/commands/setLanguage.ts b/lib/telegram/commands/setLanguage.ts index 8e281cb..4e85461 100644 --- a/lib/telegram/commands/setLanguage.ts +++ b/lib/telegram/commands/setLanguage.ts @@ -1,61 +1,65 @@ import * as TelegramBot from "node-telegram-bot-api"; import {setLang, setRules} from "../../db"; -import langJson from "../assets/lang.json"; +import langJson from "../assets/langNew.json"; import { groupSettings } from "../../../types"; /* * /setlanguage ? */ -const regexp = /\/setlanguage/ -const regexpFull = /\/setlanguage (.+)/ +const regexp = /\/lang/ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { - const match = msg.text.match(regexpFull); - const langCode = match? match[1].toLowerCase(): ''; - - if (langJson[langCode]) { - setLanguageConfirm(queue, db, bot, settings, langCode, msg) - } else { - const errorLanguage = `The language you requested is not yet available. Head to @KlerosModerateNews or @linguoKleros for information on how to add more translations!` - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, errorLanguage, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {})}catch{}}) - const opts = msg.chat.is_forum? { - message_thread_id: msg.message_thread_id, - parse_mode: 'Markdown', - reply_markup: { - inline_keyboard: [ + const opts = msg.chat.is_forum? { + message_thread_id: msg.message_thread_id, + parse_mode: 'Markdown', + reply_markup: { + inline_keyboard: [ [ { text: 'English', callback_data: `0|${msg.from.id}`+'|'+`en` } + ], + [ + { + text: 'Español', + callback_data: `0|${msg.from.id}`+'|'+`es` + } ] - ] - } - }: { - parse_mode: 'Markdown', - reply_markup: { - inline_keyboard: [ + ] + } + }: { + parse_mode: 'Markdown', + reply_markup: { + inline_keyboard: [ [ { text: 'English', callback_data: `0|${msg.from.id}`+'|'+`en` } + ], + [ + { + text: 'Español', + callback_data: `0|${msg.from.id}`+'|'+`es` + } ] - ] - } + ] } - queue.add(async () => {try{await bot.sendMessage(msg.chat.id,'List of available languages',opts)}catch{}}) } + queue.add(async () => {try{await bot.sendMessage(msg.chat.id,langJson[settings.lang].lang.select,opts)}catch{}}) } const setLanguageConfirm = async (queue: any, db: any, bot: any, settings: groupSettings, langCode: string, msg: any) => { try{ queue.add(async () => {try{await bot.deleteMessage(msg.chat.id, String(msg.message_id))}catch{}}) + if (settings.lang == langCode) + return; setLang(db, 'telegram', String(msg.chat.id),langCode); setRules(db, 'telegram', String(msg.chat.id), langJson[langCode].defaultRules, Math.floor(Date.now()/1000)); - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[langCode].confirmationLanguage, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[settings.lang].lang.confirm, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {})}catch{}}); + const msgDefaultRules = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[langCode].lang.rules}(${langJson[langCode].defaultRules}). ${langJson[langCode].lang.setrules}.`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: settings.thread_id_rules}: {parse_mode: "Markdown"}) + return val}catch{}}); if (msg.chat.is_forum){ - const msgDefaultRules = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[langCode].defaultRulesMsg1}(${langJson[langCode].defaultRules}). ${langJson[langCode].defaultRulesMsg2}.`, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: settings.thread_id_rules}: {}) - return val}catch{}}) if(!msgDefaultRules) return const msgRules = await queue.add(async () => {try{const val = await bot.forwardMessage(msg.chat.id, msg.chat.id, msgDefaultRules.message_id, {message_thread_id: settings.thread_id_rules}) diff --git a/lib/telegram/commands/setRules.ts b/lib/telegram/commands/setRules.ts index ed8bce4..8038263 100644 --- a/lib/telegram/commands/setRules.ts +++ b/lib/telegram/commands/setRules.ts @@ -1,6 +1,6 @@ import * as TelegramBot from "node-telegram-bot-api"; import { groupSettings } from "../../../types"; -import {setRules} from "../../db"; +import {setRulesCustom} from "../../db"; import {ipfsPublish} from "../../ipfs-publish"; import langJson from "../assets/lang.json"; @@ -23,8 +23,11 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, if (msg.reply_to_message && !msg.reply_to_message.forum_topic_created) { const enc = new TextEncoder(); const rulesPath = await ipfsPublish('rules.txt', enc.encode(msg.reply_to_message.text)) - setRules(db, 'telegram', String(msg.chat.id), 'https://ipfs.kleros.io'+rulesPath, new Date().getTime()/1000); - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `The community rules are [updated](https://ipfs.kleros.io${rulesPath}).`, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules, parse_mode: 'Markdown'}: {parse_mode: "Markdown"})}catch{}}); + const msg_id = msg.chat.is_forum? msg.is_topic_message? msg.message_thread_id: 1 : ''+msg.reply_to_message.message_id; + const MsgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + msg_id; + + setRulesCustom(db, 'telegram', String(msg.chat.id), 'https://ipfs.kleros.io'+rulesPath, Math.floor(Date.now()/1000), msg_id); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].rulesUpdated}(https://ipfs.kleros.io${rulesPath}).`, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules, parse_mode: 'Markdown'}: {parse_mode: "Markdown"})}catch{}}); if(msg.chat.is_forum){ const msgRules = await queue.add(async () => {try{const val = await bot.forwardMessage(msg.chat.id, msg.chat.id, msg.reply_to_message.message_id, {message_thread_id: settings.thread_id_rules}) return val}catch{}}); @@ -33,7 +36,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, queue.add(async () => {try{await bot.pinChatMessage(msg.chat.id, msgRules.message_id, {message_thread_id: settings.thread_id_rules})}catch{}}) } } else if (validateUrl(match[1])) { - setRules(db, 'telegram', String(msg.chat.id), match[1], Math.floor(new Date().getTime()/1000)); + setRulesCustom(db, 'telegram', String(msg.chat.id), match[1], Math.floor(new Date().getTime()/1000), null); if(msg.chat.is_forum){ const msgRules = await queue.add(async () => {try{const val = await bot.forwardMessage(msg.chat.id, msg.chat.id, msg.message_id, {message_thread_id: settings.thread_id_rules}) return val}catch{}}); @@ -43,9 +46,9 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, await queue.add(async () => {try{await bot.pinChatMessage(msg.chat.id, msgRules.message_id, {message_thread_id: settings.thread_id_rules})}catch{}}) await queue.add(async () => {try{await bot.closeForumTopic(msg.chat.id, settings.thread_id_rules)}catch{}}) } - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[settings.lang].rulesUpdated, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules}: {})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].rulesUpdated}(${match[1]})`, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); } else { - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[settings.lang].errorRules, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules}: {})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[settings.lang].error.url, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules}: {})}catch{}}); } } catch(e){ console.log(e) diff --git a/lib/telegram/commands/socialConsensus.ts b/lib/telegram/commands/socialConsensus.ts index 544bc0d..2553675 100644 --- a/lib/telegram/commands/socialConsensus.ts +++ b/lib/telegram/commands/socialConsensus.ts @@ -1,7 +1,7 @@ import * as TelegramBot from "node-telegram-bot-api"; import { getQuestionId } from "../../graph"; import {reportMsg} from "./report"; -import langJson from "../assets/lang.json"; +import langJson from "../assets/langNew.json"; import { groupSettings } from "../../../types"; const escape = require('markdown-escape') import {Wallet} from "@ethersproject/wallet"; @@ -19,11 +19,12 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: Teleg const calldata = rawCalldata.split('|'); const match = callbackQuery.message.reply_markup.inline_keyboard[0][0].text; const msg: any = callbackQuery.message; - const newConfirmations = Number(match.substring(9,10)) + 1; + const newConfirmations = Number(match.substring(match.length - 4,match.length-3)) + 1; + console.log(newConfirmations) - if (callbackQuery.from.id == Number(calldata[3])) + if (callbackQuery.from.id == Number(calldata[4])) return; - //if (calldata.length > 4 && callbackQuery.from.id == Number(calldata[4])) + //if (calldata.length > 5 && callbackQuery.from.id == Number(calldata[5])) // return; const markdown = { @@ -44,6 +45,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: Teleg message_id: msg.message_id, message_thread_id: msg.message_thread_id } + const optsFinal = msg.chat.is_forum? { chat_id: msg.chat.id, message_id: msg.message_id @@ -55,11 +57,11 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: Teleg try{ if (newConfirmations > 1){ queue.add(async () => {try{await bot.editMessageReplyMarkup({ inline_keyboard: []}, optsFinal)}catch{}}) - queue.add(async () => {try{await bot.editMessageText("User Reported.",optsFinal)}catch{}}) + queue.add(async () => {try{await bot.editMessageText(settings.lang === "en"? "User reported." : "Usuario reportado.",optsFinal)}catch{}}) const user = (await queue.add(async () => {try{const val = await bot.getChatMember(String(msg.chat.id), String(calldata[1])) return val}catch{}})).user; const fromUsername = user.username || user.first_name || `no-username-set`; - reportMsg(queue, settings, db, bot, msg, fromUsername, String(calldata[1]), msg.entities[1].url, String(calldata[2]), msg.entities[3].url, calldata[3],batchedSend); + reportMsg(queue, settings, db, bot, msg, fromUsername, String(calldata[1]), msg.entities[1].url, String(calldata[2]), msg.entities[3].url, calldata[4],calldata[3],batchedSend); } else{ queue.add(async () => {try{await bot.editMessageReplyMarkup(markdown, opts)}catch{}}) } diff --git a/lib/telegram/commands/start.ts b/lib/telegram/commands/start.ts index 0fad356..3793b36 100644 --- a/lib/telegram/commands/start.ts +++ b/lib/telegram/commands/start.ts @@ -1,6 +1,6 @@ import * as TelegramBot from "node-telegram-bot-api"; -import {setThreadID, getThreadIDNotifications, setRules,setTitle} from "../../db"; -import langJson from "../assets/lang.json"; +import {setThreadID, getThreadIDNotifications, setRules,setTitle,setLang} from "../../db"; +import langJson from "../assets/langNew.json"; import {groupSettings} from "../../../types"; const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 180, checkperiod: 240 } ); @@ -21,9 +21,9 @@ const callback = async (queue:any, db: any, settings: groupSettings, bot: any, b myBot = bot if (!myQueue) myQueue = queue + const lang_code = msg?.from?.language_code try{ - const lang_code = msg?.from?.language_code - if (msg.chat.type === "supergroup" && !skip_lang_check && lang_code !== 'en'){ + if (msg.chat.type === "supergroup" && !skip_lang_check && (lang_code !== 'en' && lang_code !== 'es')){ if(myCache.get(msg.chat.id)) return const opts = msg.chat.is_forum? { @@ -54,7 +54,7 @@ const callback = async (queue:any, db: any, settings: groupSettings, bot: any, b ] } } - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `My native language is English. I am learning new languages, starting with [Spanish](https://linguo.kleros.io/home). Please reach out to @SusieSupport to let me know which language I should learn next.\n\nTo continue, please understand that I can currently only effectively moderate communities in English.`, opts) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `I speak English and Spanish. Please reach out to @SusieSupport to let me know which language I should learn next.\n\nTo continue, please understand that I can currently only effectively moderate communities in English or Spanish.`, opts) return val}catch{}}) if(!resp) return @@ -70,18 +70,14 @@ const callback = async (queue:any, db: any, settings: groupSettings, bot: any, b inline_keyboard: [ [ { - text: 'Add me to your group!', + text: langJson[lang_code].start.add, url: `https://t.me/${process.env.BOT_USERNAME}?startgroup=botstart` } ] ] } } - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `Hi! My name is Susie, nice to meet you : ) - -I am a [Kleros Moderate](https://kleros.io/moderate) community manager at your service. Use /help to learn how to use me to my full potential. - -Join my news channel @KlerosModerateNews to get information on all the latest updates.`, opts)}catch{}}) + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[lang_code].start.private, opts)}catch{}}) return; } @@ -89,40 +85,36 @@ Join my news channel @KlerosModerateNews to get information on all the latest up return val}catch{}}) if(!botUser) return - if(botUser.status !== "administrator" || !botUser.can_restrict_members){ + /*if(botUser.status !== "administrator" || !botUser.can_restrict_members){ const video = msg.chat.is_forum? 'QmSdP3SDoHCdW739xLDBKM3gnLeeZug77RgwgxBJSchvYV/guide_topics.mp4' : 'QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4' - queue.add(async () => {try{await bot.sendVideo(msg.chat.id, `https://ipfs.kleros.io/ipfs/${video}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, caption: "Please give Susie full admin rights.\n\nThen try to /start community moderation again."} : {caption: "Please give Susie full admin rights.\n\nThen try to /start community moderation again."})}catch{}}); - return; - } + //queue.add(async () => {try{await bot.sendVideo(msg.chat.id, `https://ipfs.kleros.io/ipfs/${video}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, caption: ""} : {caption: "Please give Susie full admin rights.\n\nThen try to /start community moderation again."})}catch{}}); + //return; + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, 'I am ', msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id, disable_web_page_preview: true}: {parse_mode: "Markdown", disable_web_page_preview: true})}catch{}}) + }*/ if (msg.chat.is_forum){ if(!botUser.can_manage_topics){ - - queue.add(async () => {try{await bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmSdP3SDoHCdW739xLDBKM3gnLeeZug77RgwgxBJSchvYV/guide_topics.mp4', {message_thread_id: msg.message_thread_id, caption: "Susie needs permissions to manage topics to effectively moderate your community.\n\nThen try to /start community moderation again."})}catch{}}); + queue.add(async () => {try{await bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmSdP3SDoHCdW739xLDBKM3gnLeeZug77RgwgxBJSchvYV/guide_topics.mp4', {message_thread_id: msg.message_thread_id, caption: langJson[lang_code].index.topicError})}catch{}}); return; } const thread_ids = getThreadIDNotifications(db, 'telegram', String(msg.chat.id)); if (thread_ids){ - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, "Already started.", {message_thread_id: msg.message_thread_id})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[lang_code].start.already, {message_thread_id: msg.message_thread_id})}catch{}}); return } - await topicMode(queue, db,bot,settings,msg.chat); + const threads = await topicMode(queue, db,bot,settings,msg); + if (!threads) + return } - console.log(msg.chat.id) - //setTitle(db, 'telegram', String(msg.chat.id), msg.chat.title) - setRules(db, 'telegram', String(msg.chat.id), langJson[settings.lang].defaultRules, Math.floor(Date.now()/1000)); - const msg_start = `Hi! My community moderation tools are at your service. [DM](https://t.me/${process.env.BOT_USERNAME}?start=help) me to find out more about how to use me to my full potential : ) - - - Use /setrules to change the default [rules](${langJson[settings.lang].defaultRules}). - - User reports are made by replying to a message with /report - - Penalties progress from 1 day to 1 week, and 1 year bans for each violation.`; + setTitle(db, 'telegram', String(msg.chat.id), msg.chat.title) + setRules(db, 'telegram', String(msg.chat.id), langJson[lang_code].defaultRules, Math.floor(Date.now()/1000)); + setLang(db, 'telegram', String(msg.chat.id),lang_code); + const msg_start = `${langJson[lang_code].start.start1}(https://t.me/${process.env.BOT_USERNAME}?start=help)${langJson[lang_code].start.start2}(${langJson[lang_code].defaultRules}).${langJson[lang_code].start.start3}` queue.add(async () => {try{await bot.sendMessage(msg.chat.id, msg_start, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id, disable_web_page_preview: true}: {parse_mode: "Markdown", disable_web_page_preview: true})}catch{}}) return; } catch (e){ try{ if (msg.chat.is_forum){ - queue.add(async () => {try{await bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmSdP3SDoHCdW739xLDBKM3gnLeeZug77RgwgxBJSchvYV/guide_topics.mp4', {message_thread_id: msg.message_thread_id, caption: "Must have can manage topics"})}catch{}}); - } else{ - queue.add(async () => {try{await bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', {caption: langJson[settings.lang].errorAdminRights+"Topics must be enabled"})}catch{}}); + queue.add(async () => {try{await bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmSdP3SDoHCdW739xLDBKM3gnLeeZug77RgwgxBJSchvYV/guide_topics.mp4', {message_thread_id: msg.message_thread_id, caption: langJson[lang_code].error.topic})}catch{}}); } } catch (e){ console.log(e) @@ -130,19 +122,27 @@ Join my news channel @KlerosModerateNews to get information on all the latest up } } -const topicMode = async (queue: any, db:any, bot: any, settings: groupSettings, chat: TelegramBot.Chat): Promise<[string,string]> => { +const topicMode = async (queue: any, db:any, bot: any, settings: groupSettings, msg: TelegramBot.Message): Promise<[string,string]> => { // tg bugging, won't display icon_color if set - const topicRules = await queue.add(async () => {try{const val = await bot.createForumTopic(chat.id, 'Rules', {icon_custom_emoji_id: '5357193964787081133'}) + const lang_code = msg?.from?.language_code + const topicRules = await queue.add(async () => {try{const val = await bot.createForumTopic(msg.chat.id, lang_code == "en" ? 'Rules': 'Reglas')//, {icon_custom_emoji_id: '5357193964787081133'}) + return val}catch(e){console.log(e)}}); + const topicModeration = await queue.add(async () => {try{const val = await bot.createForumTopic(msg.chat.id, lang_code == "en" ? 'Notifications' : 'Notificaciones')//, {icon_custom_emoji_id: '5417915203100613993'}) return val}catch(e){console.log(e)}}); - const topicModeration = await queue.add(async () => {try{const val = await bot.createForumTopic(chat.id, 'Moderation Notifications', {icon_custom_emoji_id: '5417915203100613993'}) - return val}catch{}}); if(!topicRules || !topicModeration) return - await queue.add(async () => {try{await bot.sendMessage(chat.id, `This community is moderated according to these [rules](${settings.rules}).\n\nMisconduct can be reported with \`/report\`.\n\nIf confirmed, penalties escalate from 1 day to 1 week and finally 1 year bans.`, {parse_mode: "Markdown", message_thread_id: topicRules.message_thread_id})}catch{}}); + + if(lang_code === "en"){ + await queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `This community is moderated according to these [rules](${settings.rules}).\n\nMisconduct can be reported with \`/report\`.`, {parse_mode: "Markdown", message_thread_id: topicRules.message_thread_id})}catch{}}); //bot.sendMessage(chat_id, `${langJson[settings.lang].greeting2}(${settings.rules}). ${langJson[settings.lang].greeting3}`, {parse_mode: "Markdown", message_thread_id: topicRules.message_thread_id}); - await queue.add(async () => {try{await bot.sendMessage(chat.id, `${langJson[settings.lang].greeting1}[Kleros Moderate](https://kleros.io/moderate/).`, {parse_mode: "Markdown", message_thread_id: topicModeration.message_thread_id})}catch{}}); - queue.add(async () => {try{await bot.closeForumTopic(chat.id, topicRules.message_thread_id)}catch{}}) - setThreadID(db,'telegram',String(chat.id),String(topicRules.message_thread_id), String(topicModeration.message_thread_id)) + await queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `Welcome, this group is moderated with [Kleros Moderate](https://kleros.io/moderate/).`, {parse_mode: "Markdown", message_thread_id: topicModeration.message_thread_id})}catch{}}); + } else { + await queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `Esta comunidad está moderada de acuerdo con las siguientes [reglas](${settings.rules}).\n\nLas faltas pueden denunciarse con \`/report\`.`, {parse_mode: "Markdown", message_thread_id: topicRules.message_thread_id})}catch{}}); + //bot.sendMessage(chat_id, `${langJson[settings.lang].greeting2}(${settings.rules}). ${langJson[settings.lang].greeting3}`, {parse_mode: "Markdown", message_thread_id: topicRules.message_thread_id}); + await queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `Bienvenido, este grupo está moderado con [Kleros Moderate](https://kleros.io/moderate/).`, {parse_mode: "Markdown", message_thread_id: topicModeration.message_thread_id})}catch{}}); + } + queue.add(async () => {try{await bot.closeForumTopic(msg.chat.id, topicRules.message_thread_id)}catch{}}) + setThreadID(db,'telegram',String(msg.chat.id),String(topicRules.message_thread_id), String(topicModeration.message_thread_id)) return [topicRules.message_thread_id, topicModeration.message_thread_id] } diff --git a/lib/telegram/commands/toggleAdminReportable.ts b/lib/telegram/commands/toggleAdminReportable.ts index 8503eb5..c257839 100644 --- a/lib/telegram/commands/toggleAdminReportable.ts +++ b/lib/telegram/commands/toggleAdminReportable.ts @@ -11,7 +11,8 @@ const regexp = /\/adminreportable/ const callback = async (queue, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { try{ setAdminReportableMode(db, 'telegram', String(msg.chat.id),settings.admin_reportable? 0: 1) - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, settings.admin_reportable? "Admins are immune from reports." : "Admins are now held accountable like regular users.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {})}catch{}}); + const msgToggle = settings.lang === "en" ? settings.admin_reportable? "Admins are immune from reports." : "Admins are now held accountable like regular users." : settings.admin_reportable? "Los administradores son inmunes a los informes." : "Los administradores son ahora responsables como los usuarios normales." + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, msgToggle, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {})}catch{}}); } catch(e){ console.log(e) } diff --git a/lib/telegram/commands/toggleCaptcha.ts b/lib/telegram/commands/toggleCaptcha.ts index f22da4f..b86d87f 100644 --- a/lib/telegram/commands/toggleCaptcha.ts +++ b/lib/telegram/commands/toggleCaptcha.ts @@ -11,14 +11,32 @@ const regexp = /\/captcha/ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { try{ - if (msg.chat.is_forum && !settings.thread_id_welcome){ - toggleWelcome.createWelcomeThread(queue, db,settings,bot,msg) + const botUser = await queue.add(async () => {try{const val = await bot.getChatMember(msg.chat.id, botId) + return val}catch{}}) + if(!botUser) + return + if(botUser.status !== "administrator" || !botUser.can_restrict_members){ + const video = msg.chat.is_forum? 'QmSdP3SDoHCdW739xLDBKM3gnLeeZug77RgwgxBJSchvYV/guide_topics.mp4' : 'QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4' + const msgerror = langJson[settings.lang].error.adminbot + queue.add(async () => {try{await bot.sendVideo(msg.chat.id, `https://ipfs.kleros.io/ipfs/${video}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, caption: msgerror} : {caption: msgerror})}catch{}}); + return; + } + if (msg.chat.is_forum){ + if(!botUser.can_manage_topics){ + + queue.add(async () => {try{await bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmSdP3SDoHCdW739xLDBKM3gnLeeZug77RgwgxBJSchvYV/guide_topics.mp4', {message_thread_id: msg.message_thread_id, caption: langJson[settings.lang].error.topics})}catch{}}); + return; + } + if (!settings.thread_id_welcome){ + toggleWelcome.createWelcomeThread(queue, db,settings,bot,msg) + } } setCaptchaMode(db, 'telegram', String(msg.chat.id),settings.captcha? 0: 1) // if toggling on captcha, turn on greetings if (!settings.captcha) setGreetingMode(db, 'telegram', String(msg.chat.id),1) - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, settings.captcha? "Captcha is off." : "Captcha is on.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {})}catch{}}); + const msgcaptcha = settings.captcha? langJson[settings.lang].off : langJson[settings.lang].captcha.on + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, msgcaptcha, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {})}catch{}}); } catch(e){ console.log(e) } diff --git a/lib/telegram/commands/toggleEnforcement.ts b/lib/telegram/commands/toggleEnforcement.ts new file mode 100644 index 0000000..ce02796 --- /dev/null +++ b/lib/telegram/commands/toggleEnforcement.ts @@ -0,0 +1,32 @@ +import * as TelegramBot from "node-telegram-bot-api"; +import {setEnforcementMode} from "../../db"; +import langJson from "../assets/langNew.json"; +import {groupSettings} from "../../../types"; + +/* + * /welcome + */ +const regexp = /\/enforcement/ + +const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { + try{ + const botUser = await queue.add(async () => {try{const val = await bot.getChatMember(msg.chat.id, botId) + return val}catch{}}) + if(!botUser) + return + if(botUser.status !== "administrator" || !botUser.can_restrict_members){ + const video = msg.chat.is_forum? 'QmSdP3SDoHCdW739xLDBKM3gnLeeZug77RgwgxBJSchvYV/guide_topics.mp4' : 'QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4' + const msg_error = langJson[settings.lang].error.adminbot + queue.add(async () => {try{await bot.sendVideo(msg.chat.id, `https://ipfs.kleros.io/ipfs/${video}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, caption: msg_error} : {caption: msg_error})}catch{}}); + return; + } + setEnforcementMode(db, 'telegram', String(msg.chat.id),settings.enforcement? 0: 1) + // if toggling on captcha, turn on greetings + const msg_enforcement = settings.enforcement? langJson[settings.lang].enforcement.off : langJson[settings.lang].enforcement.on + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, msg_enforcement, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {})}catch{}}); + } catch(e){ + console.log(e) + } +} + +export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/toggleWelcome.ts b/lib/telegram/commands/toggleWelcome.ts index 1a07e75..e47de77 100644 --- a/lib/telegram/commands/toggleWelcome.ts +++ b/lib/telegram/commands/toggleWelcome.ts @@ -14,18 +14,20 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, await createWelcomeThread(queue, db, settings,bot,msg) } setGreetingMode(db, 'telegram', String(msg.chat.id),settings.greeting_mode? 0: 1) - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, settings.greeting_mode? "Welcome messages are off." : "Welcome messages are on.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {})}catch{}}); + const msg_welcome = settings.lang === "en" ? settings.greeting_mode? "Welcome messages are off." : "Welcome messages are on." : settings.greeting_mode? "Los mensajes de bienvenida están desactivados." : "Los mensajes de bienvenida están encendidos." + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, msg_welcome, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {})}catch{}}); } catch(e){ console.log(e) } } const createWelcomeThread = async (queue:any, db: any, settings: groupSettings, bot: any, msg: any) => { - const topicWelcome = await queue.add(async () => {try{const val = await bot.createForumTopic(msg.chat.id, 'Welcome', {icon_custom_emoji_id: '4929292553544531969'}) + const topicWelcome = await queue.add(async () => {try{const val = await bot.createForumTopic(msg.chat.id, settings.lang === "en" ? 'Bienvenidos' : 'Welcome', {icon_custom_emoji_id: '4929292553544531969'}) return val}catch{}}); if(!topicWelcome) return - const msg1: TelegramBot.Message = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].greeting1}[Kleros Moderate](https://kleros.io/moderate/).\n\nPlease treat this group with the same respect you would a public park. We, too, are a shared community resource — a place to share.`, {parse_mode: "Markdown", message_thread_id: topicWelcome.message_thread_id}) + const msg_welcome = settings.lang === "en" ? `Welcome, this group is moderated with [Kleros Moderate](https://kleros.io/moderate/).` : "Bienvenido, este grupo está moderado con [Kleros Moderate](https://kleros.io/moderate/)." + const msg1: TelegramBot.Message = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, msg_welcome, {parse_mode: "Markdown", message_thread_id: topicWelcome.message_thread_id}) return val}catch{}}); if(!msg1) return diff --git a/lib/telegram/commands/welcome.ts b/lib/telegram/commands/welcome.ts index f344a23..1e43021 100644 --- a/lib/telegram/commands/welcome.ts +++ b/lib/telegram/commands/welcome.ts @@ -1,6 +1,8 @@ import * as TelegramBot from "node-telegram-bot-api"; -import langJson from "../assets/lang.json"; +import langJson from "../assets/langNew.json"; import {groupSettings} from "../../../types"; +import {getMultilangGroup} from "../../db"; + /* * Welcome Message @@ -8,9 +10,11 @@ import {groupSettings} from "../../../types"; const callback = async (queue: any, settings: groupSettings, bot: any, msg: any) => { try { - if (msg.old_chat_member.status !== "left") - return; - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].welcome}[Kleros Moderate](https://kleros.io/moderate/) bot. \n\n/start to begin community sourced moderation.`, msg.chat.is_forum? {parse_mode: "Markdown"} : {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"})}catch{}}); +// if (msg.old_chat_member.status !== "left") +// return; + console.log('yoyoyoyoy welcome') + const lang_code = msg?.from?.language_code + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[lang_code].welcome.welcome, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}: {parse_mode: "Markdown"})}catch{}}); //const options = msg.chat.is_forum? {message_thread_id: msg.message_thread_id, caption: "To get started, give Susie admin rights."} : {caption: "To get started, give Susie admin rights."} //bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4', options); } catch (error) { diff --git a/lib/telegram/index.ts b/lib/telegram/index.ts index a6a6bd9..76a3563 100644 --- a/lib/telegram/index.ts +++ b/lib/telegram/index.ts @@ -8,6 +8,7 @@ import * as addEvidenceHelp from "../../lib/telegram/commands/addEvidenceHelp"; import * as report from "../../lib/telegram/commands/report"; import * as fedinfo from "../../lib/telegram/commands/fedinfo"; import * as welcome from "../../lib/telegram/commands/welcome"; +import * as multilang from "../../lib/telegram/commands/multilang"; import * as toggleWelcome from "../../lib/telegram/commands/toggleWelcome"; import * as toggleAdminReportable from "../../lib/telegram/commands/toggleAdminReportable"; import * as greeting from "../../lib/telegram/commands/greeting"; @@ -24,10 +25,9 @@ import * as setChannel from "../../lib/telegram/commands/setChannel"; import * as setChannelFed from "../../lib/telegram/commands/setChannelFed"; import * as getChannel from "../../lib/telegram/commands/getChannel"; import * as getReports from "../../lib/telegram/commands/getReports"; -import langJson from "./assets/lang.json"; +import langJson from "./assets/langNew.json"; import {groupSettings, groupSettingsUnderspecified} from "../../types"; import {openDb, getGroupSettings, getRule, getReportsUserInfoActive,getFederatedBanHistory, getFederatedFollowingBanHistory, getLocalBanHistory, eraseThreadID} from "../db"; -import { calcPenalty } from "../cron"; const Web3 = require('web3') const {default: PQueue} = require('p-queue'); const queue = new PQueue({intervalCap: 20, interval: 1000,carryoverConcurrencyCount: true}); @@ -46,7 +46,7 @@ const batchedSend = _batchedSend( greeting_mode: false, captcha: false, admin_reportable: false, - privacy_mode: true, + enforcement: false, thread_id_rules: '', thread_id_welcome: '', thread_id_notifications: '', @@ -60,6 +60,16 @@ const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: {params: {"al //bot. var botId: number; const db = openDb(); +const exit = async () => { + await db.close() + await bot.stopPolling({ cancel: true }) +} + +['SIGINT', 'SIGTERM', 'SIGQUIT','EXIT'] + .forEach(signal => process.on(signal, async () => { + await exit() + process.exit(); + })); const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 900, checkperiod: 1200 } ); // Throttling @@ -77,15 +87,23 @@ const delay = (delayInms) => { bot.on("my_chat_member", async function(myChatMember: any) { try{ - if(throttled(myChatMember.from.id) || myChatMember.chat.is_forum) + const lang_code = myChatMember?.from?.language_code + console.log(myChatMember) + if(throttled(myChatMember.from.id)) return - const settings = validate(myChatMember.chat); + if(myChatMember.new_chat_member.status === "left"){ + return; + // todo remove rules>? + // stop()? + } + const settings = validate(myChatMember.chat, lang_code); + console.log('HMMMMMM') if(myChatMember.chat.type === "channel"){ await delay(2000); if( myChatMember.new_chat_member.status === "administrator"){ try{ - queue.add(async () => {try{await bot.sendMessage(myChatMember.chat.id, `The channel id is ${myChatMember.chat.id}`, {parse_mode: "HTML"})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(myChatMember.chat.id, langJson[lang_code].index.channel+`${myChatMember.chat.id}`, {parse_mode: "HTML"})}catch{}}); } catch(e) { console.log('channel id msg error'+e); } @@ -98,7 +116,7 @@ bot.on("my_chat_member", async function(myChatMember: any) { else try{ const video = myChatMember.chat.is_forum? 'QmSdP3SDoHCdW739xLDBKM3gnLeeZug77RgwgxBJSchvYV/guide_topics.mp4' : 'QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4' - queue.add(async () => {try{await bot.sendVideo(myChatMember.chat.id, `https://ipfs.kleros.io/ipfs/${video}`, {caption: "Hi! I'm Susie, a moderation and group management bot. Please promote me to an admin then try to /start me to unlock my full potential."})}catch{}}); + queue.add(async () => {try{await bot.sendVideo(myChatMember.chat.id, `https://ipfs.kleros.io/ipfs/${video}`, {caption: langJson[lang_code].index.supergroup})}catch{}}); } catch(e){ console.log(e) } @@ -128,7 +146,7 @@ bot.on("new_chat_members", async function (chatMemberUpdated: any) { if(!hasStarted(chatMemberUpdated.chat.id)||throttled(chatMemberUpdated.from.id)||chatMemberUpdated.chat.type !== "supergroup") return; - const settings = validate(chatMemberUpdated.chat); + const settings = validate(chatMemberUpdated.chat); let calculateHistory = [] if (settings.federation_id) calculateHistory = getFederatedBanHistory(db, 'telegram', String(chatMemberUpdated.new_chat_member.id),settings.federation_id,true) @@ -139,6 +157,8 @@ bot.on("new_chat_members", async function (chatMemberUpdated: any) { console.log(calculateHistory) + // todo notify groups about federal outlaws when enforcement is false + if (calculateHistory.length > 0){ var max_timestamp = 0 for (const ban of calculateHistory){ @@ -148,7 +168,7 @@ bot.on("new_chat_members", async function (chatMemberUpdated: any) { max_timestamp = ban.timestamp_finalized } const parole_time = calcPenalty(calculateHistory.length, max_timestamp) - if (parole_time*1000 > Date.now()){ + if (settings.enforcement && parole_time*1000 > Date.now()){ queue.add(async () => {try{await bot.banChatMember(chatMemberUpdated.chat.id, chatMemberUpdated.new_chat_member.id, {until_date: parole_time})}catch{}}) return } @@ -171,7 +191,7 @@ bot.on("new_chat_members", async function (chatMemberUpdated: any) { max_timestamp = ban.timestamp_finalized } const parole_time = calcPenalty(calculateHistoryActive.length, max_timestamp) - if (parole_time > Date.now()){ + if (settings.enforcement && parole_time > Date.now()){ const options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false, until_date: parole_time}; queue.add(async () => {try{await bot.restrictChatMember(chatMemberUpdated.chat.id, chatMemberUpdated.new_chat_member.id, options)}catch{}}) return; @@ -179,9 +199,21 @@ bot.on("new_chat_members", async function (chatMemberUpdated: any) { } if(settings.captcha || settings.greeting_mode) - greeting.callback(queue, bot, settings, chatMemberUpdated); + greeting.callback(db, queue, bot, settings, chatMemberUpdated); }); + +const calcPenalty = (ban_level: number, timestamp_finalized: number): number => { + if(ban_level == 1) + return timestamp_finalized + 86400 + else if (ban_level == 2) + return timestamp_finalized + 604800 + else if (ban_level == 3) + return timestamp_finalized + 2678400 + else + return timestamp_finalized + 31536000 +} + // Handle callback queries bot.on('callback_query', async function onCallbackQuery(callbackQuery: TelegramBot.CallbackQuery) { const calldata = callbackQuery.data.split('|'); @@ -192,6 +224,7 @@ bot.on('callback_query', async function onCallbackQuery(callbackQuery: TelegramB if (callbackQuery.from.id !== Number(calldata[1])) return; setLanguage.setLanguageConfirm(queue, db, bot, settings, calldata[2], callbackQuery.message); + myCache.del(callbackQuery.message.chat.id) } else if (Number(calldata[0]) === 1){ // add evidence if (callbackQuery.from.id !== Number(calldata[1])) return; @@ -254,6 +287,7 @@ const commands: {regexp: RegExp, callback: any}[] = [ toggleAdminReportable, leaveFed, joinFed, + multilang, setChannel, setChannelFed, addEvidence, @@ -261,7 +295,7 @@ const commands: {regexp: RegExp, callback: any}[] = [ setLanguage, ]; -const adminOnlyCommands = [joinFed, leaveFed, newFed, toggleCaptcha, setLanguage, setChannelFed, setChannel, toggleWelcome, toggleAdminReportable, start, setRulesCommand ] +const adminOnlyCommands = [joinFed, multilang, leaveFed, newFed, toggleCaptcha, setLanguage, setChannelFed, setChannel, toggleWelcome, toggleAdminReportable, start, setRulesCommand ] commands.forEach((command) => { bot.onText( @@ -300,20 +334,7 @@ commands.forEach((command) => { return } else if(msg.chat.type !== "supergroup" && !(msg.chat.type === "group" && msg.text === '/help')) return - if (command === start){ - if (hasStarted(msg.chat.id)){ - try{ - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, "Susie is already moderating this community.", msg.chat.is_forum? {message_thread_id: msg.message_thread_id} : {}) - return val}catch{}}); - if(!resp) - return - myCacheGarbageCollection.set(resp.message_id, msg.chat.id) - return - } catch(e){ - console.log(e) - } - } - } else if(!hasStarted(msg.chat.id) && command !== help){ + if(!hasStarted(msg.chat.id) && (command !== help && command !== start)){ return; } @@ -331,7 +352,8 @@ commands.forEach((command) => { } if (!(status === 'creator' || status === 'administrator')) { try{ - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[groupSettings.lang].errorAdminOnly, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + const lang_code = hasStarted(msg.chat.id)? groupSettings.lang : msg?.from?.language_code + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[lang_code].error.admin, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) return val}catch{}}) if(!resp) return @@ -387,7 +409,7 @@ const validate = (chat: any, language_code?: string): groupSettings=> { if (!groupSettings){ const rules = getRule(db, 'telegram', String(chat.id), Math.floor(Date.now()/1000)) groupSettings = getGroupSettings(db, 'telegram', String(chat.id)) - groupSettings.rules = rules + groupSettings.rules = rules.rules myCache.set(chat.id, groupSettings) } const fullSettings = { @@ -397,7 +419,7 @@ const validate = (chat: any, language_code?: string): groupSettings=> { greeting_mode: groupSettings?.greeting_mode ?? defaultSettings.greeting_mode, admin_reportable: groupSettings?.admin_reportable ?? defaultSettings.admin_reportable, captcha: groupSettings?.captcha ?? defaultSettings.captcha, - privacy_mode: groupSettings?.privacy_mode ?? defaultSettings.privacy_mode, + enforcement: groupSettings?.enforcement ?? defaultSettings.enforcement, thread_id_rules: groupSettings?.thread_id_rules ?? defaultSettings.thread_id_rules, thread_id_welcome: groupSettings?.thread_id_welcome ?? defaultSettings.thread_id_rules, thread_id_notifications: groupSettings?.thread_id_notifications ?? defaultSettings.thread_id_notifications, @@ -416,14 +438,14 @@ const checkMigration = async (groupSettings: groupSettings, chat: any): Promise< const threads = await start.topicMode(queue, db, bot, groupSettings, chat); if(!threads) return; - queue.add(async () => {try{await bot.sendMessage(chat.id, "Started topic mode", {messsage_thread_id: groupSettings.thread_id_notifications})}catch{}}) + queue.add(async () => {try{await bot.sendMessage(chat.id, langJson[groupSettings.lang].index.topic, {messsage_thread_id: groupSettings.thread_id_notifications})}catch{}}) groupSettings.thread_id_rules = threads[0] groupSettings.thread_id_notifications = threads[1] groupSettings.channelID = String(chat.id) myCache.set(chat.id, groupSettings) } catch(e){ try{ - queue.add(async () => {try{await bot.sendMessage(chat.id, "Susie cannot manage groups in topic mode with out permission to manage topics. Please ask an admin to enable this permission to allow Susie to continue help moderating your community.", {messsage_thread_id: groupSettings.thread_id_notifications})}catch{}}) + queue.add(async () => {try{await bot.sendMessage(chat.id, langJson[groupSettings.lang].index.topicError, {messsage_thread_id: groupSettings.thread_id_notifications})}catch{}}) } catch(e){ console.log(e) } diff --git a/types.d.ts b/types.d.ts index 4235c0d..c68dd17 100644 --- a/types.d.ts +++ b/types.d.ts @@ -11,6 +11,7 @@ interface groupSettings { greeting_mode: boolean; admin_reportable: boolean; captcha: boolean; + enforcement: boolean; federation_id: string; federation_id_following: string; } @@ -25,6 +26,7 @@ interface groupSettings { greeting_mode: boolean | undefined; captcha: boolean | undefined; admin_reportable: boolean; + enforcement: boolean | undefined; federation_id: string | undefined; - federation_id_following: string; + federation_id_following: string | undefined; } \ No newline at end of file From 34f4d922ae5f6c9a79d3c1abd8acb485b9027aee Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Mon, 23 Jan 2023 22:35:02 +0000 Subject: [PATCH 026/111] feat: multilang support and bug fixes --- lib/cron.ts | 211 ++++++++++++--------- lib/realitioReporting.ts | 6 +- lib/telegram/assets/langNew.json | 91 +++++---- lib/telegram/commands/addEvidence.ts | 22 ++- lib/telegram/commands/getAccount.ts | 11 +- lib/telegram/commands/getReports.ts | 7 +- lib/telegram/commands/help.ts | 1 + lib/telegram/commands/report.ts | 4 +- lib/telegram/commands/setRules.ts | 8 +- lib/telegram/commands/socialConsensus.ts | 10 +- lib/telegram/commands/start.ts | 8 +- lib/telegram/commands/toggleCaptcha.ts | 2 +- lib/telegram/commands/toggleEnforcement.ts | 2 +- lib/telegram/index.ts | 9 +- subgraph/subgraph.yaml | 28 ++- 15 files changed, 255 insertions(+), 165 deletions(-) diff --git a/lib/cron.ts b/lib/cron.ts index a2a49e5..13e5daa 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -49,30 +49,33 @@ const exit = async () => { console.log(history.last_timestamp) console.log(history.last_block) // hardcode values for tests - //history.last_timestamp = 1673739955 - //history.last_block = 8312565 - let timestampNew; + + //history.last_timestamp = 1674496352 + //history.last_block = 8362931 + let timestampNew = Math.floor(Date.now()/1000); let timestampLastUpdated = history.last_timestamp - let realitio_bot_checkpoint = Math.floor(timestampNew / 3600) + let realitio_bot_checkpoint = Math.floor(timestampNew / 1800) - 1 while (1){ timestampNew = Math.floor(Date.now()/1000) - // don't run more than once per minute - if (timestampNew < timestampLastUpdated + 60){ - await delay(60000) - timestampNew = Math.floor(Date.now()/1000) - } - console.log(timestampNew < timestampLastUpdated + 60) - console.log('yoyoyoyo') const questionDelay = await update(timestampNew, timestampLastUpdated, botaddress); - delayCheck(questionDelay, 0,timestampNew,timestampLastUpdated,botaddress) - // every hour - if (Math.floor(timestampNew / 3600) > realitio_bot_checkpoint){ - realitio_bot_checkpoint = Math.floor(timestampNew / 3600) - await realitio_bot(web3, currentBlock, process.env.REALITY_ETH_V30, process.env.REALITIO_ARBITRATOR); - currentBlock = await web3.eth.getBlockNumber() + if(questionDelay) + delayCheck(questionDelay, 0,timestampNew,timestampLastUpdated,botaddress) + // every 30 min + if (Math.floor(timestampNew / 1800) > realitio_bot_checkpoint){ + realitio_bot_checkpoint = Math.floor(timestampNew / 1800) + const currentBlock = await web3.eth.getBlockNumber() + const updateBlock = Math.min(history.last_block+1000, currentBlock) + try{ + await realitio_bot(web3, history.last_block, updateBlock, process.env.REALITY_ETH_V30, process.env.REALITIO_ARBITRATOR_EN); + await realitio_bot(web3, history.last_block, updateBlock, process.env.REALITY_ETH_V30, process.env.REALITIO_ARBITRATOR_ES); + } catch (e){ + console.log(e) + } + history.last_block = updateBlock } timestampLastUpdated = timestampNew setCron(db, currentBlock,timestampNew) + await delay(60000) } })() @@ -95,7 +98,7 @@ const update = async (timestampNew: number, timestampLastUpdated: number,botaddr //console.log(queryModeration); //console.log('graphtime'); - //console.log(queryModeration) + console.log(queryModeration) const moderationActions = await request( process.env.MODERATE_SUBGRAPH, queryModeration @@ -106,18 +109,19 @@ const update = async (timestampNew: number, timestampLastUpdated: number,botaddr const settings = validate(data.moderationInfo.UserHistory.group.groupID); // settings[1] language try{ + console.log(settings) const msgLink = data.moderationInfo.message; const disputeURL = `https://resolve.kleros.io/cases/${BigNumber.from(data.id).toNumber()}`; // check rulings, note down shift since reality uses 0,1 for no, yes and kleros uses 1,2 for no, yes - const message = settings.lang === "es" ? (data.finalRuling === 2)? 'infringió las normas' : 'no infringió las normas' : (data.finalRuling === 2)? 'broke the rules' : 'did not break the rules' + const message = settings.lang === "es" ? (data.finalRuling === "2")? 'infringió las normas' : 'no infringió las normas' : (data.finalRuling === "2")? 'broke the rules' : 'did not break the rules' //console.log(data.finalRuling) try{ if (settings.lang === "en") - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `The [dispute](${disputeURL}) over *${data.moderationInfo.UserHistory.user.username}*'s [message](${msgLink}) ([backup](${data.moderationInfo.messageBackup})) resolved. *${data.moderationInfo.UserHistory.user.username}* ${message}`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `The [dispute](${disputeURL}) over [${data.moderationInfo.UserHistory.user.username}](tg://user?id=${data.moderationInfo.UserHistory.user.userID})'s [message](${msgLink}) ([backup](${data.moderationInfo.messageBackup})) resolved. *${data.moderationInfo.UserHistory.user.username}* ${message}`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); else - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `La [disputa](${disputeURL}) sobre el [mensaje](${msgLink}) ([backup](${data.moderationInfo.messageBackup})) de *${data.moderationInfo.UserHistory.user.username}* ha resuelto. *${data.moderationInfo.UserHistory.user.username}* ${message}`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `La [disputa](${disputeURL}) sobre el [mensaje](${msgLink}) ([backup](${data.moderationInfo.messageBackup})) de [${data.moderationInfo.UserHistory.user.username}](tg://user?id=${data.moderationInfo.UserHistory.user.userID})'s ha resuelto. *${data.moderationInfo.UserHistory.user.username}* ${message}`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); //bot.sendMessage(process.env.JUSTICE_LEAGUE, `The [dispute](${disputeURL}) over *${data.moderationInfo.UserHistory.user.username}*'s [message](${msgLink}) ([backup](${data.moderationInfo.messageBackup})) resolved. *${data.moderationInfo.UserHistory.user.username}* ${message}`, {parse_mode: 'Markdown'}); - handleTelegramUpdate(db, bot,settings, data.moderationInfo,timestampNew, data.finalRuling === 2, true, true); + handleTelegramUpdate(db, bot,settings, data.moderationInfo,timestampNew, data.finalRuling === "2", true, true); } catch(e){ console.log(e) } @@ -137,22 +141,26 @@ const update = async (timestampNew: number, timestampLastUpdated: number,botaddr const chatobj = (await queue.add(async () => {try{const val = await bot.getChat(data.moderationInfo.UserHistory.group.groupID) return val}catch{}})) const chatname = chatobj?.title - const isPrivate = !chatobj.active_usernames - const invite_url = isPrivate ? '' : getInviteURL(db,'telegram',data.moderationInfo.UserHistory.group.groupID) + const isPrivate = !chatobj?.active_usernames + const invite_url= isPrivate? '' : `https://t.me/${chatobj?.active_usernames[0]}` if (settings.lang === "en"){ - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `The dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - const chatobj = (await queue.add(async () => {try{const val = await bot.getChat(data.moderationInfo.UserHistory.group.groupID) - return val}catch{}})) + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `The dispute over the [question](${realityURL}) about [${data.moderationInfo.UserHistory.user.username}](tg://user?id=${data.moderationInfo.UserHistory.user.userID})'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.messageBackup})) has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); if (settings.channelID !== process.env.SUSIE_SUPPORT_EN) - queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_EN, `The dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) in the group [${chatname}](${invite_url}) has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, {message_thread_id: process.env.JUSTICE_LEAGUE_EN, parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - if(settings.federation_id) - queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `The dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) in the group [${chatname}](${invite_url})has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_EN, `The dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.messageBackupup})) in the group [${chatname}](${invite_url}) has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, {message_thread_id: process.env.JUSTICE_LEAGUE_EN, parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if(settings.federation_id){ + const fedNotificationChannel = getFederationChannel(db, 'telegram',settings.federation_id) + if (fedNotificationChannel) + queue.add(async () => {try{await bot.sendMessage(fedNotificationChannel, `The dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.messageBackupup})) in the group [${chatname}](${invite_url})has concluded it's current round. *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. If you think the decision is incorrect, you can request an [appeal](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + } } else { - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `La disputa sobre la [pregunta](${realityURL}) acerca de la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) ha concluido su ronda actual. La conducta de *${data.moderationInfo.UserHistory.user.username}* ${data.currentRuling == 2? 'infringió las normas': 'no infringió las normas'}. Si crees que la decisión es incorrecta, puedes solicitar una [apelación](${disputeURL})`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `La disputa sobre la [pregunta](${realityURL}) acerca de la conducta de [${data.moderationInfo.UserHistory.user.username}](tg://user?id=${data.moderationInfo.UserHistory.user.userID})'s debido al [mensaje](${msgLink}) ([backup](${data.moderationInfo.messageBackupup})) ha concluido su ronda actual. La conducta de *${data.moderationInfo.UserHistory.user.username}* ${data.currentRuling == 2? 'infringió las normas': 'no infringió las normas'}. Si crees que la decisión es incorrecta, puedes solicitar una [apelación](${disputeURL})`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); if (settings.channelID !== process.env.SUSIE_SUPPORT_ES) - queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_ES, `La disputa sobre la [pregunta](${realityURL}) acerca de la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) en el grupo [${chatname}](${invite_url}) ha concluido su ronda actual. La conducta de *${data.moderationInfo.UserHistory.user.username}* ${data.currentRuling == 2? 'infringió las normas': 'no infringió las normas'}. Si crees que la decisión es incorrecta, puedes solicitar una [apelación](${disputeURL})`, {message_thread_id: process.env.JUSTICE_LEAGUE_ES, parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - if(settings.federation_id) - queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `La disputa sobre la [pregunta](${realityURL}) acerca de la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) en el grupo [${chatname}](${invite_url}) ha concluido su ronda actual. La conducta de *${data.moderationInfo.UserHistory.user.username}* ${data.currentRuling == 2? 'infringió las normas': 'no infringió las normas'}. Si crees que la decisión es incorrecta, puedes solicitar una [apelación](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_ES, `La disputa sobre la [pregunta](${realityURL}) acerca de la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${msgLink}) ([backup](${data.moderationInfo.messageBackupup})) en el grupo [${chatname}](${invite_url}) ha concluido su ronda actual. La conducta de *${data.moderationInfo.UserHistory.user.username}* ${data.currentRuling == 2? 'infringió las normas': 'no infringió las normas'}. Si crees que la decisión es incorrecta, puedes solicitar una [apelación](${disputeURL})`, {message_thread_id: process.env.JUSTICE_LEAGUE_ES, parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if(settings.federation_id){ + const fedNotificationChannel = getFederationChannel(db, 'telegram',settings.federation_id) + if (fedNotificationChannel) + queue.add(async () => {try{await bot.sendMessage(fedNotificationChannel, `La disputa sobre la [pregunta](${realityURL}) acerca de la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${msgLink}) ([backup](${data.moderationInfo.messageBackupup})) en el grupo [${chatname}](${invite_url}) ha concluido su ronda actual. La conducta de *${data.moderationInfo.UserHistory.user.username}* ${data.currentRuling == 2? 'infringió las normas': 'no infringió las normas'}. Si crees que la decisión es incorrecta, puedes solicitar una [apelación](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + } } } catch(e){ console.log(e) @@ -169,20 +177,30 @@ const update = async (timestampNew: number, timestampLastUpdated: number,botaddr return val}catch{}})) const chatname = chatobj?.title const isPrivate = !chatobj.active_usernames - const invite_url = isPrivate ? '' : getInviteURL(db,'telegram',data.moderationInfo.UserHistory.group.groupID) + const invite_url= isPrivate? '' : `https://t.me/${chatobj?.active_usernames[0]}` const msg_penalty = settings.lang === 'en' ? settings.enforcement? `Consequences of the report are lifted for the duration of the [dispute](${disputeURL}) (on [Gnosis Chain](https://chainlist.org/chain/100)).` : `I recommend that any preliminary penalties due to the report be lifted for the duration of the [dispute](${disputeURL}) (on [Gnosis Chain](https://chainlist.org/chain/100)).` : settings.enforcement? `Las consecuencias de la denuncia se levantan mientras dure la [disputa](${disputeURL}) (en [Gnosis Chain](https://chainlist.org/chain/100)).` : `Recomiendo que se levanten las sanciones preliminares debidas al informe mientras dure la [disputa](${disputeURL}) (en [Gnosis Chain](https://chainlist.org/chain/100)).` if (settings.lang === "en"){ - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `Arbitration is requested for the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})). ${msg_penalty}`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - if (settings.channelID !== process.env.SUSIE_SUPPORT_EN) - queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_EN, `[Arbitration](${disputeURL}) is requested for the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) in the group [${chatname}](${invite_url}).`, {message_thread_id: process.env.JUSTICE_LEAGUE_EN, parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - if(settings.federation_id) - queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `[Arbitration](${disputeURL}) is requested for the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) in the group [${chatname}](${invite_url}).`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `Arbitration is requested for the [question](${realityURL}) about [${data.moderationInfo.UserHistory.user.username}](tg://user?id=${data.moderationInfo.UserHistory.user.userID})'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})). ${msg_penalty}`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if (!isPrivate){ + if (settings.channelID !== process.env.SUSIE_SUPPORT_EN) + queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_EN, `[Arbitration](${disputeURL}) is requested for the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) in the group [${chatname}](${invite_url}).`, {message_thread_id: process.env.JUSTICE_LEAGUE_EN, parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if(settings.federation_id){ + const fedNotificationChannel = getFederationChannel(db, 'telegram',settings.federation_id) + if (fedNotificationChannel) + queue.add(async () => {try{await bot.sendMessage(fedNotificationChannel, `[Arbitration](${disputeURL}) is requested for the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) in the group [${chatname}](${invite_url}).`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + } + } } else { queue.add(async () => {try{await bot.sendMessage(settings.channelID, `Se solicita arbitraje para la [pregunta](${realityURL}) sobre la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})). ${msg_penalty}`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - if (settings.channelID !== process.env.SUSIE_SUPPORT_ES) - queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_ES, `Se solicita [arbitraje](${disputeURL}) para la [pregunta](${realityURL}) sobre la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup}) en el grupo [${chatname}](${invite_url}).`, {message_thread_id: process.env.JUSTICE_LEAGUE_EN, parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - if(settings.federation_id) - queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `Se solicita [arbitraje](${disputeURL}) para la [pregunta](${realityURL}) sobre la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup}) en el grupo [${chatname}](${invite_url}).`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if(!isPrivate){ + if (settings.channelID !== process.env.SUSIE_SUPPORT_ES) + queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_ES, `Se solicita [arbitraje](${disputeURL}) para la [pregunta](${realityURL}) sobre la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup}) en el grupo [${chatname}](${invite_url}).`, {message_thread_id: process.env.JUSTICE_LEAGUE_EN, parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if(settings.federation_id){ + const fedNotificationChannel = getFederationChannel(db, 'telegram',settings.federation_id) + if (fedNotificationChannel) + queue.add(async () => {try{await bot.sendMessage(fedNotificationChannel, `Se solicita [arbitraje](${disputeURL}) para la [pregunta](${realityURL}) sobre la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup}) en el grupo [${chatname}](${invite_url}).`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + } + } } handleTelegramUpdate(db, bot,settings, data.moderationInfo,timestampNew, false, false, true); } catch (e){ @@ -201,19 +219,25 @@ const update = async (timestampNew: number, timestampLastUpdated: number,botaddr return val}catch{}})) const chatname = chatobj?.title const isPrivate = !chatobj.active_usernames - const invite_url = isPrivate ? '' : getInviteURL(db,'telegram',data.moderationInfo.UserHistory.group.groupID) + const invite_url= isPrivate? '' : `https://t.me/${chatobj?.active_usernames[0]}` if (settings.lang === "en"){ - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `An appeal has been funded in the dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})). Juror's voted in the previous round that *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. The contribution funded ${data.RulingFunded == data.currentRuling ? 'the previous round winning option': 'a different option that the previous round'}. If you think the funded option is incorrect, you can win some of their deposit by funding the correct side of the [appeal](${disputeURL})`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `An appeal has been funded in the dispute over the [question](${realityURL}) about [${data.moderationInfo.UserHistory.user.username}](tg://user?id=${data.moderationInfo.UserHistory.user.userID})'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.messageBackupup})). Juror's voted in the previous round that *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. The contribution funded ${data.RulingFunded == data.currentRuling ? 'the previous round winning option': 'a different option that the previous round'}. If you think the funded option is incorrect, you can win some of their deposit by funding the correct side of the [appeal](${disputeURL})`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); if (settings.channelID !== process.env.SUSIE_SUPPORT_EN) - queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_EN, `An appeal has been funded in the dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) in the group ${chatname}[${invite_url}]. Juror's voted in the previous round that *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. The contribution funded ${data.RulingFunded == data.currentRuling ? 'the previous round winning option': 'a different option that the previous round'}. If you think the funded option is incorrect, you can win some of their deposit by funding the correct side of the [appeal](${disputeURL})`, {message_thread_id: process.env.JUSTICE_LEAGUE_EN, parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - if(settings.federation_id) - queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `An appeal has been funded in the dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) in the group ${chatname}[${invite_url}]. Juror's voted in the previous round that *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. The contribution funded ${data.RulingFunded == data.currentRuling ? 'the previous round winning option': 'a different option that the previous round'}. If you think the funded option is incorrect, you can win some of their deposit by funding the correct side of the [appeal](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_EN, `An appeal has been funded in the dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.messageBackupup})) in the group ${chatname}[${invite_url}]. Juror's voted in the previous round that *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. The contribution funded ${data.RulingFunded == data.currentRuling ? 'the previous round winning option': 'a different option that the previous round'}. If you think the funded option is incorrect, you can win some of their deposit by funding the correct side of the [appeal](${disputeURL})`, {message_thread_id: process.env.JUSTICE_LEAGUE_EN, parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if(settings.federation_id){ + const fedNotificationChannel = getFederationChannel(db, 'telegram',settings.federation_id) + if (fedNotificationChannel) + queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `An appeal has been funded in the dispute over the [question](${realityURL}) about *${data.moderationInfo.UserHistory.user.username}*'s conduct due to the [message](${msgLink}) ([backup](${data.moderationInfo.messageBackupup})) in the group ${chatname}[${invite_url}]. Juror's voted in the previous round that *${data.moderationInfo.UserHistory.user.username}*'s conduct ${data.currentRuling == 2? 'broke the rules': 'did not break the rules'}. The contribution funded ${data.RulingFunded == data.currentRuling ? 'the previous round winning option': 'a different option that the previous round'}. If you think the funded option is incorrect, you can win some of their deposit by funding the correct side of the [appeal](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + } } else { - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `Se ha financiado una apelación en la disputa sobre la [pregunta](${realityURL}) acerca de la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${msgLink}) ([backup](${data.moderationInfo.msgBackup})). El jurado votó en la ronda anterior que la conducta de *${data.moderationInfo.UserHistory.user.username}* ${data.currentRuling == 2? 'infringió las normas': 'no infringió las normas'}. La contribución financió ${data.RulingFunded == data.currentRuling ? 'la opción ganadora de la ronda anterior': 'una opción diferente a la de la ronda anterior'}. Si crees que la opción financiada es incorrecta, puedes ganar parte de su depósito financiando la parte correcta del [apelación](${disputeURL})`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `Se ha financiado una apelación en la disputa sobre la [pregunta](${realityURL}) acerca de la conducta de [${data.moderationInfo.UserHistory.user.username}](tg://user?id=${data.moderationInfo.UserHistory.user.userID})'s debido al [mensaje](${msgLink}) ([backup](${data.moderationInfo.messageBackupup})). El jurado votó en la ronda anterior que la conducta de *${data.moderationInfo.UserHistory.user.username}* ${data.currentRuling == 2? 'infringió las normas': 'no infringió las normas'}. La contribución financió ${data.RulingFunded == data.currentRuling ? 'la opción ganadora de la ronda anterior': 'una opción diferente a la de la ronda anterior'}. Si crees que la opción financiada es incorrecta, puedes ganar parte de su depósito financiando la parte correcta del [apelación](${disputeURL})`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); if (settings.channelID !== process.env.SUSIE_SUPPORT_ES) - queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_ES, `Se ha financiado una apelación en la disputa sobre la [pregunta](${realityURL}) acerca de la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) en el grupo ${chatname}[${invite_url}]. El jurado votó en la ronda anterior que la conducta de *${data.moderationInfo.UserHistory.user.username}* ${data.currentRuling == 2? 'infringió las normas': 'no infringió las normas'}. La contribución financió ${data.RulingFunded == data.currentRuling ? 'la opción ganadora de la ronda anterior': 'una opción diferente a la de la ronda anterior'}. Si crees que la opción financiada es incorrecta, puedes ganar parte de su depósito financiando la parte correcta del [apelación](${disputeURL})`, {message_thread_id: process.env.JUSTICE_LEAGUE_ES, parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - if(settings.federation_id) - queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `Se ha financiado una apelación en la disputa sobre la [pregunta](${realityURL}) acerca de la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${msgLink}) ([backup](${data.moderationInfo.msgBackup})) en el grupo ${chatname}[${invite_url}]. El jurado votó en la ronda anterior que la conducta de *${data.moderationInfo.UserHistory.user.username}* ${data.currentRuling == 2? 'infringió las normas': 'no infringió las normas'}. La contribución financió ${data.RulingFunded == data.currentRuling ? 'la opción ganadora de la ronda anterior': 'una opción diferente a la de la ronda anterior'}. Si crees que la opción financiada es incorrecta, puedes ganar parte de su depósito financiando la parte correcta del [apelación](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_ES, `Se ha financiado una apelación en la disputa sobre la [pregunta](${realityURL}) acerca de la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${msgLink}) ([backup](${data.moderationInfo.messageBackupup})) en el grupo ${chatname}[${invite_url}]. El jurado votó en la ronda anterior que la conducta de *${data.moderationInfo.UserHistory.user.username}* ${data.currentRuling == 2? 'infringió las normas': 'no infringió las normas'}. La contribución financió ${data.RulingFunded == data.currentRuling ? 'la opción ganadora de la ronda anterior': 'una opción diferente a la de la ronda anterior'}. Si crees que la opción financiada es incorrecta, puedes ganar parte de su depósito financiando la parte correcta del [apelación](${disputeURL})`, {message_thread_id: process.env.JUSTICE_LEAGUE_ES, parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if(settings.federation_id){ + const fedNotificationChannel = getFederationChannel(db, 'telegram',settings.federation_id) + if (fedNotificationChannel) + queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `Se ha financiado una apelación en la disputa sobre la [pregunta](${realityURL}) acerca de la conducta de *${data.moderationInfo.UserHistory.user.username}* debido al [mensaje](${msgLink}) ([backup](${data.moderationInfo.messageBackupup})) en el grupo ${chatname}[${invite_url}]. El jurado votó en la ronda anterior que la conducta de *${data.moderationInfo.UserHistory.user.username}* ${data.currentRuling == 2? 'infringió las normas': 'no infringió las normas'}. La contribución financió ${data.RulingFunded == data.currentRuling ? 'la opción ganadora de la ronda anterior': 'una opción diferente a la de la ronda anterior'}. Si crees que la opción financiada es incorrecta, puedes ganar parte de su depósito financiando la parte correcta del [apelación](${disputeURL})`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + } } } catch(e){ console.log(e) @@ -253,36 +277,39 @@ for(const data of moderationActions.realityQuestionAnsweredNotFinalized){ const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; const answer = data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001" ? (settings.lang === 'en'? "yes": 'si') : "no"; //console.log('answeredbeg') + const chat = (await queue.add(async () => {try{const val = await bot.getChat(data.moderationInfo.UserHistory.group.groupID) + return val}catch{}})) + const chatname = chat?.title + const isPrivate = !chat?.active_usernames + const invite_url= isPrivate? '' : `https://t.me/${chat?.active_usernames[0]}` + if (settings.lang === 'en'){ - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) violate the [rules](${data.moderationInfo.rulesUrl})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - const chat = (await queue.add(async () => {try{const val = await bot.getChat(data.moderationInfo.UserHistory.group.groupID) - return val}catch{}})) - const chatname = chat?.title - const isPrivate = !chat.active_usernames - const invite_url = getInviteURL(db,'telegram',data.moderationInfo.UserHistory.group.groupID) + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `The question\n\n"Did [${data.moderationInfo.UserHistory.user.username}](tg://user?id=${data.moderationInfo.UserHistory.user.userID})'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) violate the [rules](${data.moderationInfo.rulesUrl})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); if (!isPrivate){ if (settings.channelID !== process.env.SUSIE_SUPPORT_EN) - queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_EN, `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) in the group [${chatname}](${invite_url}) violate the [rules](${data.moderationInfo.rulesUrl})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - if(settings.federation_id) - queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) in the group [${chatname}](${invite_url}) violate the [rules](${data.moderationInfo.rulesUrl})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_EN, `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) in the group [${chatname}](${invite_url}) violate the [rules](${data.moderationInfo.rulesUrl})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, {message_thread_id: process.env.JUSTICE_LEAGUE_EN, parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if(settings.federation_id){ + const fedNotificationChannel = getFederationChannel(db, 'telegram',settings.federation_id) + if (fedNotificationChannel) + queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) in the group [${chatname}](${invite_url}) violate the [rules](${data.moderationInfo.rulesUrl})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + } } }else{ - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `La pregunta\n\n"¿Ha infringido el usuario *${data.moderationInfo.UserHistory.user.username}* las [reglas](${data.moderationInfo.rulesUrl}) mediante conductas relacionadas con el [mensaje](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup}))?\"\n\nse responde con un *${answer}*.\n\n¿Crees que esta respuesta es verdadera? Si no es así, puedes [corregir](${realityURL}) la respuesta.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - const chat = (await queue.add(async () => {try{const val = await bot.getChat(data.moderationInfo.UserHistory.group.groupID) - return val}catch{}})) - const chatname = chat?.title - const isPrivate = !chat.active_usernames - const invite_url = getInviteURL(db,'telegram',data.moderationInfo.UserHistory.group.groupID) + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `La pregunta\n\n"¿Ha infringido el usuario [${data.moderationInfo.UserHistory.user.username}](tg://user?id=${data.moderationInfo.UserHistory.user.userID})'s las [reglas](${data.moderationInfo.rulesUrl}) mediante conductas relacionadas con el [mensaje](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup}))?\"\n\nse responde con un *${answer}*.\n\n¿Crees que esta respuesta es verdadera? Si no es así, puedes [corregir](${realityURL}) la respuesta.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); if (settings.channelID !== process.env.SUSIE_SUPPORT_ES) if (!isPrivate){ if (settings.channelID !== process.env.SUSIE_SUPPORT_ES) - queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_ES, `La pregunta\n\n"¿Ha infringido el usuario *${data.moderationInfo.UserHistory.user.username}* en el grupo [${chatname}](${invite_url}) las [reglas](${data.moderationInfo.rulesUrl}) mediante conductas relacionadas con el [mensaje](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup}))?\"\n\nse responde con un *${answer}*.\n\n¿Crees que esta respuesta es verdadera? Si no es así, puedes [corregir](${realityURL}) la respuesta.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); - if(settings.federation_id) - queue.add(async () => {try{await bot.sendMessage(getFederationChannel(db, 'telegram',settings.federation_id), `The question\n\n"Did *${data.moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup})) in the group [${chatname}](${invite_url}) violate the [rules](${data.moderationInfo.rulesUrl})?\"\n\nis answered with *${answer}*.\n\nDo you think this answer is true? If not, you can [correct](${realityURL}) the answer.`, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(process.env.SUSIE_SUPPORT_ES, `La pregunta\n\n"¿Ha infringido el usuario *${data.moderationInfo.UserHistory.user.username}* en el grupo [${chatname}](${invite_url}) las [reglas](${data.moderationInfo.rulesUrl}) mediante conductas relacionadas con el [mensaje](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup}))?\"\n\nse responde con un *${answer}*.\n\n¿Crees que esta respuesta es verdadera? Si no es así, puedes [corregir](${realityURL}) la respuesta.`, {message_thread_id: process.env.JUSTICE_LEAGUE_ES, parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + if(settings.federation_id){ + const fedNotificationChannel = getFederationChannel(db, 'telegram',settings.federation_id) + if (fedNotificationChannel) + queue.add(async () => {try{await bot.sendMessage(fedNotificationChannel, `La pregunta\n\n"¿Ha infringido el usuario *${data.moderationInfo.UserHistory.user.username}* en el grupo [${chatname}](${invite_url}) las [reglas](${data.moderationInfo.rulesUrl}) mediante conductas relacionadas con el [mensaje](${data.moderationInfo.message}) ([backup](${data.moderationInfo.messageBackup}))?\"\n\nse contesta con *${answer}*.\n¿Crees que esta respuesta es cierta? Si no es así, puedes [corregir](${realityURL}) la respuesta.`, {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); + } } } - handleTelegramUpdate(db, bot, settings, data.moderationInfo, timestampNew, data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001", false, false); if(settings.enforcement){ - delayQuestions += `\"${data.id},\"` + delayQuestions += `"${data.id}",` + } else { + handleTelegramUpdate(db, bot, settings, data.moderationInfo, timestampNew, data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001", false, false); } } catch(e){ console.log(e) @@ -359,7 +386,10 @@ for(const data of moderationActions.realityQuestionAnsweredFinalized){ } await queue.onIdle() - return delayQuestions.substring(0,delayQuestions.length-1); + if (delayQuestions.length > 0) + return delayQuestions.substring(0,delayQuestions.length-1); + else + return "" } const delay = (delayInms) => { @@ -368,7 +398,8 @@ const delay = (delayInms) => { const delayCheck = async (realityQuestions: string, lastPageUpdated: number, timestampNew: number, timestampLastUpdated: number, botaddress: string) => { const queryModeration = getQueryDelay(lastPageUpdated, realityQuestions, timestampLastUpdated, botaddress, timestampNew) - // 5 min delay + // 1 min delay + console.log(queryModeration) await delay(60000) //console.log(queryModeration); //console.log('graphtime'); @@ -404,7 +435,7 @@ const validate = (chatId: string): groupSettings=> { greeting_mode: false, captcha: false, admin_reportable: false, - enforcement: false, + enforcement: true, thread_id_rules: '', thread_id_welcome: '', thread_id_notifications: '', @@ -446,27 +477,29 @@ const calcPenaltyPhrase = (settings: groupSettings, ban_level: number, enforceme if (settings.lang === 'es'){ if(ban_level == 1) - return finalize? enforcement? 'primera vez y está sujeta a un baneo de 1 día' : 'primera vez y se recomienda una prohibición de 1 día' : 'primera vez y se le recomienda un silencio de 1 día por el resto del período del informe' + return finalize? enforcement? 'primera vez y está sujeta a un baneo de 1 día' : 'primera vez y se recomienda una prohibición de 1 día' : enforcement? 'primera vez y se silencia durante 1 día durante el resto del periodo del informe': 'primera vez y se le recomienda un silencio de 1 día por el resto del período del informe' else if (ban_level == 2) - return finalize? enforcement? 'segunda vez y está sujeto a una prohibición de 1 semana' : 'segunda vez y se recomienda una prohibición de 1 semana': 'segunda vez y se le recomienda un silencio de 1 día para el resto del periodo del informe' + return finalize? enforcement? 'segunda vez y está sujeto a una prohibición de 1 semana' : 'segunda vez y se recomienda una prohibición de 1 semana': enforcement? 'segunda vez y se silencia durante 1 día durante el resto del periodo del informe': 'segunda vez y se le recomienda un silencio de 1 día para el resto del periodo del informe' else if (ban_level == 3) - return finalize? enforcement? 'tercera vez y está sujeto a una prohibición de 1 mes' : 'tercera vez y se recomienda una prohibición de 1 mes' : 'tercera vez y se le recomienda un silencio de 1 día por el resto del período del informe' + return finalize? enforcement? 'tercera vez y está sujeto a una prohibición de 1 mes' : 'tercera vez y se recomienda una prohibición de 1 mes' : enforcement? 'trecera vez y se silencia durante 1 día durante el resto del periodo del informe': 'tercera vez y se le recomienda un silencio de 1 día por el resto del período del informe' else - return finalize? enforcement? 'al menos cuatro veces y está sujeto a una prohibición de 1 año' : 'al menos cuatro veces y se le recomienda una prohibición de 1 mes' : 'al menos cuatro veces y se le recomienda un silencio de 1 día para el resto del período del informe.' + return finalize? enforcement? 'al menos cuatro veces y está sujeto a una prohibición de 1 año' : 'al menos cuatro veces y se le recomienda una prohibición de 1 mes' : enforcement? 'cuarta vez y se silencia durante 1 día durante el resto del periodo del informe': 'al menos cuatro veces y se le recomienda un silencio de 1 día para el resto del período del informe.' } else { if(ban_level == 1) - return finalize? enforcement? 'first time and is subject to a 1 day ban' : 'first time and is recommended a 1 day ban' : 'first time and is recommended a 1 day mute for the remainder of the report period' + return finalize? enforcement? 'first time and is subject to a 1 day ban' : 'first time and is recommended a 1 day ban' : enforcement? 'first time and is muted for 1 day during the remainder of the report period': 'first time and is recommended a 1 day mute for the remainder of the report period' else if (ban_level == 2) - return finalize? enforcement? 'second time and is subject to a 1 week ban' : 'second time and is recommended a 1 week ban': 'second time and is recommended a 1 day mute for the remainder of the report period' + return finalize? enforcement? 'second time and is subject to a 1 week ban' : 'second time and is recommended a 1 week ban': enforcement? 'second time and is muted for 1 day during the remainder of the report period': 'second time and is recommended a 1 day mute for the remainder of the report period' else if (ban_level == 3) - return finalize? enforcement? 'third time and is subject to a 1 month ban' : 'third time and is recommended a 1 month ban' : 'third time and is recommended a 1 day mute for the remainder of the report period' + return finalize? enforcement? 'third time and is subject to a 1 month ban' : 'third time and is recommended a 1 month ban' : enforcement? 'third time and is muted for 1 day during the remainder of the report period': 'third time and is recommended a 1 day mute for the remainder of the report period' else - return finalize? enforcement? 'atleast four times and is subject to a 1 year ban' : 'atleast four times and is recommended a 1 year ban' : 'four times and is recommended a 1 day mute for the remainder of the report period' + return finalize? enforcement? 'atleast four times and is subject to a 1 year ban' : 'atleast four times and is recommended a 1 year ban' : enforcement? 'four times and is muted for 1 day during the remainder of the report period': 'four times and is recommended a 1 day mute for the remainder of the report period' } } const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, moderationInfo: any, timestampNew: number, restrict: boolean, finalize: boolean, disputed: boolean) => { try{ + console.log('UPDATE#########') + console.log(settings) const reportInfo = getReportMessageTimestampAndActive(db, moderationInfo.id) if (!reportInfo) return; let calculateHistory = [] @@ -492,7 +525,7 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, const ban_level_current = calculateHistory.length console.log(calculateHistory) - const groups = settings.federation_id? getGroupsInAndFollowingFederation(db,'telegram',settings.federation_id) : [moderationInfo.UserHistory.group.groupID] + const groups = settings.federation_id? getGroupsInAndFollowingFederation(db,'telegram',settings.federation_id) : [{group_id: moderationInfo.UserHistory.group.groupID}] if (restrict){ // TODO federation subscriptions @@ -506,12 +539,12 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, // this report changed penalties, recalculate all //console.log(moderationInfo.UserHistory.group.groupID) for (const group of groups){ - queue.add(async () => {try{await bot.banChatMember(group.group_id, moderationInfo.UserHistory.user.userID, {until_date: parole})}catch{}}); + queue.add(async () => {try{await bot.banChatMember(group.group_id, moderationInfo.UserHistory.user.userID, {until_date: parole})}catch (e){console.log(e)}}); } } else if(!finalize){ const options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false, until_date: parole}; for (const group of groups){ - queue.add(async () => {try{await bot.restrictChatMember(group.group_id, moderationInfo.UserHistory.user.userID, options)}catch{}}); + queue.add(async () => {try{await bot.restrictChatMember(group.group_id, moderationInfo.UserHistory.user.userID, options)}catch(e){console.log(e)}}); } } } @@ -545,10 +578,10 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, queue.add(async () => {try{await bot.restrictChatMember(moderationInfo.UserHistory.group.groupID, moderationInfo.UserHistory.user.userID, permissions)}catch{}}); } } - const msg_update = settings.lang === "es" ? `*${moderationInfo.UserHistory.user.username}* has no other active reports. All bans should be lifted.` : `*${moderationInfo.UserHistory.user.username}* no tiene otros informes activos. Todas las prohibiciones deben ser levantadas.` + const msg_update = settings.lang === "en" ? `*${moderationInfo.UserHistory.user.username}* has no other active reports. All bans should be lifted.` : `*${moderationInfo.UserHistory.user.username}* no tiene otros informes activos. Todas las prohibiciones deben ser levantadas.` queue.add(async () => {try{await bot.sendMessage(settings.channelID, msg_update,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); } else { - const msg_update = settings.lang === "es" ? `*${moderationInfo.UserHistory.user.username}* has other active reports and should remain restricted.` : `*${moderationInfo.UserHistory.user.username}* tiene otros informes activos y debe permanecer restringido.` + const msg_update = settings.lang === "en" ? `*${moderationInfo.UserHistory.user.username}* has other active reports and should remain restricted.` : `*${moderationInfo.UserHistory.user.username}* tiene otros informes activos y debe permanecer restringido.` queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}* has other active reports and should remain restricted.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); } } diff --git a/lib/realitioReporting.ts b/lib/realitioReporting.ts index b8d10f4..dfbfe6a 100644 --- a/lib/realitioReporting.ts +++ b/lib/realitioReporting.ts @@ -1,7 +1,7 @@ const _realitio = require('./assets/contracts/Realitio_v2_1.json') const _proxy = require('./assets/contracts/Realitio_v2_1_ArbitratorWithAppeals.json') -module.exports = async (web3, lastBlock, realitioAddress, proxyAddress) => { +module.exports = async (web3, lastBlock, toBlock,realitioAddress, proxyAddress) => { // Instantiate the contracts. const realitioInstance = new web3.eth.Contract( _realitio.abi, @@ -12,11 +12,11 @@ module.exports = async (web3, lastBlock, realitioAddress, proxyAddress) => { proxyAddress ) const block = await web3.eth.getBlockNumber() - + // console.log(lastBlock) const ruleEvents = await proxyInstance.getPastEvents('Ruling', { fromBlock: lastBlock, - toBlock: lastBlock < block - 1000 ? lastBlock + 1000:'latest' + toBlock: toBlock }) // A Ruling was made diff --git a/lib/telegram/assets/langNew.json b/lib/telegram/assets/langNew.json index 3caba85..4e1fced 100644 --- a/lib/telegram/assets/langNew.json +++ b/lib/telegram/assets/langNew.json @@ -40,8 +40,8 @@ "confirm2": "This channel will now relay moderation notifications for the federation" }, "enforcement":{ - "off": "I now only recommend penalties (1 day, 1 week, 1 year).", - "on": "I now enforce penalties (1 day, 1 week, 1 year bans)." + "off": "Trial mode off. I now apply penalties to users who break the rules", + "on": "Trial mode on. I now only recommend admins to take action when rules are broken." }, "captcha": { "on": "Captcha is on.", @@ -88,8 +88,7 @@ "Option": "Option", "Evidence": "Evidence", "MessageSent": "Message Sent", - "Desc1": "Check the bot account of the chat with /getaccount to make it matches the submission address of this automated piece of evidence, to ensure its authenticity.", - "Desc2": "The attached file is a backup record of a message sent in the chat," + "Desc1": "Automated evidence submission by the Kleros Moderate bot. Please double check authenticity.The attached file is a backup record of a message sent in the chat" }, "multilang": { "es": "Spanish group set", @@ -108,19 +107,20 @@ "topics": "I need permissions to manage topics.", "reply": "Must be used in reply.", "txn": "Does the bot address have enough funds to pay the transaction? An unexpected error has occurred", - "url": "Invalid URL" + "url": "Invalid URL.", + "setrules": "`/setrules` must be used in reply to a message or followed by a URL." }, "report": { "expired": "Live and let live. This message is more than one week old. Next time try to make the report sooner.", "reported": "The message is already [reported]", "anon": "User is anonymous. Ask admins to disable anonymouse admins to moderate admin behavior.", "bot": "Bots can't be reported.", - "errorAdmin": "Admin reports are disabled. Admin reporting can be enabled with `/adminreportable`", + "admin": "Admin reports are disabled. Admin reporting can be enabled with `/adminreportable`", "norules": "No rules found for this message.", "noallowance": "You have exhausted your daily report allowance." }, "getReports" :{ - "noReports": "No reports for user ", + "noReports": "No reports", "broke": "broke the rules.", "nobreak": "did not break the rules.", "reportFinal": "final", @@ -132,7 +132,7 @@ "reportMessage2": "backup", "reportMessage3": "Report", "reportMessage4": "current answer", - "ReportsFor": "Local reports for" + "ReportsFor": "Local answered reports for" }, "socialConsensus" : { "confirm": "confirm", @@ -165,8 +165,8 @@ }, "start": { "start1": "Hi! My community moderation tools are at your service. [DM]", - "start2": " me to find out more about how to use me to my full potential : )\n\n - /setrules to change the default [rules]", - "start3": "\n - /report messages by reply.\n\nI inform the group about content moderation outcomes and deliver a reccomendation for the admin to take action. My recommended penalties (1 day, 1 week, 1 year) can automatically apply by turning on the /enforce setting.\n\n", + "start2": " me to find out more about how to use me to my full potential : )\n\n- /setrules to change the default [rules]", + "start3": "\n- /report messages by reply.\n- /setchannel create a moderation notification channel\n\nSuccessful reports result in escalating penalties (1 day, 1 week, 1 month, 1 year ban).\n\n", "private": "Hi! My name is Susie, nice to meet you : )\n\nI am a [Kleros Moderate](https://kleros.io/moderate) community manager at your service. Use /help to learn how to use me to my full potential.\n\nJoin @SusieSupport to get information on all the latest updates.", "add": "Add me to your group!", "already": "Already started." @@ -177,26 +177,26 @@ "defaultRules": "https://ipfs.kleros.io/ipfs/Qme3Qbj9rKUNHUe9vj9rqCLnTVUCWKy2YfveQF8HiuWQSu/Kleros%20Moderate%20Community%20Rules.pdf", "index": { "supergroup": "Hi! I'm Susie, a moderation and group management bot. I can only manage supergroups. To promote this group to a supergroup, make the group public or promote any member to a full admin and try to /start me again.", - "channel": "The channel id is ${myChatMember.chat.id}", + "channel": "The channel id is ", "topicMode": "Started topic mode", "topicError": "Susie cannot manage groups in topic mode with out permission to manage topics. Please ask an admin to enable this permission to allow Susie to continue help moderating your community. Then try to /start." }, "help": { "DM": "Get Help (DM)", "DM2": "DM me for help : )", - "help": "*Help*\n\nHi! My name is Susie. I'm a [Kleros Moderate](https://kleros.io/moderate) bot, here to help you manage your groups!\n\nAs groups grow, so do their moderation problems. We're all busy people who don't have time to monitor groups 24/7. Users often complain about admin abuse and have no recourse. Who moderates the moderator? Presenting [Kleros Moderate](https://kleros.io/moderate), a crowd-sourced content moderation tool using [Reality.eth](https://reality.eth.limo/) and [Kleros](https://kleros.gitbook.io/docs/) on [Gnosis Chain](https://www.gnosis.io/).\n\nWhen users are reported, a question is created on Reality.Eth asking 'did the user break the rules?'. The question can be answered yes/no with a bond (5 DAI). When Susie is an admin, successful reports result in penalties, otherwise Susie recommends admins to take action but does not ban any users herself.\n\n- 1st Report: 1 day ban\n- 2nd Report: 1 week ban\n- 3rd Report: 1 year ban\n\nAnswers to reports can be disputed, creating a case in the Kleros court.\n\nHelpful commands:\n - /start: Starts me. You probably already used this.\n - /help: Sends this message to tell you more about myself.\n\nSelect a feature to learn more. My [documentation](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator) is also helpful, or ask a question in @SusieSupport." + "help": "*Help*\n\nHi! My name is Susie. I'm a [Kleros Moderate](https://kleros.io/moderate) bot, here to help you manage your groups!\n\nAs groups grow, so do their moderation problems. Users often complain about admin abuse and have no recourse. Who moderates the moderator? Presenting [Kleros Moderate](https://kleros.io/moderate), a crowd-sourced content moderation tool using [Reality.eth](https://reality.eth.limo/) and [Kleros](https://kleros.gitbook.io/docs/) on [Gnosis Chain](https://www.gnosis.io/).\n\nWhen users are reported, a question is created on Reality.Eth asking 'did the user break the rules?'. The question can be answered yes/no with a bond (5 DAI). Successful reports result in penalties (1 day, 1 week, 1 month, 1 year escalating bans).\n\nAnswers to reports can be disputed, creating a case in the Kleros court.\n\nHelpful commands:\n - /start: Starts me. You probably already used this.\n - /help: Sends this message to tell you more about myself.\n\nSelect a feature to learn more. My [documentation](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator) is also helpful, or ask a question in @SusieSupport." , "back": "back", - "Greeting1": "👋 *Greeting* 👋\n\nWelcome your members with a greeting informing them of the group rules.\n\n*Admin commands:*\n- `/welcome` : Toggles on/off welcomes messages.\n- `/captcha` : Toggles on/off rules captcha.\n\nAfter 5 minutes, the previous welcome messages will get deleted\n\nCaptchas remain for up to 5 minutes. If a user forgets to respond within 5 minutes, they should rejoin the group to prompt a new captcha.", - "Language1": "🗣️ *Languages* 🗣️\n\nSusie's replies can be changed to one of the languages below.\n- EN (English)\n- ES (Español)\n\n*Admin commands*: \n- `/lang`: Set your preferred language.\n\nContent moderation requires a nuanced understanding of context and language. Setting a language not only changes Susie's responses, but also specifies language skilled jurors.\n\nPlease make sure to set the appropriate language for your community for effective moderation.", + "Greeting1": "👋 *Greeting* 👋\n\nWelcome your members with a greeting informing them of the group rules.\n\n*Admin commands:*\n- `/welcome` : Toggles on/off welcomes messages.\n- `/captcha` : Toggles on/off rules captcha.\n\nAfter 5 minutes, the previous welcome messages will get deleted\n\nSusie requires admin privileges to enforce captchas (new users muted by default, until solving the captcha). Captchas remain for up to 5 minutes. If a user forgets to respond within 5 minutes, they should rejoin the group to prompt a new captcha.", + "Language1": "🗣️ *Languages* 🗣️\n\nSusie's replies can be changed to one of the languages below.\n- EN (English)\n- ES (Español)\n\n*Admin commands*: \n- `/lang`: Set your preferred language.\n\nContent moderation requires a nuanced understanding of context and language. Please make sure to set the appropriate language for your community for effective moderation.", "Topics1": "ℹ️ *Topics* ℹ️\n\nTopics allow large groups to focus discussion in dedicated **topic** chats. Susie supports topics. When changing a group to topic mode, you will need to /start Susie again.\n\n*Admin commands*:\n- `/start`: Start topic mode.", - "Evidence1": "🔍 *Evidence* 🔍\n\nTo prevent important messages from deletion, pre-emptively, messages can be saved as evidence.\n\nNote that Susie uses a proxy contract to efficiently batch reports. In case of dispute over authenticity, evidence submitted by the Kleros Moderate bot is time stamped in chat. Moreover, this timestamp should be consistent with any evidence submitted by the bot address through the transaction batching contract.\n\n*User commands*:\n- `/evidence` : Reply to a message to add it as evidence.\n- `/getaccount`: Gets bot and transaction batcher addresses.", - "Report1": "🚨 *Report* 🚨\n\nWhen users are reported, a question is created on Reality.Eth asking 'did the user break the rules?'. The question can be answered yes/no with a bond (5 DAI). Successful reports result in penalties,\n\n- 1st Report: 1 day ban\n- 2nd Report: 1 week ban\n- 3rd Report: 1 year ban\n\nWhen Susie is not an admin, she only reccomends the admins to take action.\n\nAnswers to reports can be disputed, creating a case in the Kleros court.\n\n*User commands*:\n- `/report` : Reply to a message to report it\n- `/info`: Returns active reports\n- `/info` : Returns active reports for user", - "Rules1": "📄 *Rules* 📄\n\nEvery groups starts with [default rules](https://ipfs.kleros.io/ipfs/QmYYcNfEYLtxPM8fof4wf9Tqj7gBGMDMmNnBqZKR1zSczX/Kleros%20Moderate%20Community%20Guidelines%20v1.pdf). Crafting precise policies can be challenging.\n\n***Rule Writing Tips***:\n\n- Start with a preamble defining the group culture.\n- Number each rule.\n- Be specific.\n\n***Bad Example***:\n\n- Users must not send immoral messages\n- Users must not send unethical messages\n\nThese rules are too abstract and do not describe the culture nor context of the group.\n\n***Good Example***:\n\nAs a vegan community, we adopt these rules with the goals of sharing lifestyle tips (recipes, sustainable clothing, etc) in an environment of mutual respect.\n\n1. Users must not encourage immoral behavior eg. encouraging meat consumption.\n2. Users must not engage in unethical behavior eg. stealing credit for vegan recipies.\n\nThese rules include a define the group culture in the preamble, are numbered, and are specific.\n\n*User commands*:\n- `/rules`: Returns current rules\n*Admin commands*:\n- `/setrules` : Sets the rules to the the url\n- `/setrules` : Sets the rules to a replied message", - "Court1": "`⚖️ *Court* ⚖️\n\nContent moderation questions are resolved by the [Kleros Court](https://kleros.gitbook.io/docs/) with a jury of moderators. If the jury made a mistake, the case can be appealed, drawing a larger pool of jurors and providing an opportunity to provide more context, analysis, and arguments.\n\nIf you would like a chance to serve as a jury member, get PNK ([Gnosis Chain](https://swapr.eth.link/#/swap?chainId=100) or [Mainnet](https://app.uniswap.org/#/swap?outputCurrency=0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d&inputCurrency=ETH)) and [stake](https://court.kleros.io/) in the Kleros court.\n\nTo discuss the merits of a dispute, see @klerosjuror.`", - "Lawyer1": "🧑‍⚖️ *Find a Lawyer* 🧑‍⚖️\n\nDisputes over reported behavior can be complicated and nuanced. Often, disputes resolve on the merits of the message and rules alone. In some cases, disputes are better resolved by presenting the court with analysis and arguments.\n\nIf you would like to offer your services as a lawyer or solicit services, please join this [group](https://t.me/+9fvGGkGfSZ1hZDBk).", + "Evidence1": "🔍 *Evidence* 🔍\n\nTo prevent important messages from deletion, pre-emptively, messages can be saved as evidence.\n\n*User commands*:\n- `/evidence` : Reply to a message to add it as evidence.", + "Report1": "🚨 *Report* 🚨\n\nWhen users are reported, a question is created on Reality.Eth asking 'did the user break the rules?'. The question can be answered yes/no with a bond (5 DAI). Successful reports result in escalating penalties (1 day, 1 week, 1 month, 1 year bans).\n\nIn trial mode, Susie only recommends admins to take action to penalize users who break the rules. Trial mode is helpful for admins who want to try out Susie's moderation crowdsourcing.\n\nAnswers to reports can be disputed, creating a case in the Kleros court.\n\n*User commands*:\n- `/report` : Reply to a message to report it\n- `/info`: Returns active reports\n\n*Admin commands*:\n-`/adminreportable` Toggles reportability of admins.\n- `/trial` Toggles trial mode in which Susie does not penalize users, but only recommends admins to take action.", + "Rules1": "📄 *Rules* 📄\n\nEvery groups starts with [default rules](https://ipfs.kleros.io/ipfs/Qme3Qbj9rKUNHUe9vj9rqCLnTVUCWKy2YfveQF8HiuWQSu/Kleros%20Moderate%20Community%20Rules.pdf). Crafting effective comprehensive rules can be challenging.\n\n***Rule Writing Tips***:\n\n- Start with a preamble defining the group culture.\n- Number each rule.\n- Be specific.\n\n***Bad Example***:\n\n- Users must not send immoral messages\n- Users must not send unethical messages\n\nThese rules are too abstract and do not describe the culture nor context of the group.\n\n***Good Example***:\n\nAs a vegan community, we adopt these rules with the goals of sharing lifestyle tips (recipes, sustainable clothing, etc) in an environment of mutual respect.\n\n1. Users must not encourage meat consumption.\n2. Users must credit sources. Stealing credit for vegan recipies is unacceptable.\n\nThese rules include a define the group culture in the preamble, are numbered, and are specific.\n\n*User commands*:\n- `/rules`: Returns current rules\n*Admin commands*:\n- `/setrules` : Sets the rules to the the url\n- `/setrules` : Sets the rules to a replied message", + "Court1": "⚖️ *Court* ⚖️\n\nContent moderation questions are resolved by the [Kleros Court](https://kleros.gitbook.io/docs/) with a jury of moderators. If the jury made a mistake, the case can be appealed, drawing a larger pool of jurors and providing an opportunity to provide more context, analysis, and arguments.\n\nIf you would like a chance to serve as a jury member, get PNK ([Gnosis Chain](https://swapr.eth.link/#/swap?chainId=100) or [Mainnet](https://app.uniswap.org/#/swap?outputCurrency=0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d&inputCurrency=ETH)) and [stake](https://court.kleros.io/) in the Kleros court.\n\nTo discuss the merits of a dispute, see @klerosjuror. To learn more about Kleros, ask a question in @Kleros", + "Lawyer1": "🧑‍⚖️ *Find a Lawyer* 🧑‍⚖️\n\nDisputes over reports can be complicated. Disputes often resolve on the merits of the message and rules alone. In some cases, disputes are better resolved by presenting the court with analysis and arguments.\n\nIf you would like to offer your services as a lawyer or solicit services, please join this [group](https://t.me/+9fvGGkGfSZ1hZDBk).", "Privacy1": "🕵️ *Privacy* 🕵️\n\nEffective moderation depends on access to the full context of a reported message. To provide context, users can request Susie to save messages to submit as evidence on their behalf. Susie manages moderation private and public groups differently,\n\n- In *private* groups, moderators depend on evidence submissions alone.\n- In *public* groups, Susie invites moderators to join the group and investigate message context.", "Notifications1": "🔔 *Notifications* 🔔\n\nSusie sends notifications about moderation actions and report updates. These notifications are restricted to a separate chat in topic mode. In regular Telegram groups, notifications can be sent to a notification channel to avoid cluttering the main chat.\n\nHow to enable notification channels:\n\n1. Make a channel\n2. Add Susie\n3. Susie will send a channel ID\n4. Use that channel ID to set notifications with /setchannel in the original group\n\n*User commands*:\n- `/notifications`: Returns current notification channel\n*Admin commands*:\n- `/setchannel` : Sets the notification channel to the specified channel id\n- `/setfedchannel` : Sets the notification channel for your federation to the specified channel id", - "Federations1": "🌐 *Federations*\n\nModerating a single group is hard, but managing multiple is even harder? Do you have to ban spammers manually, in all your groups?\n\nNo more! With federations, Susie can enforce a ban on a user in all federate groups.\n\n*User commands*:\n- `/fedinfo`: Returns current federation\n*Admin commands*:\n- `/newfed`: Creates a federation\n- `/joinfed`: Joins the current group to a Federation", + "Federations1": "🌐 *Federations*\n\nModerating a single group is hard, but managing multiple is even harder. Do you have to ban spammers manually, in all your groups?\n\nNo more! With federations, Susie can enforce a ban on a user in all federatec groups.\n\n*User commands*:\n- `/fedinfo`: Returns current federation\n*Admin commands*:\n- `/newfed`: Creates a federation\n- `/joinfed`: Joins the current group to a Federation", "Gnosis1": "⛓️ *Gnosis Chain* ⛓️\n\nSusie uses [xDAI](https://docs.gnosischain.com/about/tokens/xdai), a stable coin, on [Gnosis Chain](https://www.gnosis.io/). Don't know what that means? It means Susie uses a cheap and fast public ledger to coordinate moderation fairly and transparently.\n\nDon't have any xDAI on Gnosis Chain? No problem, there's a (cheap, fast) [bridge](https://bridge.connext.network/?receivingChainId=100&receivingAssetId=0x0000000000000000000000000000000000000000) for that. \n\nWhat's crypto? I heard about that on the news, I don't want anything to do with crypto. No problem, you can ask for help from freelance moderators in @SusieSupport.\n\nDon't have any cryptocurrency? No problem, there's a convinient [fiat on-ramp](https://www.mtpelerin.com/buy-xdai) (credit card or bank transfer) to buy DAI on Gnosis Chain.\n\nNeed help adding the Gnosis Chain network to your wallet? Don't worry, there's a [guide](https://docs.gnosischain.com/tools/wallets/metamask#2-configure) for that.\n\nNeed more help? Don't worry, there's a @SusieSupport group for that", "Greeting": "👋 Greeting", "Language": "🗣️ Language", @@ -223,7 +223,18 @@ "notifications": { "getfed": "Las notificaciones para la federación de este grupo se envían a este [canal].", "notset": "El canal de notificaciones para este grupo no está configurado. Pida a un administrador `/setchannel`.", - "get": "Envío notificaciones de moderación a este [canal]" + "get": "Envío notificaciones de moderación a este [canal]", + "set": "/setchannel debe ir seguido de un identificador de canal. Si necesitas más ayuda, ", + "invalid": "/setchannel debe ir seguido de un canal válido.", + "invalid2": "no es un canal válido.", + "admin": "No eres un administrador autorizado del canal.", + "invite": "Necesito permisos para invitar usuarios al canal.", + "confirm1": "Las notificaciones de moderación se enviarán ahora a este [canal]", + "confirm2": "Este canal ahora transmitirá notificaciones de moderación para" + }, + "enforcement":{ + "off": "Modo de prueba desactivado. Ahora aplico penalizaciones a los usuarios que incumplen las normas", + "on": "Modo de prueba activado. Ahora sólo recomiendo a los administradores que tomen medidas cuando se infringen las normas." }, "fed": { "specify" : "Especifique una federación, por ejemplo `/joinfed `.", @@ -236,7 +247,14 @@ "create2": "DM mí para obtener ayuda con su federación : )", "exists": "Su federación ya existe:", "name": "Nombre su federación, `/newfed Mi nueva federación`.", - "created": "Su nueva federación está creada.\n\nEs muy recomendable crear un canal de notificación para su federación con `/setfedchannel` para que la moderación pueda ser fácilmente supervisada en toda la federación en un solo lugar.\n\nPuede añadir grupos a su federación enviando `/joinfed" + "created": "Su nueva federación está creada.\n\nEs muy recomendable crear un canal de notificación para su federación con `/setfedchannel` para que la moderación pueda ser fácilmente supervisada en toda la federación en un solo lugar.\n\nPuede añadir grupos a su federación enviando `/joinfed", + "notfound2": "No se ha encontrado ninguna federación. Por favor, cree primero una federación con `/newfed`", + "specify2": "/setchannelfed debe ir seguido de un identificador de canal. Si necesita más ayuda", + "invalid": "/setchannelfed debe ir seguido de un canal válido.", + "invalid2": "no es un canal válido.", + "auth": "No eres un administrador autorizado del canal.", + "confirm1": "Las notificaciones de moderación de la federación se enviarán ahora a este [canal]", + "confirm2": "Este canal retransmitirá ahora las notificaciones de moderación para la federación" }, "getAccount": "Bot dirección", "info": { @@ -253,7 +271,7 @@ "off": "Captcha está desactivado." }, "getReports" :{ - "noReports": "No hay informes para el usuario ", + "noReports": "No hay informes", "broke": "rompió las reglas.", "nobreak": "no rompió las reglas.", "reportFinal": "final", @@ -265,7 +283,7 @@ "reportMessage2": "backup", "reportMessage3": "Informe", "reportMessage4": "respuesta actual", - "ReportsFor": "Informes locales para" + "ReportsFor": "Informes locales contestados para" }, "rules" : "La conducta de los usuarios se modera de acuerdo con las siguientes [reglas]", "rulesUpdated" : "Normas [actualizadas]", @@ -294,8 +312,7 @@ "Option": "Opción", "Evidence": "Pruebas", "MessageSent": "Mensaje enviado", - "Desc1": "Comprueba que la cuenta bot del chat con /getaccount coincide con la dirección de envío de esta prueba automatizada, para asegurarte de su autenticidad.", - "Desc2": "El archivo adjunto es un registro de copia de seguridad de un mensaje enviado en el chat," + "Desc1": "Envío de pruebas automatizado por el bot Kleros Moderate. Por favor, compruebe la autenticidad. El archivo adjunto es un registro de copia de seguridad de un mensaje enviado en el chat." }, "multilang": { "en": "Grupo inglés conectado", @@ -314,7 +331,8 @@ "adminbot": "Necesito derechos de administrador para aplicar sanciones (1 día, 1 semana, 1 año).", "topics": "Necesito permisos para gestionar temas.", "txn": "¿La dirección del bot tiene fondos suficientes para pagar la transacción? Se ha producido un error inesperado", - "url": "URL inválido" + "url": "URL inválido", + "setrules": "`/setrules` debe utilizarse en respuesta a un mensaje o seguido de una URL." }, "report": { "expired": "Vive y deja vivir. Este mensaje es de hace más de una semana. La próxima vez intenta hacer el informe antes.", @@ -335,16 +353,17 @@ }, "index": { "supergroup": "Hola, soy Susie, un bot de moderación y gestión de grupos. Sólo puedo gestionar supergrupos. Para promover este grupo a un supergrupo, haz público el grupo o promueve a cualquier miembro a administrador completo e intenta /start me de nuevo.", - "channel": "El ID del canal es ${myChatMember.chat.id}", + "channel": "El ID del canal es ", "topicMode": "Modo de tema iniciado", "topicError": "Susie no puede gestionar grupos en modo tema si no tiene permiso para gestionar temas. Pide a un administrador que habilite este permiso para que Susie pueda seguir ayudando a moderar tu comunidad. A continuación, intente /start." }, "start": { "start1": "Hola! Mis herramientas de moderación comunitaria están a tu servicio. Envíame un [DM]", - "start2": " para saber más sobre cómo aprovechar todo mi potencial. : )\n\n - /setrules para cambiar las [reglas]", - "start3": "\n - /report mensajes por respuesta.\n\nInformo al grupo sobre los resultados de la moderación de contenidos y entrego una reccomendación para que el admin tome medidas.\n\nPromoverme a un admin para aplicar las sanciones reccomendadas automáticamente. Mis sanciones recomendadas (1 día, 1 semana, 1 año) pueden aplicarse automáticamente activando la opción /enforce.", + "start2": " para saber más sobre cómo aprovechar todo mi potencial. : )\n\n- /setrules para cambiar las [reglas]", + "start3": "\n- /report mensajes por respuesta.\n- /setchannel crear un canal de notificación de moderación\n\nLos reportes exitosos resultan en penalizaciones escaladas (1 día, 1 semana, 1 mes, 1 año de baneo).", "private": "Hola, me llamo Susie, encantada de conocerte : )\n\nSoy una [Kleros Moderate](https://kleros.io/moderate) community manager a tu servicio. Utiliza /help para aprender a utilizarme en todo mi potencial.\n\nÚnete a mi canal de noticias @KlerosModerateNews para informarte de todas las últimas actualizaciones.", - "add": "Añádeme a tu grupo!" + "add": "Añádeme a tu grupo!", + "already": "Ya comenzó." }, "welcome": { "welcome": "Hola, soy Susie, un bot [Kleros Moderate](https://kleros.io/moderate/). Necesito permiso de un administrador para /start. \n\n¿Cómo ayudo a resolver preguntas sobre moderación de contenidos?\n\n1.Pregunto \"¿Un usuario ha infringido las normas?\" en la plataforma de crowdsourcing [Reality.Eth](https://realityeth.github.io/).\n2. Cualquiera puede responder dejando un bono (xDai en Gnosis Chain).\n3. Cualquiera puede impugnar la respuesta y [Kleros](https://kleros.io/), el tribunal descentralizado, resuelve la pregunta.\n\nPara saber más, lee mi [documentación](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie), haz una pregunta en @SusieSupport, o [DM](https://t.me/${process.env.BOT_USERNAME}?start=help) para obtener ayuda." @@ -353,15 +372,15 @@ "help": { "DM": "Obtener ayuda (DM)", "DM2": "DM de ayuda : )", - "help": "*Ayuda*\n\nHi! Me llamo Susie. Soy un [Kleros Moderate](https://kleros.io/moderate) bot, aquí para ayudarles a gestionar sus grupos!\n\nA medida que los grupos crecen, también lo hacen sus problemas de moderación. Todos estamos muy ocupados y no tenemos tiempo para supervisar los grupos 24 horas al día, 7 días a la semana. Los usuarios suelen quejarse de los abusos de los administradores y no tienen ningún recurso. ¿Quién modera al moderador? Presentamos [Kleros Moderate](https://kleros.io/moderate), una herramienta de moderación de contenidos de origen colectivo que utiliza [Reality.eth](https://reality.eth.limo/) y [Kleros](https://kleros.gitbook.io/docs/) con [Gnosis Chain](https://www.gnosis.io/).\n\nCuando los usuarios son denunciados, se crea una pregunta en Reality.Eth preguntando \"¿el usuario rompió las reglas?\". La pregunta puede responderse sí/no con un bono (5 DAI). Cuando Susie es una admin, los reportes exitosos resultan en penalizaciones, de lo contrario Susie recomienda a los admins que tomen acción pero no banea a ningún usuario ella misma.\n\n- 1º Report: 1 día de prohibición\n- 2º Report: 1 semana de prohibición\n- 3º Report: 1 año de prohibición\n\nLas respuestas a los informes pueden impugnarse, creando un caso en el tribunal de Kleros.\n\nComandos útiles:\n - /start: Empieza yo. Probablemente ya usaste esto.\n - /help: Envía este mensaje para contarte más cosas sobre mí.\n\nSeleccione una función para obtener más información. Mi [documentación](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator) también es útil, o haz una pregunta en @SusieSupport." + "help": "*Ayuda*\n\nHi! Me llamo Susie. Soy un [Kleros Moderate](https://kleros.io/moderate) bot, aquí para ayudarles a gestionar sus grupos!\n\nA medida que los grupos crecen, también lo hacen sus problemas de moderación. Los usuarios suelen quejarse de los abusos de los administradores y no tienen ningún recurso. ¿Quién modera al moderador? Presentamos [Kleros Moderate](https://kleros.io/moderate), una herramienta de moderación de contenidos de origen colectivo que utiliza [Reality.eth](https://reality.eth.limo/) y [Kleros](https://kleros.gitbook.io/docs/) con [Gnosis Chain](https://www.gnosis.io/).\n\nCuando los usuarios son denunciados, se crea una pregunta en Reality.Eth preguntando \"¿el usuario rompió las reglas?\". La pregunta puede responderse sí/no con un bono (5 DAI). Las denuncias acertadas dan lugar a sanciones (1 día, 1 semana, 1 mes, 1 año de prohibición escalonada).\n\nLas respuestas a los informes pueden impugnarse, creando un caso en el tribunal de Kleros.\n\nComandos útiles:\n - /start: Empieza yo. Probablemente ya usaste esto.\n - /help: Envía este mensaje para contarte más cosas sobre mí.\n\nSeleccione una función para obtener más información. Mi [documentación](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator) también es útil, o haz una pregunta en @SusieSupport." , "back": "back", "Greeting1": "👋 *Saludos* 👋\n\nDa la bienvenida a tus miembros con un saludo informándoles de las reglas del grupo.\n\n*Comandos de administrador:*\n- `/welcome` : Activa/desactiva los mensajes de bienvenida.\n- `/captcha` : Activa/desactiva el captcha de las reglas.\n\nDespués de 5 minutos, los mensajes de bienvenida anteriores se borrarán.\n\nLos captchas permanecen hasta 5 minutos. Si un usuario se olvida de responder en 5 minutos, debe volver a unirse al grupo para solicitar un nuevo captcha.", "Language1": "🗣️ *Idiomas* 🗣️\n\nLas respuestas de Susie se pueden cambiar a uno de los siguientes idiomas.\n- EN (English)\n- ES (Español)\n\n*Comandos de administración*: \n- `/lang` : Establezca su idioma preferido.\n\nLa moderación de contenidos requiere una comprensión matizada del contexto y el lenguaje. Establecer un idioma no sólo cambia las respuestas de Susie, sino que también especifica el idioma de los jurados cualificados.\n\nPor favor, asegúrese de establecer el idioma apropiado para su comunidad para una moderación efectiva.", "Topics1": "ℹ️ *Temas* ℹ️\n\nLos temas permiten a los grandes grupos centrar el debate en chats dedicados a **temas**. Susie es compatible con los temas. Cuando cambie un grupo a modo de tema, necesitará /iniciar Susie de nuevo.\n\n*Comandos de administrador*:\n- `/start`: Inicia el modo por temas.", - "Evidence1": "🔍 *Evidencia* 🔍\n\nPara evitar que se borren mensajes importantes, de forma preventiva, los mensajes pueden guardarse como pruebas.\nNNTen en cuenta que Susie utiliza un contrato proxy para procesar eficazmente los informes por lotes. En caso de disputa sobre la autenticidad, las pruebas presentadas por el bot Kleros Moderate llevan un sello de tiempo en el chat. Además, esta marca de tiempo debe ser coherente con cualquier evidencia presentada por la dirección bot a través del contrato de procesamiento por lotes de transacciones.\n\n*Comandos de usuario*:\n- `/evidence` : Responde a un mensaje para añadirlo como evidencia.\n- `/getaccount`: Obtiene direcciones de bots y batchers de transacciones.", - "Report1": "🚨 *Report* 🚨\n\nCuando los usuarios son denunciados, se crea una pregunta en Reality.Eth preguntando \"¿el usuario rompió las reglas?\". La pregunta puede responderse sí/no con un bono (5 DAI). Los reportes exitosos resultan en penalizaciones,\n\n- 1er Reporte: 1 día de suspensión- 2º Informe: 1 semana de prohibición: 1 año de baneo\n\nCuando Susie no es admin, solo recomienda a los admins que tomen medidas.\n\nLas respuestas a los reportes pueden ser disputadas, creando un caso en la corte de Kleros.\n\n*Comandos de usuario*:\n- `/report` : Responde a un mensaje para denunciarlo- `/info`: Devuelve los informes activos- `/info` : Devuelve los informes activos del usuario", - "Rules1": "📄 *Reglas* 📄\n\nTodos los grupos empiezan con [reglas por defecto](https://ipfs.kleros.io/ipfs/QmSHAjfD1MYPtyopFoXcUQ5Ny3sfs5re1yz3h3TZ5qGDsp/Kleros%20Moderate%20Normas%20comunitarias.pdf). Elaborar políticas precisas puede ser todo un reto.\n\n*Consejos para redactar reglas***:\n\n- Empieza con un preámbulo que defina la cultura del grupo.\n- Numera cada regla.\n- Sé específico.\n\n*Mal ejemplo***:\n\n- Los usuarios no deben enviar mensajes inmorales\n- Los usuarios no deben enviar mensajes poco éticos.\n\nEstas reglas son demasiado abstractas y no describen la cultura ni el contexto del grupo.\n\n*Buen ejemplo***:\n\nComo comunidad vegana, adoptamos estas reglas con el objetivo de compartir consejos de estilo de vida (recetas, ropa sostenible, etc.) en un entorno de respeto mutuo.\n\n1. Los usuarios no deben fomentar comportamientos inmorales, por ejemplo, fomentar el consumo de carne.\n2. Los usuarios no deben tener un comportamiento poco ético, por ejemplo, robar el crédito por recetas veganas.\n\nEstas reglas incluyen una definición de la cultura del grupo en el preámbulo, están numeradas y son específicas\n\ncomandos útiles:\n- `/rules`: Devuelve las reglas actuales.\n*Comandos de administrador*:\n- `/setrules` : Establece las reglas a la url\n- `/setrules` : Establece las reglas a un mensaje respondido.", - "Court1": "`⚖️ *Corte* ⚖️\n\nLas cuestiones de moderación de contenidos las resuelve el [Kleros Court](https://kleros.gitbook.io/docs/) con un jurado de moderadores. Si el jurado cometió un error, el caso puede ser apelado, atrayendo a un grupo más grande de miembros del jurado y proporcionando la oportunidad de proporcionar más contexto, análisis y argumentos.\n\nSi desea tener la oportunidad de servir como miembro del jurado, obtenga PNK ([Gnosis Chain](https://swapr.eth.link/#/swap?chainId=100) o [Mainnet](https://app.uniswap.org/#/swap?outputCurrency=0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d&inputCurrency=ETH)) y [stake](https://court.kleros.io/) en el tribunal de Kleros.\n\nPara discutir el fondo de una disputa, consulte @klerosjuror.`", + "Evidence1": "🔍 *Evidencia* 🔍\n\nPara evitar que se borren mensajes importantes, de forma preventiva, los mensajes pueden guardarse como pruebas.\n\n*Comandos de usuario*:\n- `/evidence` : Responde a un mensaje para añadirlo como evidencia.", + "Report1": "🚨 *Report* 🚨n\nCuando se reportan usuarios, se crea una pregunta en Reality.Eth preguntando \"¿el usuario rompió las reglas?\". La pregunta puede responderse sí/no con un bono (5 DAI). Los reportes exitosos resultan en sanciones escalonadas (1 día, 1 semana, 1 mes, 1 año de prohibición).\nEn el modo de prueba, Susie sólo recomienda a los administradores tomar medidas para sancionar a los usuarios que rompen las reglas.\nLas respuestas a los reportes pueden ser impugnadas, creando un caso en el tribunal de Kleros.\nComandos de usuario*:\n- `/report` : Responde a un mensaje para denunciarlo- `/info`: Devuelve los informes activos.n\n*Comandos de administrador*:\n-`/adminreportable` Activa la posibilidad de informar sobre los administradores.\n- `/trial` Activa el modo ensayo. Susie aplicará las penalizaciones automáticamente.", + "Rules1": "📄 *Reglas* 📄\n\nTodos los grupos empiezan con [reglas por defecto](https://ipfs.kleros.io/ipfs/QmSHAjfD1MYPtyopFoXcUQ5Ny3sfs5re1yz3h3TZ5qGDsp/Kleros%20Moderate%20Normas%20comunitarias.pdf). Elaborar políticas precisas puede ser todo un reto.\n\n*Consejos para redactar reglas***:\n\n- Empieza con un preámbulo que defina la cultura del grupo.\n- Numera cada regla.\n- Sé específico.\n\n*Mal ejemplo***:\n\n- Los usuarios no deben enviar mensajes inmorales\n- Los usuarios no deben enviar mensajes poco éticos.\n\nEstas reglas son demasiado abstractas y no describen la cultura ni el contexto del grupo.\n\n*Buen ejemplo***:\n\nComo comunidad vegana, adoptamos estas reglas con el objetivo de compartir consejos de estilo de vida (recetas, ropa sostenible, etc.) en un entorno de respeto mutuo.\n\n1. Los usuarios no deben fomentar el consumo de carne.\n2. Los usuarios no deben robar el crédito por recetas veganas.\n\nEstas reglas incluyen una definición de la cultura del grupo en el preámbulo, están numeradas y son específicas\n\ncomandos útiles:\n- `/rules`: Devuelve las reglas actuales.\n*Comandos de administrador*:\n- `/setrules` : Establece las reglas a la url\n- `/setrules` : Establece las reglas a un mensaje respondido.", + "Court1": "⚖️ *Corte* ⚖️\n\nLas cuestiones de moderación de contenidos las resuelve el [Kleros Court](https://kleros.gitbook.io/docs/) con un jurado de moderadores. Si el jurado cometió un error, el caso puede ser apelado, atrayendo a un grupo más grande de miembros del jurado y proporcionando la oportunidad de proporcionar más contexto, análisis y argumentos.\n\nSi desea tener la oportunidad de servir como miembro del jurado, obtenga PNK ([Gnosis Chain](https://swapr.eth.link/#/swap?chainId=100) o [Mainnet](https://app.uniswap.org/#/swap?outputCurrency=0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d&inputCurrency=ETH)) y [stake](https://court.kleros.io/) en el tribunal de Kleros.\n\nPara discutir el fondo de una disputa, consulte @klerosjuror.", "Lawyer1": "🧑‍⚖️ *Buscar un Abogado* 🧑‍⚖️\n\nLas disputas sobre el comportamiento denunciado pueden ser complicadas y llenas de matices. A menudo, las disputas se resuelven únicamente sobre el fondo del mensaje y las normas. En algunos casos, las disputas se resuelven mejor presentando al tribunal análisis y argumentos.\n\nSi desea ofrecer sus servicios como abogado o solicitar servicios, únase a este [grupo](https://t.me/+9fvGGkGfSZ1hZDBk).", "Privacy1": "🕵️ *Privacidad* 🕵️\n\nUna moderación eficaz depende del acceso al contexto completo de un mensaje denunciado. Para proporcionar el contexto, los usuarios pueden solicitar a Susie que guarde los mensajes para presentarlos como pruebas en su nombre. Susie gestiona la moderación de los grupos privados y públicos de forma diferente,\n\n- En los grupos *privados*, los moderadores dependen únicamente del envío de pruebas.\n- En los grupos *públicos*, Susie invita a los moderadores a unirse al grupo e investigar el contexto del mensaje.", "Notifications1": "🔔 *Notificaciones* 🔔\n\nSusie envía notificaciones sobre acciones de moderación y actualizaciones de informes. Estas notificaciones están restringidas a un chat separado en modo tema. En grupos regulares de Telegram, las notificaciones pueden ser enviadas a un canal de notificación para evitar saturar el chat principal.\n\nCómo habilitar canales de notificación:\n\n1. Crea un canal\n2. Añade a Susie\n3. Susie enviará un ID de canal\n4. Utiliza ese ID de canal para establecer notificaciones con /setchannel en el grupo original\n\n*Comandos de usuario*:\n- `/notificaciones`: Devuelve el canal de notificaciones actual\n*Comandos de administrador*:\n- `/setchannel` : Establece el canal de notificaciones en el id de canal especificado\n- `/setfedchannel` : Establece el canal de notificaciones para su federación en el id de canal especificado", diff --git a/lib/telegram/commands/addEvidence.ts b/lib/telegram/commands/addEvidence.ts index cca07de..f7199f7 100644 --- a/lib/telegram/commands/addEvidence.ts +++ b/lib/telegram/commands/addEvidence.ts @@ -12,9 +12,14 @@ const Web3 = require('web3') const web3 = new Web3(process.env.WEB3_PROVIDER_URL) const ob = require('urbit-ob') -const contract = new web3.eth.Contract( +const contract_en = new web3.eth.Contract( _contract, - process.env.REALITIO_ARBITRATOR + process.env.REALITIO_ARBITRATOR_EN + ) + + const contract_es = new web3.eth.Contract( + _contract, + process.env.REALITIO_ARBITRATOR_EN ) var botAddress: string; const NodeCache = require( "node-cache" ); @@ -40,7 +45,7 @@ const processCommand = async (queue: any, bot: any, settings: groupSettings, msg } catch(e){ console.log(e) } - submitEvidence(batchedSend, evidenceJsonPath, questionId); + submitEvidence(batchedSend, evidenceJsonPath, questionId, settings.lang); return evidenceJsonPath; } @@ -110,8 +115,8 @@ const uploadFileEvidence = async (filePath: string, fileName: string): Promise => { const enc = new TextEncoder(); - var author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' ID:'+msg.reply_to_message.from.id ; - var chatmsg = `${msg.chat.title} (${langJson[lang].addevidence.Chat} ID: ${msg.chat.id})` + var author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' (ID:'+msg.reply_to_message.from.id+')' ; + var chatmsg = `${msg.chat.title} (ID: ${msg.chat.id})` //if(isPrivate){ // const hashedUserID = web3.utils.sha3(String(msg.reply_to_message.from.id)+process.env.secret); // author = ob.patp(hashedUserID.substring(0,8)) @@ -176,8 +181,8 @@ ${langJson[lang].addevidence.Message} (${langJson[lang].addevidence.Poll}): \n } const uploadTextEvidence = async (lang: string, msg: TelegramBot.Message, isPrivate: boolean): Promise => { - var author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' ID:'+msg.reply_to_message.from.id ; - var chatmsg = `${msg.chat.title} (${langJson[lang].addevidence.Chat} ID: ${msg.chat.id})` + var author = (msg.reply_to_message.from.username || msg.reply_to_message.from.first_name) + ' (ID:'+msg.reply_to_message.from.id+')' ; + var chatmsg = `${msg.chat.title} ( ID: ${msg.chat.id})` /*if(isPrivate){ const hashedUserID = web3.utils.sha3(String(msg.reply_to_message.from.id)+process.env.secret); author = ob.patp(hashedUserID.substring(0,8)) @@ -243,7 +248,8 @@ const uploadEvidenceJson = async (lang: string, msg: TelegramBot.Message, eviden return evidenceJsonPath; } -const submitEvidence = async (batchedSend: any, evidencePath: string, questionId: number|string) => { +const submitEvidence = async (batchedSend: any, evidencePath: string, questionId: number|string, lang: string) => { + const contract = lang === 'es' ? contract_es : contract_en batchedSend({ args: [ questionId, diff --git a/lib/telegram/commands/getAccount.ts b/lib/telegram/commands/getAccount.ts index 76e8aef..fd9666d 100644 --- a/lib/telegram/commands/getAccount.ts +++ b/lib/telegram/commands/getAccount.ts @@ -1,19 +1,16 @@ import * as TelegramBot from "node-telegram-bot-api"; import {Wallet} from "@ethersproject/wallet"; -import langJson from "../assets/lang.json"; +import langJson from "../assets/langNew.json"; import { groupSettings } from "../../../types"; /* - * /getaccount + * /account */ -const regexp = /\/getaccount/ -var address: string; +const regexp = /\/account/ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { try{ - if (!address) - address = (await new Wallet(process.env.PRIVATE_KEY)).address - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${langJson[settings.lang].getAccount}*: ${address}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}:{parse_mode: "Markdown"})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `*${langJson[settings.lang].getAccount}*: ${process.env.TRANSACTION_BATCHER_CONTRACT_ADDRESS}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}:{parse_mode: "Markdown"})}catch{}}); } catch(e){ console.log('gettaccount error. '+e) } diff --git a/lib/telegram/commands/getReports.ts b/lib/telegram/commands/getReports.ts index aa55d77..bc6eff1 100644 --- a/lib/telegram/commands/getReports.ts +++ b/lib/telegram/commands/getReports.ts @@ -58,12 +58,15 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, let group_id: string; let user_id: string; let federation_id: string; - + if(msg.text.length > 45){ group_id = msg.text.substring(16,30) user_id = msg.text.substring(30,40) federation_id = msg.text.substring(40) - } else if (msg.text.length > 16){ + } else if (msg.text.length > 39){ + user_id = msg.text.substring(30,40) + group_id = msg.text.substring(16,30) + } else if (msg.text.length > 29){ group_id = msg.text.substring(16,30) } else return; diff --git a/lib/telegram/commands/help.ts b/lib/telegram/commands/help.ts index 3520d9a..81b77f7 100644 --- a/lib/telegram/commands/help.ts +++ b/lib/telegram/commands/help.ts @@ -228,6 +228,7 @@ const respond = (queue: any, settings: groupSettings, bot: any, helpType: string break; } case 'court': { + //https://ipfs.kleros.io/ipfs/QmZwVBdfALRWbjCLtLNSq9YceADCtP96hfPkg3Y6f6xWJk/KlerosModerate.png queue.add(async () => {try{await bot.editMessageText(langJson[lang_code].help.Court1,optsResponse)}catch{}}) break; } diff --git a/lib/telegram/commands/report.ts b/lib/telegram/commands/report.ts index 38c4dea..3a7a338 100644 --- a/lib/telegram/commands/report.ts +++ b/lib/telegram/commands/report.ts @@ -77,7 +77,7 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b if (!report) return if(report.status === "administrator" || report.status === "creator"){ - const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.admin}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].report.admin}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}: {parse_mode: "Markdown"}) return val}catch(e){console.log(e)}}); if (!resp) return resp @@ -247,7 +247,7 @@ const reportMsg = async (queue: any, settings: groupSettings, db: any, bot: any, queue.add(async () => {try{bot.sendMessage(settings.channelID, `[${fromUsername}](tg://user?id=${reportedUserID})'s conduct due to this [message](${msgLink}) ([backup](${msgBackup})) is reported for breaking the [rules](${rules}).\n\nDid *${fromUsername}* break the rules? The [question](${appealUrl}) can be answered with a minimum bond of 5 DAI. Need assistance answering the question? [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpgnosis) me for help : )\n\nTo save a record, reply to messages you want saved with \`/evidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: settings.thread_id_notifications , parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); else if (settings.lang === "es") queue.add(async () => {try{bot.sendMessage(settings.channelID, `La conducta de [${fromUsername}](tg://user?id=${reportedUserID}) a este [mensaje](${msgLink}) ([backup](${msgBackup})) es denunciada por infringir las [reglas](${rules}).\n\nHa infringido el usuario *${fromUsername}* las reglas? La [pregunta](${appealUrl}) puede responderse con un bono mínimo de 5 DAI. Necesitas ayuda para responder a la pregunta? [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpgnosis) me para obetener ayuda : )\n\nPara guardar un registro, responda a los mensajes que desee guardar con \`/evidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: settings.thread_id_notifications , parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); - return questionId; + return [appealUrl, evidenceIndex]; } catch (e) { console.log(e); try{ diff --git a/lib/telegram/commands/setRules.ts b/lib/telegram/commands/setRules.ts index 8038263..0675a50 100644 --- a/lib/telegram/commands/setRules.ts +++ b/lib/telegram/commands/setRules.ts @@ -2,7 +2,7 @@ import * as TelegramBot from "node-telegram-bot-api"; import { groupSettings } from "../../../types"; import {setRulesCustom} from "../../db"; import {ipfsPublish} from "../../ipfs-publish"; -import langJson from "../assets/lang.json"; +import langJson from "../assets/langNew.json"; /* * /setrules [ipfs file path] @@ -47,9 +47,11 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, await queue.add(async () => {try{await bot.closeForumTopic(msg.chat.id, settings.thread_id_rules)}catch{}}) } queue.add(async () => {try{await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].rulesUpdated}(${match[1]})`, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); - } else { + } else if (match[1]){ + console.log(match[1]) queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[settings.lang].error.url, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules}: {})}catch{}}); - } + } else + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[settings.lang].error.setrules, msg.chat.is_forum? {message_thread_id: settings.thread_id_rules, parse_mode: "Markdown"}: {parse_mode: "Markdown"})}catch{}}); } catch(e){ console.log(e) } diff --git a/lib/telegram/commands/socialConsensus.ts b/lib/telegram/commands/socialConsensus.ts index 2553675..8622400 100644 --- a/lib/telegram/commands/socialConsensus.ts +++ b/lib/telegram/commands/socialConsensus.ts @@ -56,12 +56,12 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: Teleg } try{ if (newConfirmations > 1){ - queue.add(async () => {try{await bot.editMessageReplyMarkup({ inline_keyboard: []}, optsFinal)}catch{}}) - queue.add(async () => {try{await bot.editMessageText(settings.lang === "en"? "User reported." : "Usuario reportado.",optsFinal)}catch{}}) const user = (await queue.add(async () => {try{const val = await bot.getChatMember(String(msg.chat.id), String(calldata[1])) - return val}catch{}})).user; - const fromUsername = user.username || user.first_name || `no-username-set`; - reportMsg(queue, settings, db, bot, msg, fromUsername, String(calldata[1]), msg.entities[1].url, String(calldata[2]), msg.entities[3].url, calldata[4],calldata[3],batchedSend); + return val}catch{}})).user; + const fromUsername = user.username || user.first_name || `no-username-set`; + const [appealURL, evidenceIndex] = await reportMsg(queue, settings, db, bot, msg, fromUsername, String(calldata[1]), msg.entities[1].url, String(calldata[2]), msg.entities[3].url, calldata[4],calldata[3],batchedSend); + queue.add(async () => {try{await bot.deleteMessage(msg.chat.id, msg.message_id)}catch{}}) + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, settings.lang === "en"? `User [reported](${appealURL}). Add evidence with \`/evidence ${evidenceIndex}\`` : `Usuario [reportado](${appealURL}). Añadir pruebas con \`/evidence ${evidenceIndex}\``,{disable_web_page_preview: true, parse_mode: "Markdown"})}catch{}}) } else{ queue.add(async () => {try{await bot.editMessageReplyMarkup(markdown, opts)}catch{}}) } diff --git a/lib/telegram/commands/start.ts b/lib/telegram/commands/start.ts index 3793b36..4aa63fe 100644 --- a/lib/telegram/commands/start.ts +++ b/lib/telegram/commands/start.ts @@ -85,12 +85,12 @@ const callback = async (queue:any, db: any, settings: groupSettings, bot: any, b return val}catch{}}) if(!botUser) return - /*if(botUser.status !== "administrator" || !botUser.can_restrict_members){ + if(botUser.status !== "administrator" || !botUser.can_restrict_members){ const video = msg.chat.is_forum? 'QmSdP3SDoHCdW739xLDBKM3gnLeeZug77RgwgxBJSchvYV/guide_topics.mp4' : 'QmbnEeVzBjcAnnDKGYJrRo1Lx2FFnG62hYfqx4fLTqYKC7/guide.mp4' - //queue.add(async () => {try{await bot.sendVideo(msg.chat.id, `https://ipfs.kleros.io/ipfs/${video}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, caption: ""} : {caption: "Please give Susie full admin rights.\n\nThen try to /start community moderation again."})}catch{}}); - //return; + queue.add(async () => {try{await bot.sendVideo(msg.chat.id, `https://ipfs.kleros.io/ipfs/${video}`, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, caption: ""} : {caption: "Please give Susie full admin rights.\n\nThen try to /start community moderation again."})}catch{}}); + return; queue.add(async () => {try{await bot.sendMessage(msg.chat.id, 'I am ', msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id, disable_web_page_preview: true}: {parse_mode: "Markdown", disable_web_page_preview: true})}catch{}}) - }*/ + } if (msg.chat.is_forum){ if(!botUser.can_manage_topics){ queue.add(async () => {try{await bot.sendVideo(msg.chat.id, 'https://ipfs.kleros.io/ipfs/QmSdP3SDoHCdW739xLDBKM3gnLeeZug77RgwgxBJSchvYV/guide_topics.mp4', {message_thread_id: msg.message_thread_id, caption: langJson[lang_code].index.topicError})}catch{}}); diff --git a/lib/telegram/commands/toggleCaptcha.ts b/lib/telegram/commands/toggleCaptcha.ts index b86d87f..ac190a2 100644 --- a/lib/telegram/commands/toggleCaptcha.ts +++ b/lib/telegram/commands/toggleCaptcha.ts @@ -1,7 +1,7 @@ import * as TelegramBot from "node-telegram-bot-api"; import {setCaptchaMode, setGreetingMode} from "../../db"; import * as toggleWelcome from "../../../lib/telegram/commands/toggleWelcome"; -import langJson from "../assets/lang.json"; +import langJson from "../assets/langNew.json"; import {groupSettings} from "../../../types"; /* diff --git a/lib/telegram/commands/toggleEnforcement.ts b/lib/telegram/commands/toggleEnforcement.ts index ce02796..4b835f7 100644 --- a/lib/telegram/commands/toggleEnforcement.ts +++ b/lib/telegram/commands/toggleEnforcement.ts @@ -6,7 +6,7 @@ import {groupSettings} from "../../../types"; /* * /welcome */ -const regexp = /\/enforcement/ +const regexp = /\/trial/ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { try{ diff --git a/lib/telegram/index.ts b/lib/telegram/index.ts index 76a3563..d97ab27 100644 --- a/lib/telegram/index.ts +++ b/lib/telegram/index.ts @@ -10,6 +10,7 @@ import * as fedinfo from "../../lib/telegram/commands/fedinfo"; import * as welcome from "../../lib/telegram/commands/welcome"; import * as multilang from "../../lib/telegram/commands/multilang"; import * as toggleWelcome from "../../lib/telegram/commands/toggleWelcome"; +import * as toggleEnforce from "../../lib/telegram/commands/toggleEnforcement"; import * as toggleAdminReportable from "../../lib/telegram/commands/toggleAdminReportable"; import * as greeting from "../../lib/telegram/commands/greeting"; import * as toggleCaptcha from "../../lib/telegram/commands/toggleCaptcha"; @@ -46,7 +47,7 @@ const batchedSend = _batchedSend( greeting_mode: false, captcha: false, admin_reportable: false, - enforcement: false, + enforcement: true, thread_id_rules: '', thread_id_welcome: '', thread_id_notifications: '', @@ -278,6 +279,7 @@ const commands: {regexp: RegExp, callback: any}[] = [ getRules, report, toggleWelcome, + toggleEnforce, start, fedinfo, toggleCaptcha, @@ -295,7 +297,8 @@ const commands: {regexp: RegExp, callback: any}[] = [ setLanguage, ]; -const adminOnlyCommands = [joinFed, multilang, leaveFed, newFed, toggleCaptcha, setLanguage, setChannelFed, setChannel, toggleWelcome, toggleAdminReportable, start, setRulesCommand ] +const adminOnlyCommands = [joinFed, toggleEnforce, multilang, leaveFed, newFed, toggleCaptcha, setLanguage, setChannelFed, setChannel, toggleWelcome, toggleAdminReportable, start, setRulesCommand ] +const settingUpateCommands = [setLanguage, toggleEnforce, setRulesCommand, joinFed, setChannel, toggleWelcome, toggleCaptcha, toggleAdminReportable] commands.forEach((command) => { bot.onText( @@ -367,7 +370,7 @@ commands.forEach((command) => { // todo success bool return val, to not always delete settings command.callback(queue, db, groupSettings, bot, botId, msg, match,batchedSend); - if (command === setLanguage || command === setRulesCommand || command === joinFed || command === setChannel || command === toggleWelcome || command === toggleCaptcha || command === toggleAdminReportable) + if (settingUpateCommands.indexOf(command)!==-1) myCache.del(msg.chat.id) if (command === start) myCache.del("started"+msg.chat.id) diff --git a/subgraph/subgraph.yaml b/subgraph/subgraph.yaml index a5bc922..252ec8b 100644 --- a/subgraph/subgraph.yaml +++ b/subgraph/subgraph.yaml @@ -34,7 +34,33 @@ dataSources: name: Realitio_v2_1_ArbitratorWithAppeals network: goerli #xdai source: - address: "0xAa5681047a16F163391377Fd9f78e84355Cc9696" #goerli "0xAa5681047a16F163391377Fd9f78e84355Cc9696" #xdai 0x17BBc6405e3Cbc452A993E5C23e460980BBeC83F + address: "0x0a3fBb60D41F0Ec10f9E76368dd4e506885c3E7d" #goerli "0x0a3fBb60D41F0Ec10f9E76368dd4e506885c3E7d" #xdai 0x17BBc6405e3Cbc452A993E5C23e460980BBeC83F + abi: Realitio_v2_1_ArbitratorWithAppeals + startBlock: 8034496 #8034496 #goerli, xdai 23143918 + mapping: + kind: ethereum/events + apiVersion: 0.0.6 + language: wasm/assemblyscript + entities: + - DisputeIDToQuestionID + - Ruling + - RulingFunded + abis: + - name: Realitio_v2_1_ArbitratorWithAppeals + file: ./abis/Realitio_v2_1_ArbitratorWithAppeals.json + eventHandlers: + - event: DisputeIDToQuestionID(indexed uint256,bytes32) + handler: handleDisputeIDToQuestionID + - event: RulingFunded(indexed uint256,indexed uint256,indexed uint256) + handler: handleRulingFunded + - event: Ruling(indexed address,indexed uint256,uint256) + handler: handleRuling + file: ./src/Realitio_v2_1_ArbitratorWithAppeals.ts + - kind: ethereum + name: Realitio_v2_1_ArbitratorWithAppeals_ES + network: goerli #xdai + source: + address: "0x8f0b33ab30D4073E0772A688A18E937beE34cd65" #goerli "0x8f0b33ab30D4073E0772A688A18E937beE34cd65" #xdai 0x17BBc6405e3Cbc452A993E5C23e460980BBeC83F abi: Realitio_v2_1_ArbitratorWithAppeals startBlock: 8034496 #8034496 #goerli, xdai 23143918 mapping: From 0d1dee244c8016a9e4c026fe27eefe45e026b1ed Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Mon, 23 Jan 2023 22:37:07 +0000 Subject: [PATCH 027/111] chore: env example update --- .env.dist | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.env.dist b/.env.dist index fef1771..1000ea9 100644 --- a/.env.dist +++ b/.env.dist @@ -1,8 +1,16 @@ BOT_TOKEN= REALITITY_ETH_V30= -REALITIO_ARBITRATOR= +REALITIO_ARBITRATOR_EN= +REALITIO_ARBITRATOR_ES= TEMPLATE_ID= WEB3_PROVIDER_URL= +BOT_USERNAME= +SUSIE_SUPPORT_EN= +SUSIE_SUPPORT_ES= +JUSTICE_LEAGUE_EN= +JUSTICE_LEAGUE_ES= +PRIVATE_KEY= +TRANSACTION_BATCHER_CONTRACT_ADDRESS= NTBA_FIX_319=1 CHAIN_ID = MODERATE_SUBGRAPH=https://api.thegraph.com/subgraphs/name/shotaronowhere/kleros-moderate-goerli From b8cc2a3a59ca53a6d77dbcc2c873a32a8e812642 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Mon, 23 Jan 2023 22:57:34 +0000 Subject: [PATCH 028/111] chore: cron adjustment --- ecosystem.config.js | 1 - lib/cron.ts | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/ecosystem.config.js b/ecosystem.config.js index b0e3624..506ba4f 100644 --- a/ecosystem.config.js +++ b/ecosystem.config.js @@ -20,7 +20,6 @@ module.exports = { autorestart: false, watch: false, ignore_watch: ['\.git', 'node_modules', 'database\.db', 'database\.db-journal'], - cron_restart: '* * * * *', env: { NODE_ENV: 'development' } diff --git a/lib/cron.ts b/lib/cron.ts index 13e5daa..0128ab9 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -398,9 +398,8 @@ const delay = (delayInms) => { const delayCheck = async (realityQuestions: string, lastPageUpdated: number, timestampNew: number, timestampLastUpdated: number, botaddress: string) => { const queryModeration = getQueryDelay(lastPageUpdated, realityQuestions, timestampLastUpdated, botaddress, timestampNew) - // 1 min delay - console.log(queryModeration) - await delay(60000) + // 5 min delay + await delay(300000) //console.log(queryModeration); //console.log('graphtime'); //console.log(queryModeration) From 50e312862c69da117a00825e3973758b1c760276 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Mon, 23 Jan 2023 23:16:43 +0000 Subject: [PATCH 029/111] chore: turn off test env --- lib/cron.ts | 2 +- lib/telegram/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/cron.ts b/lib/cron.ts index 0128ab9..603e96a 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -11,7 +11,7 @@ const ModeratorBot = require('node-telegram-bot-api'); const Web3 = require('web3') const realitio_bot = require('./realitioReporting') const db = openDb(); -const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: false, testEnvironment: true}); +const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: false, testEnvironment: false}); const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCount: true}); // Only need DB for // - channelID diff --git a/lib/telegram/index.ts b/lib/telegram/index.ts index d97ab27..14ec0ed 100644 --- a/lib/telegram/index.ts +++ b/lib/telegram/index.ts @@ -55,7 +55,7 @@ const batchedSend = _batchedSend( federation_id_following: '' } const ModeratorBot = require('node-telegram-bot-api'); -const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: {params: {"allowed_updates": JSON.stringify(["my_chat_member", "chat_member", "message","callback_query", "new_chat_members", "inline_query"])}}, testEnvironment: true}); +const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: {params: {"allowed_updates": JSON.stringify(["my_chat_member", "chat_member", "message","callback_query", "new_chat_members", "inline_query"])}}, testEnvironment: false}); //const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: true, testEnvironment: true}); //bot. From 4a7168eb87844554329a4bb0003086fd81cfe0d5 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Mon, 23 Jan 2023 23:32:19 +0000 Subject: [PATCH 030/111] fix: typo --- lib/telegram/commands/setChannel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/telegram/commands/setChannel.ts b/lib/telegram/commands/setChannel.ts index ffec88f..e2cbcbd 100644 --- a/lib/telegram/commands/setChannel.ts +++ b/lib/telegram/commands/setChannel.ts @@ -18,7 +18,7 @@ const regexpFull = /\/setchannel (.+)/ const callback = async (queue: any, db: any, settings: groupSettings, bot: TelegramBot, botId: string, msg: any, match: string[], batchedSend: any) => { try { - if (msg.chat.is_fourm) + if (msg.chat.is_forum) return if (msg.text.substring(0,14) === "/setchannelfed") return From c05e34cd9391369d54ab9f87cfc7478fc352c503 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Tue, 24 Jan 2023 00:03:44 +0000 Subject: [PATCH 031/111] fix: prevent msg replay --- lib/telegram/commands/welcome.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/telegram/commands/welcome.ts b/lib/telegram/commands/welcome.ts index 1e43021..c2726fc 100644 --- a/lib/telegram/commands/welcome.ts +++ b/lib/telegram/commands/welcome.ts @@ -10,9 +10,9 @@ import {getMultilangGroup} from "../../db"; const callback = async (queue: any, settings: groupSettings, bot: any, msg: any) => { try { -// if (msg.old_chat_member.status !== "left") -// return; - console.log('yoyoyoyoy welcome') + if (msg.old_chat_member.status !== "left") + return; + const lang_code = msg?.from?.language_code queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[lang_code].welcome.welcome, msg.chat.is_forum? {message_thread_id: msg.message_thread_id, parse_mode: "Markdown"}: {parse_mode: "Markdown"})}catch{}}); //const options = msg.chat.is_forum? {message_thread_id: msg.message_thread_id, caption: "To get started, give Susie admin rights."} : {caption: "To get started, give Susie admin rights."} From f76ceb21cd4ffc104c835c9c3c1923b2e76df849 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Tue, 24 Jan 2023 15:56:04 +0000 Subject: [PATCH 032/111] feat: mobile ux feedback, shorter msgs --- lib/telegram/assets/langNew.json | 54 +++++++++++++++++--------------- lib/telegram/commands/start.ts | 6 ++-- 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/lib/telegram/assets/langNew.json b/lib/telegram/assets/langNew.json index 4e1fced..e2aba7b 100644 --- a/lib/telegram/assets/langNew.json +++ b/lib/telegram/assets/langNew.json @@ -166,13 +166,14 @@ "start": { "start1": "Hi! My community moderation tools are at your service. [DM]", "start2": " me to find out more about how to use me to my full potential : )\n\n- /setrules to change the default [rules]", - "start3": "\n- /report messages by reply.\n- /setchannel create a moderation notification channel\n\nSuccessful reports result in escalating penalties (1 day, 1 week, 1 month, 1 year ban).\n\n", + "start3": "\n- /report messages by reply.", + "start3topic": "\n- /report messages by reply", "private": "Hi! My name is Susie, nice to meet you : )\n\nI am a [Kleros Moderate](https://kleros.io/moderate) community manager at your service. Use /help to learn how to use me to my full potential.\n\nJoin @SusieSupport to get information on all the latest updates.", "add": "Add me to your group!", "already": "Already started." }, "welcome": { - "welcome": "Hi, I'm Susie, a [Kleros Moderate](https://kleros.io/moderate/) bot.\n\nI need permission from an admin to /start.\n\nHow do I help resolve content moderation questions?\n\n1. I ask \"Did a user break the rules?\" on the crowdsourcing platform [Reality.Eth](https://realityeth.github.io/).\n2. Anyone can answer by leaving a bond (xDai on Gnosis Chain).\n3. Anyone can dispute the answer and [Kleros](https://kleros.io/), the decentralized court, resolves the question.\n\nTo learn more, read my [documentation](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie), ask a question in @SusieSupport, or [DM](https://t.me/${process.env.BOT_USERNAME}?start=help) me for help : )" + "welcome": "Hi, I'm Susie, a [Kleros Moderate](https://kleros.io/moderate/) bot.\n\nI need permission from an admin to /start.\n\nHow do I help with moderation?\n\n1. I ask \"Did a user break the rules?\" on the crowdsourcing platform [Reality.Eth](https://realityeth.github.io/).\n2. The question is answered with an escalation game using xDai on [Gnosis Chain](https://www.gnosis.io/).\n3. The answer can be disputed in the [Kleros](https://kleros.io/) court.\n\nTo learn more, [DM](https://t.me/KlerosModeratorBot?start=help) me, read my [docs](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie), or ask a question in @SusieSupport." }, "defaultRules": "https://ipfs.kleros.io/ipfs/Qme3Qbj9rKUNHUe9vj9rqCLnTVUCWKy2YfveQF8HiuWQSu/Kleros%20Moderate%20Community%20Rules.pdf", "index": { @@ -184,20 +185,20 @@ "help": { "DM": "Get Help (DM)", "DM2": "DM me for help : )", - "help": "*Help*\n\nHi! My name is Susie. I'm a [Kleros Moderate](https://kleros.io/moderate) bot, here to help you manage your groups!\n\nAs groups grow, so do their moderation problems. Users often complain about admin abuse and have no recourse. Who moderates the moderator? Presenting [Kleros Moderate](https://kleros.io/moderate), a crowd-sourced content moderation tool using [Reality.eth](https://reality.eth.limo/) and [Kleros](https://kleros.gitbook.io/docs/) on [Gnosis Chain](https://www.gnosis.io/).\n\nWhen users are reported, a question is created on Reality.Eth asking 'did the user break the rules?'. The question can be answered yes/no with a bond (5 DAI). Successful reports result in penalties (1 day, 1 week, 1 month, 1 year escalating bans).\n\nAnswers to reports can be disputed, creating a case in the Kleros court.\n\nHelpful commands:\n - /start: Starts me. You probably already used this.\n - /help: Sends this message to tell you more about myself.\n\nSelect a feature to learn more. My [documentation](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator) is also helpful, or ask a question in @SusieSupport." + "help": "*Help*\n\nHi! My name is Susie. I'm a [Kleros Moderate](https://kleros.io/moderate) bot, here to help you manage your groups!\n\nI crowdsource moderation using [Reality.eth](https://reality.eth.limo/) and [Kleros](https://kleros.gitbook.io/docs/) on [Gnosis Chain](https://www.gnosis.io/).\n\nModeration is resolved with an escalation game and the outcome can be disptued in the Kleros Court.\n\nHelpful commands:\n - /start: Starts me. You probably already used this.\n - /help: Sends this message to tell you more about myself.\n\nSelect a feature to learn more. Ask questions in @SusieSupport or read the [docs](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator)." , "back": "back", - "Greeting1": "👋 *Greeting* 👋\n\nWelcome your members with a greeting informing them of the group rules.\n\n*Admin commands:*\n- `/welcome` : Toggles on/off welcomes messages.\n- `/captcha` : Toggles on/off rules captcha.\n\nAfter 5 minutes, the previous welcome messages will get deleted\n\nSusie requires admin privileges to enforce captchas (new users muted by default, until solving the captcha). Captchas remain for up to 5 minutes. If a user forgets to respond within 5 minutes, they should rejoin the group to prompt a new captcha.", - "Language1": "🗣️ *Languages* 🗣️\n\nSusie's replies can be changed to one of the languages below.\n- EN (English)\n- ES (Español)\n\n*Admin commands*: \n- `/lang`: Set your preferred language.\n\nContent moderation requires a nuanced understanding of context and language. Please make sure to set the appropriate language for your community for effective moderation.", + "Greeting1": "👋 *Greeting* 👋\n\nWelcome your members with a greeting informing them of the group rules.\n\nAfter 5 minutes, the previous welcome messages will get deleted\n\nCaptchas remain for up to 5 minutes. If a user forgets to respond within 5 minutes, they should rejoin the group to prompt a new captcha.\n\n*Admin commands:*\n- `/welcome` : Toggles on/off welcomes messages.\n- `/captcha` : Toggles on/off captcha.", + "Language1": "🗣️ *Languages* 🗣️\n\nSusie's replies can be changed to one of the languages below.\n\n- EN (English)\n- ES (Español)\n\nContent moderation requires a nuanced understanding of context and language. Please make sure to set the appropriate language for your community for effective moderation.\n\n*Admin commands*: \n- `/lang`: Set your preferred language.", "Topics1": "ℹ️ *Topics* ℹ️\n\nTopics allow large groups to focus discussion in dedicated **topic** chats. Susie supports topics. When changing a group to topic mode, you will need to /start Susie again.\n\n*Admin commands*:\n- `/start`: Start topic mode.", - "Evidence1": "🔍 *Evidence* 🔍\n\nTo prevent important messages from deletion, pre-emptively, messages can be saved as evidence.\n\n*User commands*:\n- `/evidence` : Reply to a message to add it as evidence.", - "Report1": "🚨 *Report* 🚨\n\nWhen users are reported, a question is created on Reality.Eth asking 'did the user break the rules?'. The question can be answered yes/no with a bond (5 DAI). Successful reports result in escalating penalties (1 day, 1 week, 1 month, 1 year bans).\n\nIn trial mode, Susie only recommends admins to take action to penalize users who break the rules. Trial mode is helpful for admins who want to try out Susie's moderation crowdsourcing.\n\nAnswers to reports can be disputed, creating a case in the Kleros court.\n\n*User commands*:\n- `/report` : Reply to a message to report it\n- `/info`: Returns active reports\n\n*Admin commands*:\n-`/adminreportable` Toggles reportability of admins.\n- `/trial` Toggles trial mode in which Susie does not penalize users, but only recommends admins to take action.", - "Rules1": "📄 *Rules* 📄\n\nEvery groups starts with [default rules](https://ipfs.kleros.io/ipfs/Qme3Qbj9rKUNHUe9vj9rqCLnTVUCWKy2YfveQF8HiuWQSu/Kleros%20Moderate%20Community%20Rules.pdf). Crafting effective comprehensive rules can be challenging.\n\n***Rule Writing Tips***:\n\n- Start with a preamble defining the group culture.\n- Number each rule.\n- Be specific.\n\n***Bad Example***:\n\n- Users must not send immoral messages\n- Users must not send unethical messages\n\nThese rules are too abstract and do not describe the culture nor context of the group.\n\n***Good Example***:\n\nAs a vegan community, we adopt these rules with the goals of sharing lifestyle tips (recipes, sustainable clothing, etc) in an environment of mutual respect.\n\n1. Users must not encourage meat consumption.\n2. Users must credit sources. Stealing credit for vegan recipies is unacceptable.\n\nThese rules include a define the group culture in the preamble, are numbered, and are specific.\n\n*User commands*:\n- `/rules`: Returns current rules\n*Admin commands*:\n- `/setrules` : Sets the rules to the the url\n- `/setrules` : Sets the rules to a replied message", - "Court1": "⚖️ *Court* ⚖️\n\nContent moderation questions are resolved by the [Kleros Court](https://kleros.gitbook.io/docs/) with a jury of moderators. If the jury made a mistake, the case can be appealed, drawing a larger pool of jurors and providing an opportunity to provide more context, analysis, and arguments.\n\nIf you would like a chance to serve as a jury member, get PNK ([Gnosis Chain](https://swapr.eth.link/#/swap?chainId=100) or [Mainnet](https://app.uniswap.org/#/swap?outputCurrency=0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d&inputCurrency=ETH)) and [stake](https://court.kleros.io/) in the Kleros court.\n\nTo discuss the merits of a dispute, see @klerosjuror. To learn more about Kleros, ask a question in @Kleros", - "Lawyer1": "🧑‍⚖️ *Find a Lawyer* 🧑‍⚖️\n\nDisputes over reports can be complicated. Disputes often resolve on the merits of the message and rules alone. In some cases, disputes are better resolved by presenting the court with analysis and arguments.\n\nIf you would like to offer your services as a lawyer or solicit services, please join this [group](https://t.me/+9fvGGkGfSZ1hZDBk).", - "Privacy1": "🕵️ *Privacy* 🕵️\n\nEffective moderation depends on access to the full context of a reported message. To provide context, users can request Susie to save messages to submit as evidence on their behalf. Susie manages moderation private and public groups differently,\n\n- In *private* groups, moderators depend on evidence submissions alone.\n- In *public* groups, Susie invites moderators to join the group and investigate message context.", - "Notifications1": "🔔 *Notifications* 🔔\n\nSusie sends notifications about moderation actions and report updates. These notifications are restricted to a separate chat in topic mode. In regular Telegram groups, notifications can be sent to a notification channel to avoid cluttering the main chat.\n\nHow to enable notification channels:\n\n1. Make a channel\n2. Add Susie\n3. Susie will send a channel ID\n4. Use that channel ID to set notifications with /setchannel in the original group\n\n*User commands*:\n- `/notifications`: Returns current notification channel\n*Admin commands*:\n- `/setchannel` : Sets the notification channel to the specified channel id\n- `/setfedchannel` : Sets the notification channel for your federation to the specified channel id", - "Federations1": "🌐 *Federations*\n\nModerating a single group is hard, but managing multiple is even harder. Do you have to ban spammers manually, in all your groups?\n\nNo more! With federations, Susie can enforce a ban on a user in all federatec groups.\n\n*User commands*:\n- `/fedinfo`: Returns current federation\n*Admin commands*:\n- `/newfed`: Creates a federation\n- `/joinfed`: Joins the current group to a Federation", - "Gnosis1": "⛓️ *Gnosis Chain* ⛓️\n\nSusie uses [xDAI](https://docs.gnosischain.com/about/tokens/xdai), a stable coin, on [Gnosis Chain](https://www.gnosis.io/). Don't know what that means? It means Susie uses a cheap and fast public ledger to coordinate moderation fairly and transparently.\n\nDon't have any xDAI on Gnosis Chain? No problem, there's a (cheap, fast) [bridge](https://bridge.connext.network/?receivingChainId=100&receivingAssetId=0x0000000000000000000000000000000000000000) for that. \n\nWhat's crypto? I heard about that on the news, I don't want anything to do with crypto. No problem, you can ask for help from freelance moderators in @SusieSupport.\n\nDon't have any cryptocurrency? No problem, there's a convinient [fiat on-ramp](https://www.mtpelerin.com/buy-xdai) (credit card or bank transfer) to buy DAI on Gnosis Chain.\n\nNeed help adding the Gnosis Chain network to your wallet? Don't worry, there's a [guide](https://docs.gnosischain.com/tools/wallets/metamask#2-configure) for that.\n\nNeed more help? Don't worry, there's a @SusieSupport group for that", + "Evidence1": "🔍 *Evidence* 🔍\n\nTo prevent important messages from deletion, pre-emptively, messages can be saved as evidence.\n\n*User commands*:\n- `/evidence` : Saves message as evidence.", + "Report1": "🚨 *Report* 🚨\n\nReports create content moderation questions on the crowdsourcing platform Reality.Eth asking,\n\n'did the user break the rules?'\n\nThe question can be answered yes/no with a bond (5 DAI). Answers can be disputed in the Kleros court.\n\nSuccessful reports result in escalating penalties (1 day, 1 week, 1 month, 1 year bans).\n\n*User commands*:\n- `/report` : Reports message.\n- `/info`: Returns active reports\n\n*Admin commands*:\n-`/adminreportable` Toggles reportability of admins.\n- `/trial` Toggles trial mode where users are not penalized", + "Rules1": "📄 *Rules* 📄\n\nEvery groups starts with [default rules](https://ipfs.kleros.io/ipfs/Qme3Qbj9rKUNHUe9vj9rqCLnTVUCWKy2YfveQF8HiuWQSu/Kleros%20Moderate%20Community%20Rules.pdf).\n\n***Rule Writing Tips***:\n\n- State the group culture in a preamble.\n- Number each rule.\n- Be specific.\n\n*User commands*:\n- `/rules`: Returns current rules\n*Admin commands*:\n- `/setrules` or : Sets the rules to the url or message", + "Court1": "⚖️ *Court* ⚖️\n\nModeration questions are resolved by the [Kleros Court](https://kleros.gitbook.io/docs/) with a jury of moderators. If the jury made a mistake, the case can be appealed, drawing a larger pool of jurors and providing an opportunity to provide more context, analysis, and arguments.\n\nIf you would like a chance to serve as a jury member, get PNK ([Gnosis Chain](https://swapr.eth.link/#/swap?chainId=100) or [Mainnet](https://app.uniswap.org/#/swap?outputCurrency=0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d&inputCurrency=ETH)) and [stake](https://court.kleros.io/) in the Kleros court.\n\nTo discuss the merits of a dispute, see @klerosjuror. To learn more about Kleros, ask a question in @Kleros", + "Lawyer1": "🧑‍⚖️ *Find a Lawyer* 🧑‍⚖️\n\nDisputes over reports can be complicated.\n\nIf you need help arguing your case in the Kleros court, consider asking help from a Kleros [lawyer](https://t.me/+9fvGGkGfSZ1hZDBk).", + "Privacy1": "🕵️ *Privacy* 🕵️\n\nEffective moderation depends on access to the full context of a reported message. To provide context, users can request Susie to save messages to submit as evidence on their behalf. Susie manages moderation private and public groups differently,\n\n- In *private* groups, moderators depend on evidence submissions alone.\n- In *public* groups, moderators have access to the full public chat history.", + "Notifications1": "🔔 *Notifications* 🔔\n\nNotifications can be sent to a separate channel to avoid cluttering the main group.\n\nHow to enable notification channels:\n\n1. Make a channel\n2. Add Susie\n3. Susie will send a channel ID\n4. Use that channel ID to set notifications with /setchannel in the original group\n\n*User commands*:\n- `/notifications`: Returns current notification channel\n*Admin commands*:\n- `/setchannel` : Sets the notification channel to the specified channel id\n- `/setfedchannel` : Sets the notification channel for your federation to the specified channel id", + "Federations1": "🌐 *Federations*\n\nModerating a single group is hard, but managing multiple is even harder. Do you have to ban spammers manually, in all your groups?\n\nNo more! With federations, Susie can enforce a ban on a user in all federated groups.\n\n*User commands*:\n- `/fedinfo`: Returns current federation\n*Admin commands*:\n- `/newfed`: Creates a federation\n- `/joinfed`: Joins the current group to a Federation", + "Gnosis1": "⛓️ *Gnosis Chain* ⛓️\n\nSusie uses [xDAI](https://docs.gnosischain.com/about/tokens/xdai), a stable coin, on [Gnosis Chain](https://www.gnosis.io/). Don't know what that means? It means Susie uses a cheap and fast public ledger to coordinate moderation fairly and transparently.\n\nDon't have any xDAI on Gnosis Chain? No problem, there's a (cheap, fast) [bridge](https://bridge.connext.network/?receivingChainId=100&receivingAssetId=0x0000000000000000000000000000000000000000) for that. \n\nWhat's crypto? I heard about that on the news, I don't want anything to do with crypto. No problem, you can ask for help from freelance moderators in @SusieSupport.\n\nDon't have any cryptocurrency? No problem, there's a convenient [fiat on-ramp](https://www.mtpelerin.com/buy-xdai) (credit card or bank transfer) to buy DAI on Gnosis Chain.\n\nNeed help adding the Gnosis Chain network to your wallet? Don't worry, there's a [guide](https://docs.gnosischain.com/tools/wallets/metamask#2-configure) for that.\n\nNeed more help? Don't worry, there's a @SusieSupport group for that", "Greeting": "👋 Greeting", "Language": "🗣️ Language", "Topics": "ℹ️ Topics", @@ -360,30 +361,31 @@ "start": { "start1": "Hola! Mis herramientas de moderación comunitaria están a tu servicio. Envíame un [DM]", "start2": " para saber más sobre cómo aprovechar todo mi potencial. : )\n\n- /setrules para cambiar las [reglas]", - "start3": "\n- /report mensajes por respuesta.\n- /setchannel crear un canal de notificación de moderación\n\nLos reportes exitosos resultan en penalizaciones escaladas (1 día, 1 semana, 1 mes, 1 año de baneo).", + "start3": "\n- /report mensajes por respuesta.", + "start3topic": "\n- /reportar mensajes por respuesta.", "private": "Hola, me llamo Susie, encantada de conocerte : )\n\nSoy una [Kleros Moderate](https://kleros.io/moderate) community manager a tu servicio. Utiliza /help para aprender a utilizarme en todo mi potencial.\n\nÚnete a mi canal de noticias @KlerosModerateNews para informarte de todas las últimas actualizaciones.", "add": "Añádeme a tu grupo!", "already": "Ya comenzó." }, "welcome": { - "welcome": "Hola, soy Susie, un bot [Kleros Moderate](https://kleros.io/moderate/). Necesito permiso de un administrador para /start. \n\n¿Cómo ayudo a resolver preguntas sobre moderación de contenidos?\n\n1.Pregunto \"¿Un usuario ha infringido las normas?\" en la plataforma de crowdsourcing [Reality.Eth](https://realityeth.github.io/).\n2. Cualquiera puede responder dejando un bono (xDai en Gnosis Chain).\n3. Cualquiera puede impugnar la respuesta y [Kleros](https://kleros.io/), el tribunal descentralizado, resuelve la pregunta.\n\nPara saber más, lee mi [documentación](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie), haz una pregunta en @SusieSupport, o [DM](https://t.me/${process.env.BOT_USERNAME}?start=help) para obtener ayuda." + "welcome": "Hola, soy Susie, un bot [Kleros Moderate](https://kleros.io/moderate/). Necesito permiso de un administrador para /start. ¿Cómo puedo ayudar con la moderación? Pregunto "¿Un usuario ha infringido las normas?" en la plataforma de crowdsourcing [Reality.Eth](https://realityeth.github.io/).n2. La pregunta se responde con un juego de escalada usando xDai en [Gnosis Chain](https://www.gnosis.io/).\n3. La respuesta se puede disputar en el tribunal [Kleros](https://kleros.io/).\n\nPara saber más, [DM](https://t.me/KlerosModeratorBot?start=help) mío, lee mis [docs](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie), o haz una pregunta en @SusieSupport." }, "defaultRules": "https://ipfs.kleros.io/ipfs/QmSHAjfD1MYPtyopFoXcUQ5Ny3sfs5re1yz3h3TZ5qGDsp/Kleros%20Moderate%20Normas%20comunitarias.pdf", "help": { "DM": "Obtener ayuda (DM)", "DM2": "DM de ayuda : )", - "help": "*Ayuda*\n\nHi! Me llamo Susie. Soy un [Kleros Moderate](https://kleros.io/moderate) bot, aquí para ayudarles a gestionar sus grupos!\n\nA medida que los grupos crecen, también lo hacen sus problemas de moderación. Los usuarios suelen quejarse de los abusos de los administradores y no tienen ningún recurso. ¿Quién modera al moderador? Presentamos [Kleros Moderate](https://kleros.io/moderate), una herramienta de moderación de contenidos de origen colectivo que utiliza [Reality.eth](https://reality.eth.limo/) y [Kleros](https://kleros.gitbook.io/docs/) con [Gnosis Chain](https://www.gnosis.io/).\n\nCuando los usuarios son denunciados, se crea una pregunta en Reality.Eth preguntando \"¿el usuario rompió las reglas?\". La pregunta puede responderse sí/no con un bono (5 DAI). Las denuncias acertadas dan lugar a sanciones (1 día, 1 semana, 1 mes, 1 año de prohibición escalonada).\n\nLas respuestas a los informes pueden impugnarse, creando un caso en el tribunal de Kleros.\n\nComandos útiles:\n - /start: Empieza yo. Probablemente ya usaste esto.\n - /help: Envía este mensaje para contarte más cosas sobre mí.\n\nSeleccione una función para obtener más información. Mi [documentación](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator) también es útil, o haz una pregunta en @SusieSupport." + "help": "*Ayuda*\n\n¡Hola! Me llamo Susie. Soy un bot [Kleros Moderate](https://kleros.io/moderate), ¡aquí para ayudarte a gestionar tus grupos!\n\n¡Modero en grupo usando [Reality.eth](https://reality.eth.limo/) y [Kleros](https://kleros.gitbook.io/docs/) en [Gnosis Chain](https://www.gnosis.io/).\n\nLa moderación se resuelve con un juego de escalada y el resultado se puede disputar en el Tribunal Kleros.\n\nComandos útiles:\n - /start: Me inicia. Probablemente ya lo hayas usado. \n - /help: Envía este mensaje para contarte más sobre mí.\n\nSelecciona una función para saber más. Haz preguntas en @SusieSupport o lee los [docs](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator)." , "back": "back", - "Greeting1": "👋 *Saludos* 👋\n\nDa la bienvenida a tus miembros con un saludo informándoles de las reglas del grupo.\n\n*Comandos de administrador:*\n- `/welcome` : Activa/desactiva los mensajes de bienvenida.\n- `/captcha` : Activa/desactiva el captcha de las reglas.\n\nDespués de 5 minutos, los mensajes de bienvenida anteriores se borrarán.\n\nLos captchas permanecen hasta 5 minutos. Si un usuario se olvida de responder en 5 minutos, debe volver a unirse al grupo para solicitar un nuevo captcha.", - "Language1": "🗣️ *Idiomas* 🗣️\n\nLas respuestas de Susie se pueden cambiar a uno de los siguientes idiomas.\n- EN (English)\n- ES (Español)\n\n*Comandos de administración*: \n- `/lang` : Establezca su idioma preferido.\n\nLa moderación de contenidos requiere una comprensión matizada del contexto y el lenguaje. Establecer un idioma no sólo cambia las respuestas de Susie, sino que también especifica el idioma de los jurados cualificados.\n\nPor favor, asegúrese de establecer el idioma apropiado para su comunidad para una moderación efectiva.", + "Greeting1": "👋 *Saludos* 👋 Bienvenida a tus miembros con un saludo informándoles de las reglas del grupo. Después de 5 minutos, los mensajes de bienvenida anteriores se borrarán. Si un usuario se olvida de responder dentro de los 5 minutos, deben volver a unirse al grupo para solicitar una nueva captcha.\n\n*Comandos de administrador:*\n- `/welcome` : Activa / desactiva los mensajes de bienvenida.\n- `/captcha` : Activa / desactiva las reglas captcha.", + "Language1": "🗣️ *Idiomas* 🗣️\n\nLas respuestas de Susie pueden cambiarse a uno de los siguientes idiomas.\n\n- EN (English)\n- ES (Español)\n\nLa moderación de contenidos requiere una comprensión matizada del contexto y del lenguaje. Por favor, asegúrese de establecer el idioma apropiado para su comunidad para una moderación efectiva. \n\n*Comandos de administración*:\n`/lang`: Establezca su idioma preferido.", "Topics1": "ℹ️ *Temas* ℹ️\n\nLos temas permiten a los grandes grupos centrar el debate en chats dedicados a **temas**. Susie es compatible con los temas. Cuando cambie un grupo a modo de tema, necesitará /iniciar Susie de nuevo.\n\n*Comandos de administrador*:\n- `/start`: Inicia el modo por temas.", - "Evidence1": "🔍 *Evidencia* 🔍\n\nPara evitar que se borren mensajes importantes, de forma preventiva, los mensajes pueden guardarse como pruebas.\n\n*Comandos de usuario*:\n- `/evidence` : Responde a un mensaje para añadirlo como evidencia.", - "Report1": "🚨 *Report* 🚨n\nCuando se reportan usuarios, se crea una pregunta en Reality.Eth preguntando \"¿el usuario rompió las reglas?\". La pregunta puede responderse sí/no con un bono (5 DAI). Los reportes exitosos resultan en sanciones escalonadas (1 día, 1 semana, 1 mes, 1 año de prohibición).\nEn el modo de prueba, Susie sólo recomienda a los administradores tomar medidas para sancionar a los usuarios que rompen las reglas.\nLas respuestas a los reportes pueden ser impugnadas, creando un caso en el tribunal de Kleros.\nComandos de usuario*:\n- `/report` : Responde a un mensaje para denunciarlo- `/info`: Devuelve los informes activos.n\n*Comandos de administrador*:\n-`/adminreportable` Activa la posibilidad de informar sobre los administradores.\n- `/trial` Activa el modo ensayo. Susie aplicará las penalizaciones automáticamente.", - "Rules1": "📄 *Reglas* 📄\n\nTodos los grupos empiezan con [reglas por defecto](https://ipfs.kleros.io/ipfs/QmSHAjfD1MYPtyopFoXcUQ5Ny3sfs5re1yz3h3TZ5qGDsp/Kleros%20Moderate%20Normas%20comunitarias.pdf). Elaborar políticas precisas puede ser todo un reto.\n\n*Consejos para redactar reglas***:\n\n- Empieza con un preámbulo que defina la cultura del grupo.\n- Numera cada regla.\n- Sé específico.\n\n*Mal ejemplo***:\n\n- Los usuarios no deben enviar mensajes inmorales\n- Los usuarios no deben enviar mensajes poco éticos.\n\nEstas reglas son demasiado abstractas y no describen la cultura ni el contexto del grupo.\n\n*Buen ejemplo***:\n\nComo comunidad vegana, adoptamos estas reglas con el objetivo de compartir consejos de estilo de vida (recetas, ropa sostenible, etc.) en un entorno de respeto mutuo.\n\n1. Los usuarios no deben fomentar el consumo de carne.\n2. Los usuarios no deben robar el crédito por recetas veganas.\n\nEstas reglas incluyen una definición de la cultura del grupo en el preámbulo, están numeradas y son específicas\n\ncomandos útiles:\n- `/rules`: Devuelve las reglas actuales.\n*Comandos de administrador*:\n- `/setrules` : Establece las reglas a la url\n- `/setrules` : Establece las reglas a un mensaje respondido.", - "Court1": "⚖️ *Corte* ⚖️\n\nLas cuestiones de moderación de contenidos las resuelve el [Kleros Court](https://kleros.gitbook.io/docs/) con un jurado de moderadores. Si el jurado cometió un error, el caso puede ser apelado, atrayendo a un grupo más grande de miembros del jurado y proporcionando la oportunidad de proporcionar más contexto, análisis y argumentos.\n\nSi desea tener la oportunidad de servir como miembro del jurado, obtenga PNK ([Gnosis Chain](https://swapr.eth.link/#/swap?chainId=100) o [Mainnet](https://app.uniswap.org/#/swap?outputCurrency=0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d&inputCurrency=ETH)) y [stake](https://court.kleros.io/) en el tribunal de Kleros.\n\nPara discutir el fondo de una disputa, consulte @klerosjuror.", - "Lawyer1": "🧑‍⚖️ *Buscar un Abogado* 🧑‍⚖️\n\nLas disputas sobre el comportamiento denunciado pueden ser complicadas y llenas de matices. A menudo, las disputas se resuelven únicamente sobre el fondo del mensaje y las normas. En algunos casos, las disputas se resuelven mejor presentando al tribunal análisis y argumentos.\n\nSi desea ofrecer sus servicios como abogado o solicitar servicios, únase a este [grupo](https://t.me/+9fvGGkGfSZ1hZDBk).", - "Privacy1": "🕵️ *Privacidad* 🕵️\n\nUna moderación eficaz depende del acceso al contexto completo de un mensaje denunciado. Para proporcionar el contexto, los usuarios pueden solicitar a Susie que guarde los mensajes para presentarlos como pruebas en su nombre. Susie gestiona la moderación de los grupos privados y públicos de forma diferente,\n\n- En los grupos *privados*, los moderadores dependen únicamente del envío de pruebas.\n- En los grupos *públicos*, Susie invita a los moderadores a unirse al grupo e investigar el contexto del mensaje.", - "Notifications1": "🔔 *Notificaciones* 🔔\n\nSusie envía notificaciones sobre acciones de moderación y actualizaciones de informes. Estas notificaciones están restringidas a un chat separado en modo tema. En grupos regulares de Telegram, las notificaciones pueden ser enviadas a un canal de notificación para evitar saturar el chat principal.\n\nCómo habilitar canales de notificación:\n\n1. Crea un canal\n2. Añade a Susie\n3. Susie enviará un ID de canal\n4. Utiliza ese ID de canal para establecer notificaciones con /setchannel en el grupo original\n\n*Comandos de usuario*:\n- `/notificaciones`: Devuelve el canal de notificaciones actual\n*Comandos de administrador*:\n- `/setchannel` : Establece el canal de notificaciones en el id de canal especificado\n- `/setfedchannel` : Establece el canal de notificaciones para su federación en el id de canal especificado", + "Evidence1": "🔍 *Evidencia* 🔍\n\nPara evitar que se borren mensajes importantes, de forma preventiva, se pueden guardar mensajes como evidencia.\n\n*Comandos de usuario*:\n- `/evidence` : Guarda el mensaje como evidencia.", + "Report1": "🚨 *Informe* 🚨 \n\nLos informes crean preguntas de moderación de contenidos en la plataforma de crowdsourcing Reality.Eth preguntando,\n\n'¿el usuario infringió las normas?'\n\nLa pregunta puede responderse sí/no con un bono (5 DAI). Las respuestas pueden ser impugnadas en el tribunal Kleros.\n\nLos informes exitosos resultan en sanciones escalonadas (1 día, 1 semana, 1 mes, 1 año de prohibición).\n\n*Comandos de usuario*:\n- `/report` : Informa del mensaje.\n- `/info`: Devuelve los informes activos.n\n*Comandos de administrador*:\n-`/adminreportable` Activa la posibilidad de informar de los administradores.\n- `/trial` Activa el modo de prueba en el que los usuarios no son penalizados.", + "Rules1": "📄 *Reglas* 📄\n\nTodos los grupos empiezan con [reglas por defecto](https://ipfs.kleros.io/ipfs/QmSHAjfD1MYPtyopFoXcUQ5Ny3sfs5re1yz3h3TZ5qGDsp/Kleros%20Moderate%20Normas%20comunitarias.pdf). \n\n***Consejos para la redacción de reglas***:\n\n -Enuncie la cultura del grupo en un preámbulo.\n -Numere cada regla.\nSea específico.\n\n*Comandos de usuario*:\n-`/rules`: Devuelve las reglas.\n*Comandos de administrador*:\n- `/setrules` o : Establece las reglas a la url o mensaje.", + "Court1": "⚖️ *Corte* ⚖️\n\nLas preguntas de moderación las resuelve el [Kleros Court](https://kleros.gitbook.io/docs/) con un jurado de moderadores. Si el jurado cometió un error, el caso puede ser apelado, atrayendo a un grupo más grande de miembros del jurado y proporcionando la oportunidad de proporcionar más contexto, análisis y argumentos.\n\nSi desea tener la oportunidad de servir como miembro del jurado, obtenga PNK ([Gnosis Chain](https://swapr.eth.link/#/swap?chainId=100) o [Mainnet](https://app.uniswap.org/#/swap?outputCurrency=0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d&inputCurrency=ETH)) y [stake](https://court.kleros.io/) en el tribunal de Kleros.\n\nPara discutir el fondo de una disputa, consulte @klerosjuror.", + "Lawyer1": "🧑‍⚖️ *Busque un abogado* 🧑‍⚖️ \n\nLas disputas sobre informes pueden ser complicadas.\n\nSi necesita ayuda para defender su caso ante el tribunal kleros, considere pedir ayuda a un [abogado] kleros(https://t.me/+9fvGGkGfSZ1hZDBk).", + "Privacy1": "🕵️ *Privacidad* 🕵️\n\nLa moderación eficaz depende del acceso al contexto completo de un mensaje denunciado. Para proporcionar este contexto, los usuarios pueden solicitar a Susie que guarde mensajes para presentarlos como pruebas en su nombre. Susie gestiona la moderación de los grupos privados y públicos de forma diferente.\n\n-En los grupos *privados*, los moderadores dependen únicamente del envío de pruebas.\n-En los grupos *públicos*, los moderadores tienen acceso a todo el historial del chat público.", + "Notifications1": "🔔 *Notificaciones* 🔔\n\nLas notificaciones pueden enviarse a un canal independiente para no saturar el grupo principal.\n\nCómo habilitar canales de notificación:\n\n1. Crea un canal\n2. Añade a Susie\n3. Susie enviará un ID de canal\n4. Utiliza ese ID de canal para establecer notificaciones con /setchannel en el grupo original\n\n*Comandos de usuario*:\n- `/notificaciones`: Devuelve el canal de notificaciones actual\n*Comandos de administrador*:\n- `/setchannel` : Establece el canal de notificaciones en el id de canal especificado\n- `/setfedchannel` : Establece el canal de notificaciones para su federación en el id de canal especificado", "Federations1": "🌐 *Federaciones*\n\nModerar un solo grupo es difícil, ¿pero gestionar varios lo es aún más? ¿Tienes que bloquear manualmente a los spammers en todos tus grupos? Con las federaciones, Susie puede aplicar una prohibición a un usuario en todos los grupos federados.\n\n*Comandos de usuario*:\n- `/fedinfo`: Devuelve la federación actual: Crea una federación- `/joinfed`: Une el grupo actual a una federación", "Gnosis1": "⛓️ *Gnosis Chain* ⛓️\n\nSusie usa [xDAI](https://docs.gnosischain.com/about/tokens/xdai), una moneda estable, en [Gnosis Chain](https://www.gnosis.io/). ¿No sabes lo que eso significa? Significa que Susie utiliza un libro de contabilidad público barato y rápido para coordinar la moderación de forma justa y transparente. \n\n¿No tienes ningún xDAI en Gnosis Chain? No hay problema, hay un (barato, rápido) [puente](https://bridge.connext.network/?receivingChainId=100&receivingAssetId=0x0000000000000000000000000000000000000000) para eso. \n\n¿Qué es crypto? He oído hablar de eso en las noticias, no quiero tener nada que ver con crypto. No hay problema, puedes pedir ayuda a los moderadores independientes en @SusieSupport.\n\n¿No tienes ninguna criptodivisa? No hay problema, hay una conveniente [fiat on-ramp](https://www.mtpelerin.com/buy-xdai) (tarjeta de crédito o transferencia bancaria) para comprar DAI en Gnosis Chain.\n\n¿Necesitas ayuda para añadir la red Gnosis Chain a tu cartera? No te preocupes, hay una [guía](https://docs.gnosischain.com/tools/wallets/metamask#2-configure) para eso.\n\n¿Necesitas más ayuda? No te preocupes, hay un grupo @SusieSupport para eso.", "Greeting": "👋 Saludos", diff --git a/lib/telegram/commands/start.ts b/lib/telegram/commands/start.ts index 4aa63fe..212f494 100644 --- a/lib/telegram/commands/start.ts +++ b/lib/telegram/commands/start.ts @@ -108,7 +108,7 @@ const callback = async (queue:any, db: any, settings: groupSettings, bot: any, b setTitle(db, 'telegram', String(msg.chat.id), msg.chat.title) setRules(db, 'telegram', String(msg.chat.id), langJson[lang_code].defaultRules, Math.floor(Date.now()/1000)); setLang(db, 'telegram', String(msg.chat.id),lang_code); - const msg_start = `${langJson[lang_code].start.start1}(https://t.me/${process.env.BOT_USERNAME}?start=help)${langJson[lang_code].start.start2}(${langJson[lang_code].defaultRules}).${langJson[lang_code].start.start3}` + const msg_start = `${langJson[lang_code].start.start1}(https://t.me/${process.env.BOT_USERNAME}?start=help)${langJson[lang_code].start.start2}(${langJson[lang_code].defaultRules}).${msg.is_forum? langJson[lang_code].start.start3topic : langJson[lang_code].start.start3}` queue.add(async () => {try{await bot.sendMessage(msg.chat.id, msg_start, msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id, disable_web_page_preview: true}: {parse_mode: "Markdown", disable_web_page_preview: true})}catch{}}) return; } catch (e){ @@ -125,9 +125,9 @@ const callback = async (queue:any, db: any, settings: groupSettings, bot: any, b const topicMode = async (queue: any, db:any, bot: any, settings: groupSettings, msg: TelegramBot.Message): Promise<[string,string]> => { // tg bugging, won't display icon_color if set const lang_code = msg?.from?.language_code - const topicRules = await queue.add(async () => {try{const val = await bot.createForumTopic(msg.chat.id, lang_code == "en" ? 'Rules': 'Reglas')//, {icon_custom_emoji_id: '5357193964787081133'}) + const topicRules = await queue.add(async () => {try{const val = await bot.createForumTopic(msg.chat.id, lang_code == "en" ? 'Rules': 'Reglas', {icon_custom_emoji_id: '5357193964787081133'}) return val}catch(e){console.log(e)}}); - const topicModeration = await queue.add(async () => {try{const val = await bot.createForumTopic(msg.chat.id, lang_code == "en" ? 'Notifications' : 'Notificaciones')//, {icon_custom_emoji_id: '5417915203100613993'}) + const topicModeration = await queue.add(async () => {try{const val = await bot.createForumTopic(msg.chat.id, lang_code == "en" ? 'Notifications' : 'Notificaciones', {icon_custom_emoji_id: '5417915203100613993'}) return val}catch(e){console.log(e)}}); if(!topicRules || !topicModeration) return From 9268e3e694772d3586192b2d2c2265cd9f034800 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Tue, 24 Jan 2023 20:26:16 +0000 Subject: [PATCH 033/111] feat: roll back 4 levels of bans to 3 --- lib/cron.ts | 28 +++++++++++----------------- lib/db.ts | 16 ++++------------ lib/telegram/commands/getReports.ts | 4 +--- lib/telegram/index.ts | 2 -- 4 files changed, 16 insertions(+), 34 deletions(-) diff --git a/lib/cron.ts b/lib/cron.ts index 603e96a..94c760b 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -466,9 +466,7 @@ const calcPenalty = (ban_level: number, timestamp_finalized: number): number => return timestamp_finalized + 86400 else if (ban_level == 2) return timestamp_finalized + 604800 - else if (ban_level == 3) - return timestamp_finalized + 2678400 - else + else (ban_level == 3) return timestamp_finalized + 31536000 } @@ -476,22 +474,18 @@ const calcPenaltyPhrase = (settings: groupSettings, ban_level: number, enforceme if (settings.lang === 'es'){ if(ban_level == 1) - return finalize? enforcement? 'primera vez y está sujeta a un baneo de 1 día' : 'primera vez y se recomienda una prohibición de 1 día' : enforcement? 'primera vez y se silencia durante 1 día durante el resto del periodo del informe': 'primera vez y se le recomienda un silencio de 1 día por el resto del período del informe' - else if (ban_level == 2) - return finalize? enforcement? 'segunda vez y está sujeto a una prohibición de 1 semana' : 'segunda vez y se recomienda una prohibición de 1 semana': enforcement? 'segunda vez y se silencia durante 1 día durante el resto del periodo del informe': 'segunda vez y se le recomienda un silencio de 1 día para el resto del periodo del informe' - else if (ban_level == 3) - return finalize? enforcement? 'tercera vez y está sujeto a una prohibición de 1 mes' : 'tercera vez y se recomienda una prohibición de 1 mes' : enforcement? 'trecera vez y se silencia durante 1 día durante el resto del periodo del informe': 'tercera vez y se le recomienda un silencio de 1 día por el resto del período del informe' - else - return finalize? enforcement? 'al menos cuatro veces y está sujeto a una prohibición de 1 año' : 'al menos cuatro veces y se le recomienda una prohibición de 1 mes' : enforcement? 'cuarta vez y se silencia durante 1 día durante el resto del periodo del informe': 'al menos cuatro veces y se le recomienda un silencio de 1 día para el resto del período del informe.' + return finalize? enforcement? 'primera vez y está sujeta a un baneo de 1 día' : 'primera vez y se recomienda una prohibición de 1 día' : enforcement? 'primera vez y se silencia durante 1 día durante el resto del periodo del informe': 'primera vez y se le recomienda un silencio de 1 día por el resto del período del informe' + else if (ban_level == 2) + return finalize? enforcement? 'segunda vez y está sujeto a una prohibición de 1 semana' : 'segunda vez y se recomienda una prohibición de 1 semana': enforcement? 'segunda vez y se silencia durante 1 día durante el resto del periodo del informe': 'segunda vez y se le recomienda un silencio de 1 día para el resto del periodo del informe' + else + return finalize? enforcement? 'tercera vez y está sujeto a una prohibición de 1 mes' : 'tercera vez y se recomienda una prohibición de 1 mes' : enforcement? 'trecera vez y se silencia durante 1 día durante el resto del periodo del informe': 'tercera vez y se le recomienda un silencio de 1 día por el resto del período del informe' } else { if(ban_level == 1) - return finalize? enforcement? 'first time and is subject to a 1 day ban' : 'first time and is recommended a 1 day ban' : enforcement? 'first time and is muted for 1 day during the remainder of the report period': 'first time and is recommended a 1 day mute for the remainder of the report period' - else if (ban_level == 2) - return finalize? enforcement? 'second time and is subject to a 1 week ban' : 'second time and is recommended a 1 week ban': enforcement? 'second time and is muted for 1 day during the remainder of the report period': 'second time and is recommended a 1 day mute for the remainder of the report period' - else if (ban_level == 3) - return finalize? enforcement? 'third time and is subject to a 1 month ban' : 'third time and is recommended a 1 month ban' : enforcement? 'third time and is muted for 1 day during the remainder of the report period': 'third time and is recommended a 1 day mute for the remainder of the report period' - else - return finalize? enforcement? 'atleast four times and is subject to a 1 year ban' : 'atleast four times and is recommended a 1 year ban' : enforcement? 'four times and is muted for 1 day during the remainder of the report period': 'four times and is recommended a 1 day mute for the remainder of the report period' + return finalize? enforcement? 'first time and is subject to a 1 day ban' : 'first time and is recommended a 1 day ban' : enforcement? 'first time and is muted for 1 day during the remainder of the report period': 'first time and is recommended a 1 day mute for the remainder of the report period' + else if (ban_level == 2) + return finalize? enforcement? 'second time and is subject to a 1 week ban' : 'second time and is recommended a 1 week ban': enforcement? 'second time and is muted for 1 day during the remainder of the report period': 'second time and is recommended a 1 day mute for the remainder of the report period' + else + return finalize? enforcement? 'third time and is subject to a 1 month ban' : 'third time and is recommended a 1 month ban' : enforcement? 'third time and is muted for 1 day during the remainder of the report period': 'third time and is recommended a 1 day mute for the remainder of the report period' } } diff --git a/lib/db.ts b/lib/db.ts index f95f706..2c2d16e 100644 --- a/lib/db.ts +++ b/lib/db.ts @@ -602,11 +602,8 @@ const getLocalBanHistory = (db: any, platform: string, userId: string, group_id: const banLevel2 = getLocalBanHistoryInduction(db,platform,userId,group_id,banLevel1.timestamp, finalized) if(!banLevel2) return [base, banLevel1] - const banLevel3 = getLocalBanHistoryInduction(db,platform,userId,group_id,banLevel2.timestamp, finalized) - if(!banLevel3) - return [base, banLevel1, banLevel2] - return [base, banLevel1, banLevel2, banLevel3] + return [base, banLevel1, banLevel2] } const getLocalBanHistoryBase = (db: any, platform: string, userId: string, group_id: string, finalized: boolean) => { @@ -650,11 +647,8 @@ const getFederatedBanHistory = (db: any, platform: string, userId: string, feder const banLevel2 = getFederatedBanHistoryInduction(db,platform,userId,federation_id,banLevel1.timestamp, finalized) if(!banLevel2) return [base, banLevel1] - const banLevel3 = getFederatedBanHistoryInduction(db,platform,userId,federation_id,banLevel2.timestamp, finalized) - if(!banLevel3) - return [base, banLevel1, banLevel2] - return [base, banLevel1, banLevel2, banLevel3] + return [base, banLevel1, banLevel2] } const getFederatedBanHistoryBase = (db: any, platform: string, userId: string, federation_id: string, finalized: boolean) => { @@ -710,10 +704,8 @@ const getFederatedFollowingBanHistory = (db: any, platform: string, userId: stri const banLevel2 = getFederatedFollowingBanHistoryInduction(db,platform,userId,group_id,federation_id,banLevel1.timestamp, finalized) if(!banLevel2) return [base, banLevel1] - const banLevel3 = getFederatedFollowingBanHistoryInduction(db,platform,userId,group_id,federation_id,banLevel1.timestamp, finalized) - if(!banLevel3) - return [base, banLevel1, banLevel2] - return [base, banLevel1, banLevel2, banLevel3] + + return [base, banLevel1, banLevel2] } const getFederatedFollowingBanHistoryBase = (db: any, platform: string, userId: string, group_id: string, federation_id: string, finalized: boolean) => { diff --git a/lib/telegram/commands/getReports.ts b/lib/telegram/commands/getReports.ts index bc6eff1..bfa20a5 100644 --- a/lib/telegram/commands/getReports.ts +++ b/lib/telegram/commands/getReports.ts @@ -153,9 +153,7 @@ const calcPenalty = (ban_level: number, timestamp_finalized: number): number => return timestamp_finalized + 86400 else if (ban_level == 2) return timestamp_finalized + 604800 - else if (ban_level == 3) - return timestamp_finalized + 2678400 - else + else (ban_level == 3) return timestamp_finalized + 31536000 } diff --git a/lib/telegram/index.ts b/lib/telegram/index.ts index 14ec0ed..cbd28e0 100644 --- a/lib/telegram/index.ts +++ b/lib/telegram/index.ts @@ -209,8 +209,6 @@ const calcPenalty = (ban_level: number, timestamp_finalized: number): number => return timestamp_finalized + 86400 else if (ban_level == 2) return timestamp_finalized + 604800 - else if (ban_level == 3) - return timestamp_finalized + 2678400 else return timestamp_finalized + 31536000 } From 077ccd7dcc459017235adc563e2ecef75e4ad1ae Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Tue, 24 Jan 2023 20:29:23 +0000 Subject: [PATCH 034/111] chore: format updates --- lib/telegram/assets/langNew.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/telegram/assets/langNew.json b/lib/telegram/assets/langNew.json index e2aba7b..2979052 100644 --- a/lib/telegram/assets/langNew.json +++ b/lib/telegram/assets/langNew.json @@ -185,20 +185,20 @@ "help": { "DM": "Get Help (DM)", "DM2": "DM me for help : )", - "help": "*Help*\n\nHi! My name is Susie. I'm a [Kleros Moderate](https://kleros.io/moderate) bot, here to help you manage your groups!\n\nI crowdsource moderation using [Reality.eth](https://reality.eth.limo/) and [Kleros](https://kleros.gitbook.io/docs/) on [Gnosis Chain](https://www.gnosis.io/).\n\nModeration is resolved with an escalation game and the outcome can be disptued in the Kleros Court.\n\nHelpful commands:\n - /start: Starts me. You probably already used this.\n - /help: Sends this message to tell you more about myself.\n\nSelect a feature to learn more. Ask questions in @SusieSupport or read the [docs](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator)." + "help": "*Help*\n\nHi! My name is Susie. I'm a [Kleros Moderate](https://kleros.io/moderate) bot, here to help you manage your groups!\n\nI crowdsource moderation using [Reality.eth](https://reality.eth.limo/) and [Kleros](https://kleros.gitbook.io/docs/) on [Gnosis Chain](https://www.gnosis.io/).\n\nModeration is resolved with an escalation game and the outcome can be disptued in the Kleros Court.\n\nHelpful commands:\n - /start: Starts me.\n - /help: Sends this help message.\n\nSelect a feature to learn more. Ask questions in @SusieSupport or read the [docs](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator)." , "back": "back", - "Greeting1": "👋 *Greeting* 👋\n\nWelcome your members with a greeting informing them of the group rules.\n\nAfter 5 minutes, the previous welcome messages will get deleted\n\nCaptchas remain for up to 5 minutes. If a user forgets to respond within 5 minutes, they should rejoin the group to prompt a new captcha.\n\n*Admin commands:*\n- `/welcome` : Toggles on/off welcomes messages.\n- `/captcha` : Toggles on/off captcha.", + "Greeting1": "👋 *Greeting* 👋\n\nWelcome your members with a greeting informing them of the group rules.\n\nAfter 5 minutes, the previous welcome message or captcha will get deleted\n\n*Admin commands:*\n- `/welcome` : Toggles on/off welcomes messages.\n- `/captcha` : Toggles on/off captcha.", "Language1": "🗣️ *Languages* 🗣️\n\nSusie's replies can be changed to one of the languages below.\n\n- EN (English)\n- ES (Español)\n\nContent moderation requires a nuanced understanding of context and language. Please make sure to set the appropriate language for your community for effective moderation.\n\n*Admin commands*: \n- `/lang`: Set your preferred language.", "Topics1": "ℹ️ *Topics* ℹ️\n\nTopics allow large groups to focus discussion in dedicated **topic** chats. Susie supports topics. When changing a group to topic mode, you will need to /start Susie again.\n\n*Admin commands*:\n- `/start`: Start topic mode.", "Evidence1": "🔍 *Evidence* 🔍\n\nTo prevent important messages from deletion, pre-emptively, messages can be saved as evidence.\n\n*User commands*:\n- `/evidence` : Saves message as evidence.", - "Report1": "🚨 *Report* 🚨\n\nReports create content moderation questions on the crowdsourcing platform Reality.Eth asking,\n\n'did the user break the rules?'\n\nThe question can be answered yes/no with a bond (5 DAI). Answers can be disputed in the Kleros court.\n\nSuccessful reports result in escalating penalties (1 day, 1 week, 1 month, 1 year bans).\n\n*User commands*:\n- `/report` : Reports message.\n- `/info`: Returns active reports\n\n*Admin commands*:\n-`/adminreportable` Toggles reportability of admins.\n- `/trial` Toggles trial mode where users are not penalized", + "Report1": "🚨 *Report* 🚨\n\nReports create content moderation questions on the crowdsourcing platform Reality.Eth asking,\n\n***Did the user break the rules?***\n\nThe question can be answered yes/no with a bond (5 xDAI). Answers can be disputed in the Kleros court.\n\nSuccessful reports result in escalating penalties (1 day, 1 week, 1 year ban).\n\n*User commands*:\n- `/report` : Reports message.\n- `/info`: Returns active reports\n\n*Admin commands*:\n-`/adminreportable` Toggles reportability of admins.\n- `/trial` Toggles trial mode where users are not penalized", "Rules1": "📄 *Rules* 📄\n\nEvery groups starts with [default rules](https://ipfs.kleros.io/ipfs/Qme3Qbj9rKUNHUe9vj9rqCLnTVUCWKy2YfveQF8HiuWQSu/Kleros%20Moderate%20Community%20Rules.pdf).\n\n***Rule Writing Tips***:\n\n- State the group culture in a preamble.\n- Number each rule.\n- Be specific.\n\n*User commands*:\n- `/rules`: Returns current rules\n*Admin commands*:\n- `/setrules` or : Sets the rules to the url or message", "Court1": "⚖️ *Court* ⚖️\n\nModeration questions are resolved by the [Kleros Court](https://kleros.gitbook.io/docs/) with a jury of moderators. If the jury made a mistake, the case can be appealed, drawing a larger pool of jurors and providing an opportunity to provide more context, analysis, and arguments.\n\nIf you would like a chance to serve as a jury member, get PNK ([Gnosis Chain](https://swapr.eth.link/#/swap?chainId=100) or [Mainnet](https://app.uniswap.org/#/swap?outputCurrency=0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d&inputCurrency=ETH)) and [stake](https://court.kleros.io/) in the Kleros court.\n\nTo discuss the merits of a dispute, see @klerosjuror. To learn more about Kleros, ask a question in @Kleros", - "Lawyer1": "🧑‍⚖️ *Find a Lawyer* 🧑‍⚖️\n\nDisputes over reports can be complicated.\n\nIf you need help arguing your case in the Kleros court, consider asking help from a Kleros [lawyer](https://t.me/+9fvGGkGfSZ1hZDBk).", - "Privacy1": "🕵️ *Privacy* 🕵️\n\nEffective moderation depends on access to the full context of a reported message. To provide context, users can request Susie to save messages to submit as evidence on their behalf. Susie manages moderation private and public groups differently,\n\n- In *private* groups, moderators depend on evidence submissions alone.\n- In *public* groups, moderators have access to the full public chat history.", + "Lawyer1": "🧑‍⚖️ *Find a Lawyer* 🧑‍⚖️\n\nDisputes over content moderation questions can be complicated.\n\nIf you need help arguing your case in the Kleros court, consider asking help from a Kleros [lawyer](https://t.me/+9fvGGkGfSZ1hZDBk).", + "Privacy1": "🕵️ *Privacy* 🕵️\n\nTo provide context, users can request Susie to save messages to submit as evidence on their behalf. Susie manages moderation private and public groups differently,\n\n- ***Private Groups***: Moderators depend on evidence submissions alone.\n\n- ***Public Groups***: Moderators have access to the full public chat history.", "Notifications1": "🔔 *Notifications* 🔔\n\nNotifications can be sent to a separate channel to avoid cluttering the main group.\n\nHow to enable notification channels:\n\n1. Make a channel\n2. Add Susie\n3. Susie will send a channel ID\n4. Use that channel ID to set notifications with /setchannel in the original group\n\n*User commands*:\n- `/notifications`: Returns current notification channel\n*Admin commands*:\n- `/setchannel` : Sets the notification channel to the specified channel id\n- `/setfedchannel` : Sets the notification channel for your federation to the specified channel id", "Federations1": "🌐 *Federations*\n\nModerating a single group is hard, but managing multiple is even harder. Do you have to ban spammers manually, in all your groups?\n\nNo more! With federations, Susie can enforce a ban on a user in all federated groups.\n\n*User commands*:\n- `/fedinfo`: Returns current federation\n*Admin commands*:\n- `/newfed`: Creates a federation\n- `/joinfed`: Joins the current group to a Federation", - "Gnosis1": "⛓️ *Gnosis Chain* ⛓️\n\nSusie uses [xDAI](https://docs.gnosischain.com/about/tokens/xdai), a stable coin, on [Gnosis Chain](https://www.gnosis.io/). Don't know what that means? It means Susie uses a cheap and fast public ledger to coordinate moderation fairly and transparently.\n\nDon't have any xDAI on Gnosis Chain? No problem, there's a (cheap, fast) [bridge](https://bridge.connext.network/?receivingChainId=100&receivingAssetId=0x0000000000000000000000000000000000000000) for that. \n\nWhat's crypto? I heard about that on the news, I don't want anything to do with crypto. No problem, you can ask for help from freelance moderators in @SusieSupport.\n\nDon't have any cryptocurrency? No problem, there's a convenient [fiat on-ramp](https://www.mtpelerin.com/buy-xdai) (credit card or bank transfer) to buy DAI on Gnosis Chain.\n\nNeed help adding the Gnosis Chain network to your wallet? Don't worry, there's a [guide](https://docs.gnosischain.com/tools/wallets/metamask#2-configure) for that.\n\nNeed more help? Don't worry, there's a @SusieSupport group for that", + "Gnosis1": "⛓️ *Gnosis Chain* ⛓️\n\nSusie uses the stable coin xDai on [Gnosis Chain](https://www.gnosis.io/), a public ledger to coordinate moderation fairly and transparently.\n\nDon't have any xDAI on Gnosis Chain? No problem, there's a [bridge](https://bridge.connext.network/?receivingChainId=100&receivingAssetId=0x0000000000000000000000000000000000000000) for that. \n\nWhat's crypto? I don't want anything to do with crypto. No problem, you can ask for help from freelance moderators in @SusieSupport.\n\nDon't have any cryptocurrency? No problem, there's a convenient [fiat on-ramp](https://www.mtpelerin.com/buy-xdai) (credit card or bank transfer) to buy xDai on Gnosis Chain.\n\nNeed help adding the Gnosis Chain network to your wallet? Don't worry, there's a [guide](https://docs.gnosischain.com/tools/wallets/metamask#2-configure) for that.\n\nNeed more help? Don't worry, there's a @SusieSupport group for that", "Greeting": "👋 Greeting", "Language": "🗣️ Language", "Topics": "ℹ️ Topics", @@ -368,26 +368,26 @@ "already": "Ya comenzó." }, "welcome": { - "welcome": "Hola, soy Susie, un bot [Kleros Moderate](https://kleros.io/moderate/). Necesito permiso de un administrador para /start. ¿Cómo puedo ayudar con la moderación? Pregunto "¿Un usuario ha infringido las normas?" en la plataforma de crowdsourcing [Reality.Eth](https://realityeth.github.io/).n2. La pregunta se responde con un juego de escalada usando xDai en [Gnosis Chain](https://www.gnosis.io/).\n3. La respuesta se puede disputar en el tribunal [Kleros](https://kleros.io/).\n\nPara saber más, [DM](https://t.me/KlerosModeratorBot?start=help) mío, lee mis [docs](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie), o haz una pregunta en @SusieSupport." + "welcome": "Hola, soy Susie, un bot [Kleros Moderate](https://kleros.io/moderate/). Necesito permiso de un administrador para /start. ¿Cómo puedo ayudar con la moderación? Pregunto '¿Un usuario ha infringido las normas?' en la plataforma de crowdsourcing [Reality.Eth](https://realityeth.github.io/).n2. La pregunta se responde con un juego de escalada usando xDai en [Gnosis Chain](https://www.gnosis.io/).\n3. La respuesta se puede disputar en el tribunal [Kleros](https://kleros.io/).\n\nPara saber más, [DM](https://t.me/KlerosModeratorBot?start=help) mío, lee mis [docs](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie), o haz una pregunta en @SusieSupport." }, "defaultRules": "https://ipfs.kleros.io/ipfs/QmSHAjfD1MYPtyopFoXcUQ5Ny3sfs5re1yz3h3TZ5qGDsp/Kleros%20Moderate%20Normas%20comunitarias.pdf", "help": { "DM": "Obtener ayuda (DM)", "DM2": "DM de ayuda : )", - "help": "*Ayuda*\n\n¡Hola! Me llamo Susie. Soy un bot [Kleros Moderate](https://kleros.io/moderate), ¡aquí para ayudarte a gestionar tus grupos!\n\n¡Modero en grupo usando [Reality.eth](https://reality.eth.limo/) y [Kleros](https://kleros.gitbook.io/docs/) en [Gnosis Chain](https://www.gnosis.io/).\n\nLa moderación se resuelve con un juego de escalada y el resultado se puede disputar en el Tribunal Kleros.\n\nComandos útiles:\n - /start: Me inicia. Probablemente ya lo hayas usado. \n - /help: Envía este mensaje para contarte más sobre mí.\n\nSelecciona una función para saber más. Haz preguntas en @SusieSupport o lee los [docs](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator)." + "help": "*Ayuda*\n\n¡Hola! Me llamo Susie. Soy un bot [Kleros Moderate](https://kleros.io/moderate), ¡aquí para ayudarte a gestionar tus grupos!\n\n¡Modero en grupo usando [Reality.eth](https://reality.eth.limo/) y [Kleros](https://kleros.gitbook.io/docs/) en [Gnosis Chain](https://www.gnosis.io/).\n\nLa moderación se resuelve con un juego de escalada y el resultado se puede disputar en el Tribunal Kleros.\n\nComandos útiles:\n - /start: Me inicia.\n - /help: Envía este mensaje de ayuda.\n\nSelecciona una función para saber más. Haz preguntas en @SusieSupport o lee los [docs](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator)." , "back": "back", - "Greeting1": "👋 *Saludos* 👋 Bienvenida a tus miembros con un saludo informándoles de las reglas del grupo. Después de 5 minutos, los mensajes de bienvenida anteriores se borrarán. Si un usuario se olvida de responder dentro de los 5 minutos, deben volver a unirse al grupo para solicitar una nueva captcha.\n\n*Comandos de administrador:*\n- `/welcome` : Activa / desactiva los mensajes de bienvenida.\n- `/captcha` : Activa / desactiva las reglas captcha.", + "Greeting1": "👋 *Saludos* 👋 Bienvenida a tus miembros con un saludo informándoles de las reglas del grupo. Después de 5 minutos, los mensajes de bienvenida o captcha anteriores se borrarán.\n\n*Comandos de administrador:*\n- `/welcome` : Activa / desactiva los mensajes de bienvenida.\n- `/captcha` : Activa / desactiva las reglas captcha.", "Language1": "🗣️ *Idiomas* 🗣️\n\nLas respuestas de Susie pueden cambiarse a uno de los siguientes idiomas.\n\n- EN (English)\n- ES (Español)\n\nLa moderación de contenidos requiere una comprensión matizada del contexto y del lenguaje. Por favor, asegúrese de establecer el idioma apropiado para su comunidad para una moderación efectiva. \n\n*Comandos de administración*:\n`/lang`: Establezca su idioma preferido.", "Topics1": "ℹ️ *Temas* ℹ️\n\nLos temas permiten a los grandes grupos centrar el debate en chats dedicados a **temas**. Susie es compatible con los temas. Cuando cambie un grupo a modo de tema, necesitará /iniciar Susie de nuevo.\n\n*Comandos de administrador*:\n- `/start`: Inicia el modo por temas.", "Evidence1": "🔍 *Evidencia* 🔍\n\nPara evitar que se borren mensajes importantes, de forma preventiva, se pueden guardar mensajes como evidencia.\n\n*Comandos de usuario*:\n- `/evidence` : Guarda el mensaje como evidencia.", - "Report1": "🚨 *Informe* 🚨 \n\nLos informes crean preguntas de moderación de contenidos en la plataforma de crowdsourcing Reality.Eth preguntando,\n\n'¿el usuario infringió las normas?'\n\nLa pregunta puede responderse sí/no con un bono (5 DAI). Las respuestas pueden ser impugnadas en el tribunal Kleros.\n\nLos informes exitosos resultan en sanciones escalonadas (1 día, 1 semana, 1 mes, 1 año de prohibición).\n\n*Comandos de usuario*:\n- `/report` : Informa del mensaje.\n- `/info`: Devuelve los informes activos.n\n*Comandos de administrador*:\n-`/adminreportable` Activa la posibilidad de informar de los administradores.\n- `/trial` Activa el modo de prueba en el que los usuarios no son penalizados.", + "Report1": "🚨 *Informe* 🚨 \n\nLos informes crean preguntas de moderación de contenidos en la plataforma de crowdsourcing Reality.Eth preguntando,\n\n'¿el usuario infringió las normas?'\n\nLa pregunta puede responderse sí/no con un bono (5 xDAI). Las respuestas pueden ser impugnadas en el tribunal Kleros.\n\nLos informes exitosos resultan en sanciones escalonadas (1 día, 1 semana, 1 año de prohibición).\n\n*Comandos de usuario*:\n- `/report` : Informa del mensaje.\n- `/info`: Devuelve los informes activos.n\n*Comandos de administrador*:\n-`/adminreportable` Activa la posibilidad de informar de los administradores.\n- `/trial` Activa el modo de prueba en el que los usuarios no son penalizados.", "Rules1": "📄 *Reglas* 📄\n\nTodos los grupos empiezan con [reglas por defecto](https://ipfs.kleros.io/ipfs/QmSHAjfD1MYPtyopFoXcUQ5Ny3sfs5re1yz3h3TZ5qGDsp/Kleros%20Moderate%20Normas%20comunitarias.pdf). \n\n***Consejos para la redacción de reglas***:\n\n -Enuncie la cultura del grupo en un preámbulo.\n -Numere cada regla.\nSea específico.\n\n*Comandos de usuario*:\n-`/rules`: Devuelve las reglas.\n*Comandos de administrador*:\n- `/setrules` o : Establece las reglas a la url o mensaje.", "Court1": "⚖️ *Corte* ⚖️\n\nLas preguntas de moderación las resuelve el [Kleros Court](https://kleros.gitbook.io/docs/) con un jurado de moderadores. Si el jurado cometió un error, el caso puede ser apelado, atrayendo a un grupo más grande de miembros del jurado y proporcionando la oportunidad de proporcionar más contexto, análisis y argumentos.\n\nSi desea tener la oportunidad de servir como miembro del jurado, obtenga PNK ([Gnosis Chain](https://swapr.eth.link/#/swap?chainId=100) o [Mainnet](https://app.uniswap.org/#/swap?outputCurrency=0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d&inputCurrency=ETH)) y [stake](https://court.kleros.io/) en el tribunal de Kleros.\n\nPara discutir el fondo de una disputa, consulte @klerosjuror.", "Lawyer1": "🧑‍⚖️ *Busque un abogado* 🧑‍⚖️ \n\nLas disputas sobre informes pueden ser complicadas.\n\nSi necesita ayuda para defender su caso ante el tribunal kleros, considere pedir ayuda a un [abogado] kleros(https://t.me/+9fvGGkGfSZ1hZDBk).", - "Privacy1": "🕵️ *Privacidad* 🕵️\n\nLa moderación eficaz depende del acceso al contexto completo de un mensaje denunciado. Para proporcionar este contexto, los usuarios pueden solicitar a Susie que guarde mensajes para presentarlos como pruebas en su nombre. Susie gestiona la moderación de los grupos privados y públicos de forma diferente.\n\n-En los grupos *privados*, los moderadores dependen únicamente del envío de pruebas.\n-En los grupos *públicos*, los moderadores tienen acceso a todo el historial del chat público.", + "Privacy1": "🕵️ *Privacidad* 🕵️\n\nPara proporcionar contexto, los usuarios pueden solicitar a Susie que guarde mensajes para presentarlos como pruebas en su nombre. Susie gestiona la moderación de grupos privados y públicos de forma diferente,\n\n- *** Grupos Privados ***: Los moderadores dependen únicamente de las pruebas presentadas\n\n- *** Grupos Públicos ***: Los moderadores tienen acceso a todo el historial del chat público.", "Notifications1": "🔔 *Notificaciones* 🔔\n\nLas notificaciones pueden enviarse a un canal independiente para no saturar el grupo principal.\n\nCómo habilitar canales de notificación:\n\n1. Crea un canal\n2. Añade a Susie\n3. Susie enviará un ID de canal\n4. Utiliza ese ID de canal para establecer notificaciones con /setchannel en el grupo original\n\n*Comandos de usuario*:\n- `/notificaciones`: Devuelve el canal de notificaciones actual\n*Comandos de administrador*:\n- `/setchannel` : Establece el canal de notificaciones en el id de canal especificado\n- `/setfedchannel` : Establece el canal de notificaciones para su federación en el id de canal especificado", "Federations1": "🌐 *Federaciones*\n\nModerar un solo grupo es difícil, ¿pero gestionar varios lo es aún más? ¿Tienes que bloquear manualmente a los spammers en todos tus grupos? Con las federaciones, Susie puede aplicar una prohibición a un usuario en todos los grupos federados.\n\n*Comandos de usuario*:\n- `/fedinfo`: Devuelve la federación actual: Crea una federación- `/joinfed`: Une el grupo actual a una federación", - "Gnosis1": "⛓️ *Gnosis Chain* ⛓️\n\nSusie usa [xDAI](https://docs.gnosischain.com/about/tokens/xdai), una moneda estable, en [Gnosis Chain](https://www.gnosis.io/). ¿No sabes lo que eso significa? Significa que Susie utiliza un libro de contabilidad público barato y rápido para coordinar la moderación de forma justa y transparente. \n\n¿No tienes ningún xDAI en Gnosis Chain? No hay problema, hay un (barato, rápido) [puente](https://bridge.connext.network/?receivingChainId=100&receivingAssetId=0x0000000000000000000000000000000000000000) para eso. \n\n¿Qué es crypto? He oído hablar de eso en las noticias, no quiero tener nada que ver con crypto. No hay problema, puedes pedir ayuda a los moderadores independientes en @SusieSupport.\n\n¿No tienes ninguna criptodivisa? No hay problema, hay una conveniente [fiat on-ramp](https://www.mtpelerin.com/buy-xdai) (tarjeta de crédito o transferencia bancaria) para comprar DAI en Gnosis Chain.\n\n¿Necesitas ayuda para añadir la red Gnosis Chain a tu cartera? No te preocupes, hay una [guía](https://docs.gnosischain.com/tools/wallets/metamask#2-configure) para eso.\n\n¿Necesitas más ayuda? No te preocupes, hay un grupo @SusieSupport para eso.", + "Gnosis1": "⛓️ *Gnosis Chain* ⛓️\n\nSusie usa [xDAI](https://docs.gnosischain.com/about/tokens/xdai), una moneda estable, en [Gnosis Chain](https://www.gnosis.io/). ¿No sabes lo que eso significa? Significa que Susie utiliza un libro de contabilidad público barato y rápido para coordinar la moderación de forma justa y transparente. \n\n¿No tienes ningún xDAI en Gnosis Chain? No hay problema, hay un (barato, rápido) [puente](https://bridge.connext.network/?receivingChainId=100&receivingAssetId=0x0000000000000000000000000000000000000000) para eso. \n\n¿Qué es crypto? He oído hablar de eso en las noticias, no quiero tener nada que ver con crypto. No hay problema, puedes pedir ayuda a los moderadores independientes en @SusieSupport.\n\n¿No tienes ninguna criptodivisa? No hay problema, hay una conveniente [fiat on-ramp](https://www.mtpelerin.com/buy-xdai) (tarjeta de crédito o transferencia bancaria) para comprar xDAI en Gnosis Chain.\n\n¿Necesitas ayuda para añadir la red Gnosis Chain a tu cartera? No te preocupes, hay una [guía](https://docs.gnosischain.com/tools/wallets/metamask#2-configure) para eso.\n\n¿Necesitas más ayuda? No te preocupes, hay un grupo @SusieSupport para eso.", "Greeting": "👋 Saludos", "Language": "🗣️ Idiomas", "Topics": "ℹ️ Temas", From f841c94614088adadc975818ad21cca98e2ef46f Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Wed, 25 Jan 2023 00:17:07 +0000 Subject: [PATCH 035/111] fix: permissions --- lib/telegram/commands/greeting.ts | 2 +- lib/telegram/index.ts | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/telegram/commands/greeting.ts b/lib/telegram/commands/greeting.ts index 04ebf5f..8ddf933 100644 --- a/lib/telegram/commands/greeting.ts +++ b/lib/telegram/commands/greeting.ts @@ -56,7 +56,7 @@ const callback = async (db: any, queue: any, bot: any, settings: groupSettings, ] } }; - const msg_greeting_full = `${langJson[settings.lang].greeting.greeting0} [${msg.from.first_name}](tg://user?id=${msg.from.id}). ${msg_greeting} ${langJson[settings.lang].greeting.greeting1}(${settings.rules}). ${langJson[settings.lang].greeting.greeting2}` + const msg_greeting_full = `${langJson[settings.lang].greeting.greeting0} [${msg.from.first_name}](tg://user?id=${msg.from.id}). ${msg_greeting}${langJson[settings.lang].greeting.greeting1}(${settings.rules}). ${langJson[settings.lang].greeting.greeting2}` console.log('full') console.log(msg_greeting_full) let msg_welcome; diff --git a/lib/telegram/index.ts b/lib/telegram/index.ts index cbd28e0..96bc235 100644 --- a/lib/telegram/index.ts +++ b/lib/telegram/index.ts @@ -163,9 +163,7 @@ bot.on("new_chat_members", async function (chatMemberUpdated: any) { if (calculateHistory.length > 0){ var max_timestamp = 0 for (const ban of calculateHistory){ - if (ban.timestamp_active > max_timestamp) - max_timestamp = ban.timestamp_active - else if (ban.timestamp_finalized > max_timestamp) + if (ban.timestamp_finalized > max_timestamp) max_timestamp = ban.timestamp_finalized } const parole_time = calcPenalty(calculateHistory.length, max_timestamp) @@ -188,8 +186,6 @@ bot.on("new_chat_members", async function (chatMemberUpdated: any) { for (const ban of calculateHistoryActive){ if (ban.timestamp_active > max_timestamp) max_timestamp = ban.timestamp_active - else if (ban.timestamp_finalized > max_timestamp) - max_timestamp = ban.timestamp_finalized } const parole_time = calcPenalty(calculateHistoryActive.length, max_timestamp) if (settings.enforcement && parole_time > Date.now()){ @@ -256,8 +252,11 @@ bot.on('callback_query', async function onCallbackQuery(callbackQuery: TelegramB } else if (Number(calldata[0]) === 5){ if (callbackQuery.from.id !== Number(calldata[1])) return; - const options = {can_send_messages: true, can_send_media_messages: true, can_send_polls: true, can_send_other_messages: true, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false}; - queue.add(async () => {try{await bot.restrictChatMember(callbackQuery.message.chat.id, callbackQuery.from.id, options)}catch{}}); + const permissions = await queue.add(async () => {try{const val = await bot.getChat(callbackQuery.message.chat.id).permissions + return val}catch{}}) + if(!permissions) + return + queue.add(async () => {try{await bot.restrictChatMember(callbackQuery.message.chat.id, callbackQuery.from.id, permissions)}catch{}}); queue.add(async () => {try{await bot.deleteMessage(callbackQuery.message.chat.id, callbackQuery.message.message_id)}catch{}}) } else if (Number(calldata[0]) === 6){ const member = await queue.add(async () => {try{const val = await bot.getChatMember(callbackQuery.message.chat.id, callbackQuery.from.id) From 546037aa16d3d32e5cad395a90393cb85a915104 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Wed, 25 Jan 2023 12:23:55 +0000 Subject: [PATCH 036/111] fix: permissions --- lib/cron.ts | 2 +- lib/telegram/index.ts | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/cron.ts b/lib/cron.ts index 94c760b..d2739f0 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -564,7 +564,7 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, if (settings.enforcement) for (const group of groups){ if(group.group_id == moderationInfo.UserHistory.group.groupID){ - const permissions = await queue.add(async () => {try{const val = await bot.getChat(moderationInfo.UserHistory.group.groupID).permissions + const permissions = await queue.add(async () => {try{const val = (await bot.getChat(moderationInfo.UserHistory.group.groupID)).permissions return val}catch{}}) if(!permissions) return diff --git a/lib/telegram/index.ts b/lib/telegram/index.ts index 96bc235..2cf24ed 100644 --- a/lib/telegram/index.ts +++ b/lib/telegram/index.ts @@ -144,10 +144,14 @@ bot.on("chat_member", async function (msg: any) { */ bot.on("new_chat_members", async function (chatMemberUpdated: any) { + + console.log(chatMemberUpdated) if(!hasStarted(chatMemberUpdated.chat.id)||throttled(chatMemberUpdated.from.id)||chatMemberUpdated.chat.type !== "supergroup") return; + console.log('hmmm1') const settings = validate(chatMemberUpdated.chat); + console.log('hmmm2') let calculateHistory = [] if (settings.federation_id) calculateHistory = getFederatedBanHistory(db, 'telegram', String(chatMemberUpdated.new_chat_member.id),settings.federation_id,true) @@ -156,6 +160,7 @@ bot.on("new_chat_members", async function (chatMemberUpdated: any) { else calculateHistory = getLocalBanHistory(db, 'telegram', String(chatMemberUpdated.new_chat_member.id),String(chatMemberUpdated.chat.id),true) + console.log('wtf') console.log(calculateHistory) // todo notify groups about federal outlaws when enforcement is false @@ -181,7 +186,10 @@ bot.on("new_chat_members", async function (chatMemberUpdated: any) { else calculateHistoryActive = getLocalBanHistory(db, 'telegram', String(chatMemberUpdated.new_chat_member.id),String(chatMemberUpdated.chat.id),false) - if (calculateHistoryActive.length > calculateHistory.length ){ + console.log('wtf') + console.log(calculateHistoryActive) + + if (calculateHistoryActive.length > 0){ var max_timestamp = 0 for (const ban of calculateHistoryActive){ if (ban.timestamp_active > max_timestamp) @@ -250,11 +258,14 @@ bot.on('callback_query', async function onCallbackQuery(callbackQuery: TelegramB console.log(e) } } else if (Number(calldata[0]) === 5){ + console.log(calldata) + console.log(callbackQuery.from.id) if (callbackQuery.from.id !== Number(calldata[1])) return; - const permissions = await queue.add(async () => {try{const val = await bot.getChat(callbackQuery.message.chat.id).permissions - return val}catch{}}) - if(!permissions) + const permissions = await queue.add(async () => {try{const val = (await bot.getChat(callbackQuery.message.chat.id)).permissions + return val}catch (e){console.log(e)}}) + console.log(permissions) + if(!permissions) return queue.add(async () => {try{await bot.restrictChatMember(callbackQuery.message.chat.id, callbackQuery.from.id, permissions)}catch{}}); queue.add(async () => {try{await bot.deleteMessage(callbackQuery.message.chat.id, callbackQuery.message.message_id)}catch{}}) From 8e7ab075b8f3431c31283e281a57ca422f1632e1 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Thu, 26 Jan 2023 12:09:10 +0000 Subject: [PATCH 037/111] fix: cron graph sync delay --- lib/cron.ts | 12 ++++++------ lib/telegram/commands/toggleWelcome.ts | 2 +- lib/telegram/index.ts | 11 ++++++++++- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/lib/cron.ts b/lib/cron.ts index d2739f0..4ec24f7 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -1,5 +1,5 @@ require('dotenv').config() -import {openDb, getGroupSettings, getRule, getCron, getFederationChannel, getInviteURL, getFederatedFollowingBanHistory, getLocalBanHistory, getFederatedBanHistory, setCron, getGroupsInAndFollowingFederation, getReportMessageTimestampAndActive, setReport} from "./db"; +import {openDb, getGroupSettings, getRule, getCron, getMultilangGroup, getFederationChannel, getInviteURL, getFederatedFollowingBanHistory, getLocalBanHistory, getFederatedBanHistory, setCron, getGroupsInAndFollowingFederation, getReportMessageTimestampAndActive, setReport} from "./db"; import request from "graphql-request"; import {BigNumber} from "ethers"; import TelegramBot from "node-telegram-bot-api"; @@ -42,7 +42,7 @@ const exit = async () => { let currentBlock = await web3.eth.getBlockNumber() if (!history) history = { - last_timestamp: currentTime, + last_timestamp: currentTime -20, last_block: currentBlock } @@ -52,11 +52,11 @@ const exit = async () => { //history.last_timestamp = 1674496352 //history.last_block = 8362931 - let timestampNew = Math.floor(Date.now()/1000); + let timestampNew = Math.floor(Date.now()/1000)-20; let timestampLastUpdated = history.last_timestamp let realitio_bot_checkpoint = Math.floor(timestampNew / 1800) - 1 while (1){ - timestampNew = Math.floor(Date.now()/1000) + timestampNew = Math.floor(Date.now()/1000)-20 const questionDelay = await update(timestampNew, timestampLastUpdated, botaddress); if(questionDelay) delayCheck(questionDelay, 0,timestampNew,timestampLastUpdated,botaddress) @@ -74,8 +74,8 @@ const exit = async () => { history.last_block = updateBlock } timestampLastUpdated = timestampNew - setCron(db, currentBlock,timestampNew) - await delay(60000) + setCron(db, history.last_block,timestampNew) + await delay(20000) } })() diff --git a/lib/telegram/commands/toggleWelcome.ts b/lib/telegram/commands/toggleWelcome.ts index e47de77..772e24e 100644 --- a/lib/telegram/commands/toggleWelcome.ts +++ b/lib/telegram/commands/toggleWelcome.ts @@ -26,7 +26,7 @@ const createWelcomeThread = async (queue:any, db: any, settings: groupSettings, return val}catch{}}); if(!topicWelcome) return - const msg_welcome = settings.lang === "en" ? `Welcome, this group is moderated with [Kleros Moderate](https://kleros.io/moderate/).` : "Bienvenido, este grupo está moderado con [Kleros Moderate](https://kleros.io/moderate/)." + const msg_welcome = settings.lang === "en" ? `This group is moderated with [Kleros Moderate](https://kleros.io/moderate/).` : "Este grupo está moderado con [Kleros Moderate](https://kleros.io/moderate/)." const msg1: TelegramBot.Message = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, msg_welcome, {parse_mode: "Markdown", message_thread_id: topicWelcome.message_thread_id}) return val}catch{}}); if(!msg1) diff --git a/lib/telegram/index.ts b/lib/telegram/index.ts index 2cf24ed..cec61e2 100644 --- a/lib/telegram/index.ts +++ b/lib/telegram/index.ts @@ -55,7 +55,7 @@ const batchedSend = _batchedSend( federation_id_following: '' } const ModeratorBot = require('node-telegram-bot-api'); -const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: {params: {"allowed_updates": JSON.stringify(["my_chat_member", "chat_member", "message","callback_query", "new_chat_members", "inline_query"])}}, testEnvironment: false}); +const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: {params: {"allowed_updates": JSON.stringify(["my_chat_member","callback_query", "new_chat_members"])}}, testEnvironment: false}); //const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: true, testEnvironment: true}); //bot. @@ -126,8 +126,17 @@ bot.on("my_chat_member", async function(myChatMember: any) { } }); +/* Forward messages to Susie for appeal +// include "member" in allowed updates to work +bot.on("message", async function (msg: TelegramBot.Message) { + if (msg.chat.type !== "private") + return; + console.log(msg) +}) +*/ //invite_url only present in private groups +// include "chat_member" in allowed updates to work /* bot.on("chat_member", async function (msg: any) { if (msg.new_chat_member){ From 152189dc24acec9b0efe8a3b71ed44eebc04b57f Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Thu, 26 Jan 2023 12:45:06 +0000 Subject: [PATCH 038/111] fix: polling --- lib/cron.ts | 2 +- lib/telegram/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/cron.ts b/lib/cron.ts index 4ec24f7..05f5698 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -98,7 +98,7 @@ const update = async (timestampNew: number, timestampLastUpdated: number,botaddr //console.log(queryModeration); //console.log('graphtime'); - console.log(queryModeration) + //console.log(queryModeration) const moderationActions = await request( process.env.MODERATE_SUBGRAPH, queryModeration diff --git a/lib/telegram/index.ts b/lib/telegram/index.ts index cec61e2..d485d37 100644 --- a/lib/telegram/index.ts +++ b/lib/telegram/index.ts @@ -55,7 +55,7 @@ const batchedSend = _batchedSend( federation_id_following: '' } const ModeratorBot = require('node-telegram-bot-api'); -const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: {params: {"allowed_updates": JSON.stringify(["my_chat_member","callback_query", "new_chat_members"])}}, testEnvironment: false}); +const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: {params: {"allowed_updates": JSON.stringify(["my_chat_member","message","callback_query", "new_chat_members"])}}, testEnvironment: false}); //const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: true, testEnvironment: true}); //bot. From 7dc7cd2c01022b775308f7af6ea397f4dbec1bed Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Thu, 26 Jan 2023 13:41:12 +0000 Subject: [PATCH 039/111] feat: handle no username --- lib/cron.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/cron.ts b/lib/cron.ts index 05f5698..d89f48a 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -342,7 +342,8 @@ for(const data of moderationActions.realityQuestionAnsweredFinalized){ if(!sherrif) continue //console.log(sherrif) - queue.add(async () => {try{await bot.sendMessage(data.group.groupID, `${langJson[settings.lang].reputation.sheriff} 🥇🤠[${sherrif.user.username}](tg://user?id=${sherrif.user.id})🤠🥇`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + const fromUsername = (sherrif.user.username || sherrif.user.first_name || `no-username-set`); + queue.add(async () => {try{await bot.sendMessage(data.group.groupID, `${langJson[settings.lang].reputation.sheriff} 🥇🤠[${fromUsername}](tg://user?id=${sherrif.user.id})🤠🥇`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); } catch(e){ console.log(e) } @@ -356,7 +357,8 @@ for(const data of moderationActions.realityQuestionAnsweredFinalized){ return val}catch{}}) if(!deputysherrif) continue - queue.add(async () => {try{await bot.sendMessage(data.group.groupID, `${langJson[settings.lang].reputation.deputy} 🥈[${deputysherrif.user.username}](tg://user?id=${deputysherrif.user.id})🥈`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + const fromUsername = (deputysherrif.user.username || deputysherrif.user.first_name || `no-username-set`); + queue.add(async () => {try{await bot.sendMessage(data.group.groupID, `${langJson[settings.lang].reputation.deputy} 🥈[${fromUsername}](tg://user?id=${deputysherrif.user.id})🥈`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); } catch(e){ console.log(e) } @@ -370,6 +372,8 @@ for(const data of moderationActions.realityQuestionAnsweredFinalized){ return val}catch{}}) if(!userUpdate) continue + + const fromUsername = (userUpdate.user.username || userUpdate.user.first_name || `no-username-set`); let message = "" if (data.status === "GoodSamaritan"){ message = langJson[settings.lang].reputation.samaritan @@ -379,7 +383,7 @@ for(const data of moderationActions.realityQuestionAnsweredFinalized){ message = langJson[settings.lang].reputation.BoyWhoCriedWolf } if(data.status !== "CommunityMember") - queue.add(async () => {try{await bot.sendMessage(data.group.groupID, `${message} [${userUpdate.user.username}](tg://user?id=${userUpdate.user.id})`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(data.group.groupID, `${message} [${fromUsername}](tg://user?id=${userUpdate.user.id})`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); } catch(e){ console.log(e) } From ae4cc3c1663638764ee5dd3761aea7a8bb42f4a8 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Thu, 26 Jan 2023 14:59:50 +0000 Subject: [PATCH 040/111] chore: new docs --- lib/telegram/assets/langNew.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/telegram/assets/langNew.json b/lib/telegram/assets/langNew.json index 2979052..b4e8116 100644 --- a/lib/telegram/assets/langNew.json +++ b/lib/telegram/assets/langNew.json @@ -173,7 +173,7 @@ "already": "Already started." }, "welcome": { - "welcome": "Hi, I'm Susie, a [Kleros Moderate](https://kleros.io/moderate/) bot.\n\nI need permission from an admin to /start.\n\nHow do I help with moderation?\n\n1. I ask \"Did a user break the rules?\" on the crowdsourcing platform [Reality.Eth](https://realityeth.github.io/).\n2. The question is answered with an escalation game using xDai on [Gnosis Chain](https://www.gnosis.io/).\n3. The answer can be disputed in the [Kleros](https://kleros.io/) court.\n\nTo learn more, [DM](https://t.me/KlerosModeratorBot?start=help) me, read my [docs](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie), or ask a question in @SusieSupport." + "welcome": "Hi, I'm Susie, a [Kleros Moderate](https://kleros.io/moderate/) bot.\n\nI need permission from an admin to /start.\n\nHow do I help with moderation?\n\n1. I ask \"Did a user break the rules?\" on the crowdsourcing platform [Reality.Eth](https://realityeth.github.io/).\n2. The question is answered with an escalation game using xDai on [Gnosis Chain](https://www.gnosis.io/).\n3. The answer can be disputed in the [Kleros](https://kleros.io/) court.\n\nTo learn more, [DM](https://t.me/SusieTheKlerosModeratorBot?start=help) me, read my [docs](https://kleros.gitbook.io/docs/products/moderate/susie), or ask a question in @SusieSupport." }, "defaultRules": "https://ipfs.kleros.io/ipfs/Qme3Qbj9rKUNHUe9vj9rqCLnTVUCWKy2YfveQF8HiuWQSu/Kleros%20Moderate%20Community%20Rules.pdf", "index": { @@ -185,7 +185,7 @@ "help": { "DM": "Get Help (DM)", "DM2": "DM me for help : )", - "help": "*Help*\n\nHi! My name is Susie. I'm a [Kleros Moderate](https://kleros.io/moderate) bot, here to help you manage your groups!\n\nI crowdsource moderation using [Reality.eth](https://reality.eth.limo/) and [Kleros](https://kleros.gitbook.io/docs/) on [Gnosis Chain](https://www.gnosis.io/).\n\nModeration is resolved with an escalation game and the outcome can be disptued in the Kleros Court.\n\nHelpful commands:\n - /start: Starts me.\n - /help: Sends this help message.\n\nSelect a feature to learn more. Ask questions in @SusieSupport or read the [docs](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator)." + "help": "*Help*\n\nHi! My name is Susie. I'm a [Kleros Moderate](https://kleros.io/moderate) bot, here to help you manage your groups!\n\nI crowdsource moderation using [Reality.eth](https://reality.eth.limo/) and [Kleros](https://kleros.gitbook.io/docs/) on [Gnosis Chain](https://www.gnosis.io/).\n\nModeration is resolved with an escalation game and the outcome can be disptued in the Kleros Court.\n\nHelpful commands:\n - /start: Starts me.\n - /help: Sends this help message.\n\nSelect a feature to learn more. Ask questions in @SusieSupport or read the [docs](https://kleros.gitbook.io/docs/products/moderate/susie)." , "back": "back", "Greeting1": "👋 *Greeting* 👋\n\nWelcome your members with a greeting informing them of the group rules.\n\nAfter 5 minutes, the previous welcome message or captcha will get deleted\n\n*Admin commands:*\n- `/welcome` : Toggles on/off welcomes messages.\n- `/captcha` : Toggles on/off captcha.", "Language1": "🗣️ *Languages* 🗣️\n\nSusie's replies can be changed to one of the languages below.\n\n- EN (English)\n- ES (Español)\n\nContent moderation requires a nuanced understanding of context and language. Please make sure to set the appropriate language for your community for effective moderation.\n\n*Admin commands*: \n- `/lang`: Set your preferred language.", @@ -292,7 +292,7 @@ "select" : "Seleccione un idioma compatible", "confirm": "Language changed to english.", "rules": "Se aplican por defecto las Directrices de la Comunidad Moderada de Kleros [normas]", - "setrules": "Puedes establecer nuevas reglas con /setrules. Elaborar reglas precisas es un reto, puedes pedirme ayuda (/help)." + "setrules": "Puedes establecer nuevas reglas con /setrules. Elaborar reglas precisas es un reto, puedes pedirme /help" }, "addevidence" : { "allowance": "Se han agotado las pruebas diarias.", @@ -368,13 +368,13 @@ "already": "Ya comenzó." }, "welcome": { - "welcome": "Hola, soy Susie, un bot [Kleros Moderate](https://kleros.io/moderate/). Necesito permiso de un administrador para /start. ¿Cómo puedo ayudar con la moderación? Pregunto '¿Un usuario ha infringido las normas?' en la plataforma de crowdsourcing [Reality.Eth](https://realityeth.github.io/).n2. La pregunta se responde con un juego de escalada usando xDai en [Gnosis Chain](https://www.gnosis.io/).\n3. La respuesta se puede disputar en el tribunal [Kleros](https://kleros.io/).\n\nPara saber más, [DM](https://t.me/KlerosModeratorBot?start=help) mío, lee mis [docs](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie), o haz una pregunta en @SusieSupport." + "welcome": "Hola, soy Susie, un bot [Kleros Moderate](https://kleros.io/moderate/). Necesito permiso de un administrador para /start. ¿Cómo puedo ayudar con la moderación? Pregunto '¿Un usuario ha infringido las normas?' en la plataforma de crowdsourcing [Reality.Eth](https://realityeth.github.io/).n2. La pregunta se responde con un juego de escalada usando xDai en [Gnosis Chain](https://www.gnosis.io/).\n3. La respuesta se puede disputar en el tribunal [Kleros](https://kleros.io/).\n\nPara saber más, [DM](https://t.me/SusieTheKlerosModeratorBot?start=help) mío, lee mis [docs](https://kleros.gitbook.io/docs/products/moderate/susie), o haz una pregunta en @SusieSupport." }, "defaultRules": "https://ipfs.kleros.io/ipfs/QmSHAjfD1MYPtyopFoXcUQ5Ny3sfs5re1yz3h3TZ5qGDsp/Kleros%20Moderate%20Normas%20comunitarias.pdf", "help": { "DM": "Obtener ayuda (DM)", "DM2": "DM de ayuda : )", - "help": "*Ayuda*\n\n¡Hola! Me llamo Susie. Soy un bot [Kleros Moderate](https://kleros.io/moderate), ¡aquí para ayudarte a gestionar tus grupos!\n\n¡Modero en grupo usando [Reality.eth](https://reality.eth.limo/) y [Kleros](https://kleros.gitbook.io/docs/) en [Gnosis Chain](https://www.gnosis.io/).\n\nLa moderación se resuelve con un juego de escalada y el resultado se puede disputar en el Tribunal Kleros.\n\nComandos útiles:\n - /start: Me inicia.\n - /help: Envía este mensaje de ayuda.\n\nSelecciona una función para saber más. Haz preguntas en @SusieSupport o lee los [docs](https://shotaro.gitbook.io/kleros-moderate/products/moderate/susie-or-kleros-moderator)." + "help": "*Ayuda*\n\n¡Hola! Me llamo Susie. Soy un bot [Kleros Moderate](https://kleros.io/moderate), ¡aquí para ayudarte a gestionar tus grupos!\n\n¡Modero en grupo usando [Reality.eth](https://reality.eth.limo/) y [Kleros](https://kleros.gitbook.io/docs/) en [Gnosis Chain](https://www.gnosis.io/).\n\nLa moderación se resuelve con un juego de escalada y el resultado se puede disputar en el Tribunal Kleros.\n\nComandos útiles:\n - /start: Me inicia.\n - /help: Envía este mensaje de ayuda.\n\nSelecciona una función para saber más. Haz preguntas en @SusieSupport o lee los [docs](https://kleros.gitbook.io/docs/products/moderate/susie)." , "back": "back", "Greeting1": "👋 *Saludos* 👋 Bienvenida a tus miembros con un saludo informándoles de las reglas del grupo. Después de 5 minutos, los mensajes de bienvenida o captcha anteriores se borrarán.\n\n*Comandos de administrador:*\n- `/welcome` : Activa / desactiva los mensajes de bienvenida.\n- `/captcha` : Activa / desactiva las reglas captcha.", "Language1": "🗣️ *Idiomas* 🗣️\n\nLas respuestas de Susie pueden cambiarse a uno de los siguientes idiomas.\n\n- EN (English)\n- ES (Español)\n\nLa moderación de contenidos requiere una comprensión matizada del contexto y del lenguaje. Por favor, asegúrese de establecer el idioma apropiado para su comunidad para una moderación efectiva. \n\n*Comandos de administración*:\n`/lang`: Establezca su idioma preferido.", From 4435f0fe33d59209b72a9e250eb7e5040df14c5a Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Thu, 26 Jan 2023 15:00:13 +0000 Subject: [PATCH 041/111] fix: msg replay --- lib/cron.ts | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/lib/cron.ts b/lib/cron.ts index d89f48a..00e3e35 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -315,23 +315,6 @@ for(const data of moderationActions.realityQuestionAnsweredNotFinalized){ console.log(e) } } - -for(const data of moderationActions.realityQuestionAnsweredFinalized){ - const settings = validate(data.moderationInfo.UserHistory.group.groupID); - // settings[1] language - try{ - //bot.sendMessage(settings[0], `The reality question ${data.id} is finalized with ${data.currentAnswer}`); - //const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; - //bot.sendMessage(settings.channelID, `The [report](${realityURL}) is finalized.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'}); - //bot.sendMessage(process.env.JUSTICE_LEAGUE, `The [report](${realityURL}) is finalized.`, {parse_mode: 'Markdown'}); - // finalize - handleTelegramUpdate(db, bot, settings, data.moderationInfo, timestampNew, data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001", true, false); - } catch(e){ - console.log(e) - } -} - - // promise queue example for(const data of moderationActions.sheriffs){ const settings = validate(data.group.groupID); @@ -550,9 +533,9 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, } else{ const i = calculateHistory.findIndex(e => e.question_id === moderationInfo.id); if (i > -1) { - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messsageBackup})) violated the [rules](${moderationInfo.rulesUrl}) for the ${calcPenaltyPhrase(settings, ban_level_current, settings.enforcement, finalize)}.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}) for the ${calcPenaltyPhrase(settings, ban_level_current, settings.enforcement, finalize)}.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true})}catch{}}); } else - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messsageBackup})) violated the [rules](${moderationInfo.rulesUrl}). The conduct occured before *${moderationInfo.UserHistory.user.username}*'s latest confirmed report, so the user is recommended to get a second chance --- they should have been penalized already.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}). The conduct occured before *${moderationInfo.UserHistory.user.username}*'s latest confirmed report, so the user is recommended to get a second chance --- they should have been penalized already.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true})}catch{}}); } } else if (ban_level_current < ban_level_history){ let liftbans = true; @@ -649,7 +632,7 @@ return `{ timestampLastUpdated ${moderationInfo} } - sheriffs: jannies(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastUpdatedSheriff_gt: ${timestampLastUpdated}, group_: {botAddress: "${botaddress}"}}) { + sheriffs: jannies(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastUpdatedSheriff_gt: ${timestampLastUpdated}, timestampLastUpdatedSheriff_lt: ${timestampNew}, group_: {botAddress: "${botaddress}"}}) { id group{ groupID @@ -660,7 +643,7 @@ return `{ } } } - deputySheriffs: jannies(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastUpdatedDeputySheriff_gt: ${timestampLastUpdated}, group_: {botAddress: "${botaddress}"}}) { + deputySheriffs: jannies(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastUpdatedDeputySheriff_gt: ${timestampLastUpdated}, timestampLastUpdatedDeputySheriff_lt: ${timestampNew}, group_: {botAddress: "${botaddress}"}}) { id group{ groupID From fffa5b6a333966f97d2eeee2b89aa7e3b666164e Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Thu, 26 Jan 2023 15:30:19 +0000 Subject: [PATCH 042/111] chore: msg format --- lib/cron.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/cron.ts b/lib/cron.ts index 00e3e35..921193f 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -457,22 +457,22 @@ const calcPenalty = (ban_level: number, timestamp_finalized: number): number => return timestamp_finalized + 31536000 } -const calcPenaltyPhrase = (settings: groupSettings, ban_level: number, enforcement: boolean, finalize: boolean): string => { +const calcPenaltyPhrase = (settings: groupSettings, ban_level: number, enforcement: boolean, finalize: boolean, realityURL: string): string => { if (settings.lang === 'es'){ if(ban_level == 1) - return finalize? enforcement? 'primera vez y está sujeta a un baneo de 1 día' : 'primera vez y se recomienda una prohibición de 1 día' : enforcement? 'primera vez y se silencia durante 1 día durante el resto del periodo del informe': 'primera vez y se le recomienda un silencio de 1 día por el resto del período del informe' + return finalize? enforcement? 'primera vez y está sujeta a un baneo de 1 día' : 'primera vez y se recomienda una prohibición de 1 día' : enforcement? `primera vez y se silencia durante 1 día durante el resto del periodo del [informe]${realityURL}`: `primera vez y se le recomienda un silencio de 1 día por el resto del período del [informe]${realityURL}` else if (ban_level == 2) - return finalize? enforcement? 'segunda vez y está sujeto a una prohibición de 1 semana' : 'segunda vez y se recomienda una prohibición de 1 semana': enforcement? 'segunda vez y se silencia durante 1 día durante el resto del periodo del informe': 'segunda vez y se le recomienda un silencio de 1 día para el resto del periodo del informe' + return finalize? enforcement? 'segunda vez y está sujeto a una prohibición de 1 semana' : 'segunda vez y se recomienda una prohibición de 1 semana': enforcement? `segunda vez y se silencia durante 1 día durante el resto del periodo del [informe]${realityURL}`: `segunda vez y se le recomienda un silencio de 1 día para el resto del periodo del [informe]${realityURL}` else - return finalize? enforcement? 'tercera vez y está sujeto a una prohibición de 1 mes' : 'tercera vez y se recomienda una prohibición de 1 mes' : enforcement? 'trecera vez y se silencia durante 1 día durante el resto del periodo del informe': 'tercera vez y se le recomienda un silencio de 1 día por el resto del período del informe' + return finalize? enforcement? 'tercera vez y está sujeto a una prohibición de 1 mes' : 'tercera vez y se recomienda una prohibición de 1 mes' : enforcement? `trecera vez y se silencia durante 1 día durante el resto del periodo del [informe]${realityURL}`: `tercera vez y se le recomienda un silencio de 1 día por el resto del período del [informe]${realityURL}` } else { if(ban_level == 1) - return finalize? enforcement? 'first time and is subject to a 1 day ban' : 'first time and is recommended a 1 day ban' : enforcement? 'first time and is muted for 1 day during the remainder of the report period': 'first time and is recommended a 1 day mute for the remainder of the report period' + return finalize? enforcement? 'first time and is subject to a 1 day ban' : 'first time and is recommended a 1 day ban' : enforcement? `first time and is muted for 1 day during the remainder of the [report]${realityURL}`: `first time and is recommended a 1 day mute for the remainder of the [report]${realityURL}` else if (ban_level == 2) - return finalize? enforcement? 'second time and is subject to a 1 week ban' : 'second time and is recommended a 1 week ban': enforcement? 'second time and is muted for 1 day during the remainder of the report period': 'second time and is recommended a 1 day mute for the remainder of the report period' + return finalize? enforcement? 'second time and is subject to a 1 week ban' : 'second time and is recommended a 1 week ban': enforcement? `second time and is muted for 1 day during the remainder of the [report]${realityURL}`: `second time and is recommended a 1 day mute for the remainder of the [report]${realityURL}` else - return finalize? enforcement? 'third time and is subject to a 1 month ban' : 'third time and is recommended a 1 month ban' : enforcement? 'third time and is muted for 1 day during the remainder of the report period': 'third time and is recommended a 1 day mute for the remainder of the report period' + return finalize? enforcement? 'third time and is subject to a 1 month ban' : 'third time and is recommended a 1 month ban' : enforcement? `third time and is muted for 1 day during the remainder of the [report]${realityURL}`: `third time and is recommended a 1 day mute for the remainder of the [report]${realityURL}` } } @@ -528,12 +528,13 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, } } } - const msg_enforcement = settings.lang === 'es'? `la conducta de *${moderationInfo.UserHistory.user.username}* por este [mensaje](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) mensaje viola las [reglas](${moderationInfo.rulesUrl}) por ${calcPenaltyPhrase(settings, ban_level_current, settings.enforcement, finalize)}.` : `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}) for the ${calcPenaltyPhrase(settings, ban_level_current, settings.enforcement, finalize)}.` + const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${moderationInfo.id}`; + const msg_enforcement = settings.lang === 'es'? `la conducta de *${moderationInfo.UserHistory.user.username}* por este [mensaje](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) mensaje viola las [reglas](${moderationInfo.rulesUrl}) por ${calcPenaltyPhrase(settings, ban_level_current, settings.enforcement, finalize, realityURL)}.` : `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}) for the ${calcPenaltyPhrase(settings, ban_level_current, settings.enforcement, finalize, realityURL)}.` queue.add(async () => {try{await bot.sendMessage(settings.channelID, msg_enforcement, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); } else{ const i = calculateHistory.findIndex(e => e.question_id === moderationInfo.id); if (i > -1) { - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}) for the ${calcPenaltyPhrase(settings, ban_level_current, settings.enforcement, finalize)}.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}) for the ${calcPenaltyPhrase(settings, ban_level_current, settings.enforcement, finalize, realityURL)}.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true})}catch{}}); } else queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}). The conduct occured before *${moderationInfo.UserHistory.user.username}*'s latest confirmed report, so the user is recommended to get a second chance --- they should have been penalized already.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true})}catch{}}); } From 58a8d16dcb94281f2074148c30631e59fc66d2cd Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Thu, 26 Jan 2023 15:32:56 +0000 Subject: [PATCH 043/111] fix: msg format --- lib/cron.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/cron.ts b/lib/cron.ts index 921193f..67c888f 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -461,18 +461,18 @@ const calcPenaltyPhrase = (settings: groupSettings, ban_level: number, enforceme if (settings.lang === 'es'){ if(ban_level == 1) - return finalize? enforcement? 'primera vez y está sujeta a un baneo de 1 día' : 'primera vez y se recomienda una prohibición de 1 día' : enforcement? `primera vez y se silencia durante 1 día durante el resto del periodo del [informe]${realityURL}`: `primera vez y se le recomienda un silencio de 1 día por el resto del período del [informe]${realityURL}` + return finalize? enforcement? 'primera vez y está sujeta a un baneo de 1 día' : 'primera vez y se recomienda una prohibición de 1 día' : enforcement? `primera vez y se silencia durante 1 día durante el resto del periodo del [informe](${realityURL})`: `primera vez y se le recomienda un silencio de 1 día por el resto del período del [informe](${realityURL})` else if (ban_level == 2) - return finalize? enforcement? 'segunda vez y está sujeto a una prohibición de 1 semana' : 'segunda vez y se recomienda una prohibición de 1 semana': enforcement? `segunda vez y se silencia durante 1 día durante el resto del periodo del [informe]${realityURL}`: `segunda vez y se le recomienda un silencio de 1 día para el resto del periodo del [informe]${realityURL}` + return finalize? enforcement? 'segunda vez y está sujeto a una prohibición de 1 semana' : 'segunda vez y se recomienda una prohibición de 1 semana': enforcement? `segunda vez y se silencia durante 1 día durante el resto del periodo del [informe](${realityURL})`: `segunda vez y se le recomienda un silencio de 1 día para el resto del periodo del [informe](${realityURL})` else - return finalize? enforcement? 'tercera vez y está sujeto a una prohibición de 1 mes' : 'tercera vez y se recomienda una prohibición de 1 mes' : enforcement? `trecera vez y se silencia durante 1 día durante el resto del periodo del [informe]${realityURL}`: `tercera vez y se le recomienda un silencio de 1 día por el resto del período del [informe]${realityURL}` + return finalize? enforcement? 'tercera vez y está sujeto a una prohibición de 1 mes' : 'tercera vez y se recomienda una prohibición de 1 mes' : enforcement? `trecera vez y se silencia durante 1 día durante el resto del periodo del [informe](${realityURL})`: `tercera vez y se le recomienda un silencio de 1 día por el resto del período del [informe](${realityURL})` } else { if(ban_level == 1) - return finalize? enforcement? 'first time and is subject to a 1 day ban' : 'first time and is recommended a 1 day ban' : enforcement? `first time and is muted for 1 day during the remainder of the [report]${realityURL}`: `first time and is recommended a 1 day mute for the remainder of the [report]${realityURL}` + return finalize? enforcement? 'first time and is subject to a 1 day ban' : 'first time and is recommended a 1 day ban' : enforcement? `first time and is muted for 1 day during the remainder of the [report](${realityURL})`: `first time and is recommended a 1 day mute for the remainder of the [report](${realityURL})` else if (ban_level == 2) - return finalize? enforcement? 'second time and is subject to a 1 week ban' : 'second time and is recommended a 1 week ban': enforcement? `second time and is muted for 1 day during the remainder of the [report]${realityURL}`: `second time and is recommended a 1 day mute for the remainder of the [report]${realityURL}` + return finalize? enforcement? 'second time and is subject to a 1 week ban' : 'second time and is recommended a 1 week ban': enforcement? `second time and is muted for 1 day during the remainder of the [report](${realityURL})`: `second time and is recommended a 1 day mute for the remainder of the [report](${realityURL})` else - return finalize? enforcement? 'third time and is subject to a 1 month ban' : 'third time and is recommended a 1 month ban' : enforcement? `third time and is muted for 1 day during the remainder of the [report]${realityURL}`: `third time and is recommended a 1 day mute for the remainder of the [report]${realityURL}` + return finalize? enforcement? 'third time and is subject to a 1 month ban' : 'third time and is recommended a 1 month ban' : enforcement? `third time and is muted for 1 day during the remainder of the [report](${realityURL})`: `third time and is recommended a 1 day mute for the remainder of the [report](${realityURL})` } } @@ -506,6 +506,7 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, const ban_level_current = calculateHistory.length console.log(calculateHistory) const groups = settings.federation_id? getGroupsInAndFollowingFederation(db,'telegram',settings.federation_id) : [{group_id: moderationInfo.UserHistory.group.groupID}] + const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${moderationInfo.id}`; if (restrict){ // TODO federation subscriptions @@ -528,7 +529,6 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, } } } - const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${moderationInfo.id}`; const msg_enforcement = settings.lang === 'es'? `la conducta de *${moderationInfo.UserHistory.user.username}* por este [mensaje](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) mensaje viola las [reglas](${moderationInfo.rulesUrl}) por ${calcPenaltyPhrase(settings, ban_level_current, settings.enforcement, finalize, realityURL)}.` : `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}) for the ${calcPenaltyPhrase(settings, ban_level_current, settings.enforcement, finalize, realityURL)}.` queue.add(async () => {try{await bot.sendMessage(settings.channelID, msg_enforcement, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); } else{ From 21795b5c94c6552775de5c5038a698ae6bd6f8cd Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Thu, 26 Jan 2023 16:39:22 +0000 Subject: [PATCH 044/111] fix: avoid duplicate msgs --- lib/cron.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/cron.ts b/lib/cron.ts index 67c888f..82054ff 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -42,7 +42,7 @@ const exit = async () => { let currentBlock = await web3.eth.getBlockNumber() if (!history) history = { - last_timestamp: currentTime -20, + last_timestamp: currentTime -30, last_block: currentBlock } @@ -52,11 +52,11 @@ const exit = async () => { //history.last_timestamp = 1674496352 //history.last_block = 8362931 - let timestampNew = Math.floor(Date.now()/1000)-20; + let timestampNew: number; let timestampLastUpdated = history.last_timestamp let realitio_bot_checkpoint = Math.floor(timestampNew / 1800) - 1 while (1){ - timestampNew = Math.floor(Date.now()/1000)-20 + timestampNew = Math.floor(Date.now()/1000)-30 const questionDelay = await update(timestampNew, timestampLastUpdated, botaddress); if(questionDelay) delayCheck(questionDelay, 0,timestampNew,timestampLastUpdated,botaddress) @@ -75,7 +75,7 @@ const exit = async () => { } timestampLastUpdated = timestampNew setCron(db, history.last_block,timestampNew) - await delay(20000) + await delay(30000) } })() @@ -559,7 +559,7 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, queue.add(async () => {try{await bot.restrictChatMember(moderationInfo.UserHistory.group.groupID, moderationInfo.UserHistory.user.userID, permissions)}catch{}}); } } - const msg_update = settings.lang === "en" ? `*${moderationInfo.UserHistory.user.username}* has no other active reports. All bans should be lifted.` : `*${moderationInfo.UserHistory.user.username}* no tiene otros informes activos. Todas las prohibiciones deben ser levantadas.` + const msg_update = settings.lang === "en" ? `*${moderationInfo.UserHistory.user.username}*'s has no other active reports. All bans should be lifted.` : `*${moderationInfo.UserHistory.user.username}* no tiene otros informes activos. Todas las prohibiciones deben ser levantadas.` queue.add(async () => {try{await bot.sendMessage(settings.channelID, msg_update,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); } else { const msg_update = settings.lang === "en" ? `*${moderationInfo.UserHistory.user.username}* has other active reports and should remain restricted.` : `*${moderationInfo.UserHistory.user.username}* tiene otros informes activos y debe permanecer restringido.` @@ -592,26 +592,26 @@ const getQuery = (lastPageUpdated: number, timestampLastUpdated: number, botaddr ${moderationInfoContent} }`; return `{ - disputesFinal: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastUpdated_gt: ${timestampLastUpdated}, finalRuling_not: null, moderationInfo_: {askedBy: "${botaddress}"}}) { + disputesFinal: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastUpdated_gt: ${timestampLastUpdated}, timestampLastUpdated_lt: ${timestampNew}, finalRuling_not: null, moderationInfo_: {askedBy: "${botaddress}"}}) { id finalRuling ${moderationInfo} } - disputesAppealPossible: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastAppealPossible_gt: ${timestampLastUpdated}, finalRuling: null, moderationInfo_: {askedBy: "${botaddress}"}}) { + disputesAppealPossible: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastAppealPossible_gt: ${timestampLastUpdated}, timestampLastAppealPossible_lt: ${timestampNew}, finalRuling: null, moderationInfo_: {askedBy: "${botaddress}"}}) { id currentRuling ${moderationInfo} } - disputesAppeal: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastAppeal_gt: ${timestampLastUpdated}, finalRuling: null, moderationInfo_: {askedBy: "${botaddress}"}}) { + disputesAppeal: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastAppeal_gt: ${timestampLastUpdated}, timestampLastAppeal_lt: ${timestampNew}, finalRuling: null, moderationInfo_: {askedBy: "${botaddress}"}}) { id currentRuling ${moderationInfo} } - disputesCreated: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastUpdated_gt: ${timestampLastUpdated}, finalRuling: null, currentRuling: null, rulingFunded: null, moderationInfo_: {askedBy: "${botaddress}"}}) { + disputesCreated: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastUpdated_gt: ${timestampLastUpdated}, timestampLastUpdated_lt: ${timestampNew}, finalRuling: null, currentRuling: null, rulingFunded: null, moderationInfo_: {askedBy: "${botaddress}"}}) { id ${moderationInfo} } - disputesAppealFunded: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastAppealPossible_gt: ${timestampLastUpdated}, rulingFunded_not: null, moderationInfo_: {askedBy: "${botaddress}"}}) { + disputesAppealFunded: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastAppealPossible_gt: ${timestampLastUpdated}, , timestampLastAppealPossible_lt: ${timestampNew}, rulingFunded_not: null, moderationInfo_: {askedBy: "${botaddress}"}}) { id rulingFunded currentRuling @@ -655,7 +655,7 @@ return `{ } } } - ranks: userHistories(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampStatusUpdated_gt: ${timestampLastUpdated}, group_: {botAddress: "${botaddress}", platform: "Telegram"}}) { + ranks: userHistories(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampStatusUpdated_gt: ${timestampLastUpdated}, timestampStatusUpdated_lt: ${timestampNew}, group_: {botAddress: "${botaddress}", platform: "Telegram"}}) { status user{ userID From e32fda18d974a52b88d7c3b486983f072cbe8343 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Thu, 26 Jan 2023 17:10:17 +0000 Subject: [PATCH 045/111] chore: 3 min delay --- lib/cron.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/cron.ts b/lib/cron.ts index 82054ff..37e91c8 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -385,8 +385,8 @@ const delay = (delayInms) => { const delayCheck = async (realityQuestions: string, lastPageUpdated: number, timestampNew: number, timestampLastUpdated: number, botaddress: string) => { const queryModeration = getQueryDelay(lastPageUpdated, realityQuestions, timestampLastUpdated, botaddress, timestampNew) - // 5 min delay - await delay(300000) + // 3 min delay + await delay(180000) //console.log(queryModeration); //console.log('graphtime'); //console.log(queryModeration) From e0c4f85d33f7f5c84b9ea83d6a2589729f47410f Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Thu, 26 Jan 2023 19:18:42 +0000 Subject: [PATCH 046/111] chore: typo --- lib/telegram/assets/langNew.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/telegram/assets/langNew.json b/lib/telegram/assets/langNew.json index b4e8116..c19985c 100644 --- a/lib/telegram/assets/langNew.json +++ b/lib/telegram/assets/langNew.json @@ -260,7 +260,7 @@ "getAccount": "Bot dirección", "info": { "evidence": "¿De qué usuario trata el informe?", - "noevidence": "No hay informes a los que añadir pruebas en tu grupo.", + "noevidence": "No hay informes a los que añadir evidencia en tu grupo.", "get": "Obtener información del informe", "DM": "DM mí para información de informe : )", "report1": "rompió las reglas al menos", @@ -295,10 +295,10 @@ "setrules": "Puedes establecer nuevas reglas con /setrules. Elaborar reglas precisas es un reto, puedes pedirme /help" }, "addevidence" : { - "allowance": "Se han agotado las pruebas diarias.", - "ID": "pruebas ID sin especificar.", - "submitted": "Pruebas [cargadas]", - "explain": "Pruebas presentadas con explicaciones", + "allowance": "Se han agotado las evidencia diarias.", + "ID": "evidencia ID sin especificar.", + "submitted": "Evidencia [cargadas]", + "explain": "Evidencia presentadas con explicaciones", "errorId": "El ID no está activo o no existe.", "Chat": "Charla", "Author": "Autor", @@ -311,9 +311,9 @@ "Poll": "Encuesta", "Question": "Pregunta", "Option": "Opción", - "Evidence": "Pruebas", + "Evidence": "Evidencia", "MessageSent": "Mensaje enviado", - "Desc1": "Envío de pruebas automatizado por el bot Kleros Moderate. Por favor, compruebe la autenticidad. El archivo adjunto es un registro de copia de seguridad de un mensaje enviado en el chat." + "Desc1": "Envío de evidencia automatizado por el bot Kleros Moderate. Por favor, compruebe la autenticidad. El archivo adjunto es un registro de copia de seguridad de un mensaje enviado en el chat." }, "multilang": { "en": "Grupo inglés conectado", @@ -384,7 +384,7 @@ "Rules1": "📄 *Reglas* 📄\n\nTodos los grupos empiezan con [reglas por defecto](https://ipfs.kleros.io/ipfs/QmSHAjfD1MYPtyopFoXcUQ5Ny3sfs5re1yz3h3TZ5qGDsp/Kleros%20Moderate%20Normas%20comunitarias.pdf). \n\n***Consejos para la redacción de reglas***:\n\n -Enuncie la cultura del grupo en un preámbulo.\n -Numere cada regla.\nSea específico.\n\n*Comandos de usuario*:\n-`/rules`: Devuelve las reglas.\n*Comandos de administrador*:\n- `/setrules` o : Establece las reglas a la url o mensaje.", "Court1": "⚖️ *Corte* ⚖️\n\nLas preguntas de moderación las resuelve el [Kleros Court](https://kleros.gitbook.io/docs/) con un jurado de moderadores. Si el jurado cometió un error, el caso puede ser apelado, atrayendo a un grupo más grande de miembros del jurado y proporcionando la oportunidad de proporcionar más contexto, análisis y argumentos.\n\nSi desea tener la oportunidad de servir como miembro del jurado, obtenga PNK ([Gnosis Chain](https://swapr.eth.link/#/swap?chainId=100) o [Mainnet](https://app.uniswap.org/#/swap?outputCurrency=0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d&inputCurrency=ETH)) y [stake](https://court.kleros.io/) en el tribunal de Kleros.\n\nPara discutir el fondo de una disputa, consulte @klerosjuror.", "Lawyer1": "🧑‍⚖️ *Busque un abogado* 🧑‍⚖️ \n\nLas disputas sobre informes pueden ser complicadas.\n\nSi necesita ayuda para defender su caso ante el tribunal kleros, considere pedir ayuda a un [abogado] kleros(https://t.me/+9fvGGkGfSZ1hZDBk).", - "Privacy1": "🕵️ *Privacidad* 🕵️\n\nPara proporcionar contexto, los usuarios pueden solicitar a Susie que guarde mensajes para presentarlos como pruebas en su nombre. Susie gestiona la moderación de grupos privados y públicos de forma diferente,\n\n- *** Grupos Privados ***: Los moderadores dependen únicamente de las pruebas presentadas\n\n- *** Grupos Públicos ***: Los moderadores tienen acceso a todo el historial del chat público.", + "Privacy1": "🕵️ *Privacidad* 🕵️\n\nPara proporcionar contexto, los usuarios pueden solicitar a Susie que guarde mensajes para presentarlos como evidencia en su nombre. Susie gestiona la moderación de grupos privados y públicos de forma diferente,\n\n- *** Grupos Privados ***: Los moderadores dependen únicamente de las evidencia presentadas\n\n- *** Grupos Públicos ***: Los moderadores tienen acceso a todo el historial del chat público.", "Notifications1": "🔔 *Notificaciones* 🔔\n\nLas notificaciones pueden enviarse a un canal independiente para no saturar el grupo principal.\n\nCómo habilitar canales de notificación:\n\n1. Crea un canal\n2. Añade a Susie\n3. Susie enviará un ID de canal\n4. Utiliza ese ID de canal para establecer notificaciones con /setchannel en el grupo original\n\n*Comandos de usuario*:\n- `/notificaciones`: Devuelve el canal de notificaciones actual\n*Comandos de administrador*:\n- `/setchannel` : Establece el canal de notificaciones en el id de canal especificado\n- `/setfedchannel` : Establece el canal de notificaciones para su federación en el id de canal especificado", "Federations1": "🌐 *Federaciones*\n\nModerar un solo grupo es difícil, ¿pero gestionar varios lo es aún más? ¿Tienes que bloquear manualmente a los spammers en todos tus grupos? Con las federaciones, Susie puede aplicar una prohibición a un usuario en todos los grupos federados.\n\n*Comandos de usuario*:\n- `/fedinfo`: Devuelve la federación actual: Crea una federación- `/joinfed`: Une el grupo actual a una federación", "Gnosis1": "⛓️ *Gnosis Chain* ⛓️\n\nSusie usa [xDAI](https://docs.gnosischain.com/about/tokens/xdai), una moneda estable, en [Gnosis Chain](https://www.gnosis.io/). ¿No sabes lo que eso significa? Significa que Susie utiliza un libro de contabilidad público barato y rápido para coordinar la moderación de forma justa y transparente. \n\n¿No tienes ningún xDAI en Gnosis Chain? No hay problema, hay un (barato, rápido) [puente](https://bridge.connext.network/?receivingChainId=100&receivingAssetId=0x0000000000000000000000000000000000000000) para eso. \n\n¿Qué es crypto? He oído hablar de eso en las noticias, no quiero tener nada que ver con crypto. No hay problema, puedes pedir ayuda a los moderadores independientes en @SusieSupport.\n\n¿No tienes ninguna criptodivisa? No hay problema, hay una conveniente [fiat on-ramp](https://www.mtpelerin.com/buy-xdai) (tarjeta de crédito o transferencia bancaria) para comprar xDAI en Gnosis Chain.\n\n¿Necesitas ayuda para añadir la red Gnosis Chain a tu cartera? No te preocupes, hay una [guía](https://docs.gnosischain.com/tools/wallets/metamask#2-configure) para eso.\n\n¿Necesitas más ayuda? No te preocupes, hay un grupo @SusieSupport para eso.", From a1a51b134675b2fd339d1fb83e910aaba852fd90 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Thu, 26 Jan 2023 23:05:25 +0000 Subject: [PATCH 047/111] chore: msg format --- lib/telegram/assets/langNew.json | 2 +- lib/telegram/commands/report.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/telegram/assets/langNew.json b/lib/telegram/assets/langNew.json index c19985c..a59ac3b 100644 --- a/lib/telegram/assets/langNew.json +++ b/lib/telegram/assets/langNew.json @@ -313,7 +313,7 @@ "Option": "Opción", "Evidence": "Evidencia", "MessageSent": "Mensaje enviado", - "Desc1": "Envío de evidencia automatizado por el bot Kleros Moderate. Por favor, compruebe la autenticidad. El archivo adjunto es un registro de copia de seguridad de un mensaje enviado en el chat." + "Desc1": "Envío de evidencia automatizado por el bot Kleros Moderate. Por favor, compruebe la autenticidad. El archivo adjunto es un mensaje de copia de seguridad de un mensaje enviado en el chat." }, "multilang": { "en": "Grupo inglés conectado", diff --git a/lib/telegram/commands/report.ts b/lib/telegram/commands/report.ts index 3a7a338..a46cd19 100644 --- a/lib/telegram/commands/report.ts +++ b/lib/telegram/commands/report.ts @@ -246,7 +246,7 @@ const reportMsg = async (queue: any, settings: groupSettings, db: any, bot: any, if (settings.lang === "en") queue.add(async () => {try{bot.sendMessage(settings.channelID, `[${fromUsername}](tg://user?id=${reportedUserID})'s conduct due to this [message](${msgLink}) ([backup](${msgBackup})) is reported for breaking the [rules](${rules}).\n\nDid *${fromUsername}* break the rules? The [question](${appealUrl}) can be answered with a minimum bond of 5 DAI. Need assistance answering the question? [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpgnosis) me for help : )\n\nTo save a record, reply to messages you want saved with \`/evidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: settings.thread_id_notifications , parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); else if (settings.lang === "es") - queue.add(async () => {try{bot.sendMessage(settings.channelID, `La conducta de [${fromUsername}](tg://user?id=${reportedUserID}) a este [mensaje](${msgLink}) ([backup](${msgBackup})) es denunciada por infringir las [reglas](${rules}).\n\nHa infringido el usuario *${fromUsername}* las reglas? La [pregunta](${appealUrl}) puede responderse con un bono mínimo de 5 DAI. Necesitas ayuda para responder a la pregunta? [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpgnosis) me para obetener ayuda : )\n\nPara guardar un registro, responda a los mensajes que desee guardar con \`/evidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: settings.thread_id_notifications , parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + queue.add(async () => {try{bot.sendMessage(settings.channelID, `La conducta de [${fromUsername}](tg://user?id=${reportedUserID}) a este [mensaje](${msgLink}) ([backup](${msgBackup})) es denunciada por infringir las [reglas](${rules}).\n\nHa infringido el usuario *${fromUsername}* las reglas? La [pregunta](${appealUrl}) puede responderse con un bono mínimo de 5 DAI. Necesitas ayuda para responder a la pregunta? [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpgnosis) me para obetener ayuda : )\n\nPara guardar un mensaje, responda a los mensajes que desee guardar con \`/evidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: settings.thread_id_notifications , parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); return [appealUrl, evidenceIndex]; } catch (e) { console.log(e); From 8ace133627354ffa14ad7a071683de7e3035d506 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Thu, 26 Jan 2023 23:09:28 +0000 Subject: [PATCH 048/111] chore: msg format --- lib/telegram/assets/langNew.json | 2 +- lib/telegram/commands/report.ts | 2 +- lib/telegram/index.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/telegram/assets/langNew.json b/lib/telegram/assets/langNew.json index c19985c..a59ac3b 100644 --- a/lib/telegram/assets/langNew.json +++ b/lib/telegram/assets/langNew.json @@ -313,7 +313,7 @@ "Option": "Opción", "Evidence": "Evidencia", "MessageSent": "Mensaje enviado", - "Desc1": "Envío de evidencia automatizado por el bot Kleros Moderate. Por favor, compruebe la autenticidad. El archivo adjunto es un registro de copia de seguridad de un mensaje enviado en el chat." + "Desc1": "Envío de evidencia automatizado por el bot Kleros Moderate. Por favor, compruebe la autenticidad. El archivo adjunto es un mensaje de copia de seguridad de un mensaje enviado en el chat." }, "multilang": { "en": "Grupo inglés conectado", diff --git a/lib/telegram/commands/report.ts b/lib/telegram/commands/report.ts index 3a7a338..a46cd19 100644 --- a/lib/telegram/commands/report.ts +++ b/lib/telegram/commands/report.ts @@ -246,7 +246,7 @@ const reportMsg = async (queue: any, settings: groupSettings, db: any, bot: any, if (settings.lang === "en") queue.add(async () => {try{bot.sendMessage(settings.channelID, `[${fromUsername}](tg://user?id=${reportedUserID})'s conduct due to this [message](${msgLink}) ([backup](${msgBackup})) is reported for breaking the [rules](${rules}).\n\nDid *${fromUsername}* break the rules? The [question](${appealUrl}) can be answered with a minimum bond of 5 DAI. Need assistance answering the question? [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpgnosis) me for help : )\n\nTo save a record, reply to messages you want saved with \`/evidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: settings.thread_id_notifications , parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); else if (settings.lang === "es") - queue.add(async () => {try{bot.sendMessage(settings.channelID, `La conducta de [${fromUsername}](tg://user?id=${reportedUserID}) a este [mensaje](${msgLink}) ([backup](${msgBackup})) es denunciada por infringir las [reglas](${rules}).\n\nHa infringido el usuario *${fromUsername}* las reglas? La [pregunta](${appealUrl}) puede responderse con un bono mínimo de 5 DAI. Necesitas ayuda para responder a la pregunta? [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpgnosis) me para obetener ayuda : )\n\nPara guardar un registro, responda a los mensajes que desee guardar con \`/evidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: settings.thread_id_notifications , parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + queue.add(async () => {try{bot.sendMessage(settings.channelID, `La conducta de [${fromUsername}](tg://user?id=${reportedUserID}) a este [mensaje](${msgLink}) ([backup](${msgBackup})) es denunciada por infringir las [reglas](${rules}).\n\nHa infringido el usuario *${fromUsername}* las reglas? La [pregunta](${appealUrl}) puede responderse con un bono mínimo de 5 DAI. Necesitas ayuda para responder a la pregunta? [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpgnosis) me para obetener ayuda : )\n\nPara guardar un mensaje, responda a los mensajes que desee guardar con \`/evidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: settings.thread_id_notifications , parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); return [appealUrl, evidenceIndex]; } catch (e) { console.log(e); diff --git a/lib/telegram/index.ts b/lib/telegram/index.ts index d485d37..11a0955 100644 --- a/lib/telegram/index.ts +++ b/lib/telegram/index.ts @@ -250,7 +250,7 @@ bot.on('callback_query', async function onCallbackQuery(callbackQuery: TelegramB var reportMessage: string = `To add evidence, reply to the message you want saved in the original chat with the evidence index.\n\n` reports.forEach( (report) => { const MsgLink = 'https://t.me/c/' + calldata[1].substring(4) + '/' + report.msg_id; - reportMessage += `- [Message](${MsgLink}) ([${langJson[settings.lang].socialConsensus.consensus5}](${report.msgBackup})) [${langJson[settings.lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), \`/addevidence ${report.evidenceIndex}\` \n`; + reportMessage += `- [Message](${MsgLink}) ([${langJson[settings.lang].socialConsensus.consensus5}](${report.msgBackup})) [${langJson[settings.lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), \`/evidence ${report.evidenceIndex}\` \n`; }); reportMessage +='\n eg. \`/evidence\` 1 This message breaks the rules because xyz.' From 0953d35b37716bd081ea7134712b9ad18ef98250 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Fri, 27 Jan 2023 10:56:14 +0000 Subject: [PATCH 049/111] fix: answer dispute edge case --- lib/cron.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/cron.ts b/lib/cron.ts index 37e91c8..4a3668e 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -397,6 +397,9 @@ const delayCheck = async (realityQuestions: string, lastPageUpdated: number, tim for(const data of moderationActionsDelay.realityQuestionAnsweredNotFinalizedDelayed){ //console.log(data.moderationInfo.UserHistory.group) + if (!data.moderationInfo.dispute.id || data.moderationInfo.dispute.id === "null" ) + continue; + const settings = validate(data.moderationInfo.UserHistory.group.groupID); // settings[1] language try{ @@ -576,6 +579,9 @@ message messageBackup moderationType rulesUrl +dispute{ + id + } UserHistory{ countBrokeRulesArbitrated group { From 59adb50ad7bac96bcfa66639dbfb7f134b820ce6 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Fri, 27 Jan 2023 10:58:36 +0000 Subject: [PATCH 050/111] chore: msg format --- lib/telegram/commands/socialConsensus.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/telegram/commands/socialConsensus.ts b/lib/telegram/commands/socialConsensus.ts index 8622400..e3923aa 100644 --- a/lib/telegram/commands/socialConsensus.ts +++ b/lib/telegram/commands/socialConsensus.ts @@ -61,7 +61,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: Teleg const fromUsername = user.username || user.first_name || `no-username-set`; const [appealURL, evidenceIndex] = await reportMsg(queue, settings, db, bot, msg, fromUsername, String(calldata[1]), msg.entities[1].url, String(calldata[2]), msg.entities[3].url, calldata[4],calldata[3],batchedSend); queue.add(async () => {try{await bot.deleteMessage(msg.chat.id, msg.message_id)}catch{}}) - queue.add(async () => {try{await bot.sendMessage(msg.chat.id, settings.lang === "en"? `User [reported](${appealURL}). Add evidence with \`/evidence ${evidenceIndex}\`` : `Usuario [reportado](${appealURL}). Añadir pruebas con \`/evidence ${evidenceIndex}\``,{disable_web_page_preview: true, parse_mode: "Markdown"})}catch{}}) + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, settings.lang === "en"? `User [reported](${appealURL}). Add evidence with \`/evidence ${evidenceIndex}\`` : `Usuario [reportado](${appealURL}). Añadir evidencia con \`/evidence ${evidenceIndex}\``,{disable_web_page_preview: true, parse_mode: "Markdown"})}catch{}}) } else{ queue.add(async () => {try{await bot.editMessageReplyMarkup(markdown, opts)}catch{}}) } From e27cd49c907bfa65f77f1d7b70d0c9879a307bee Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Fri, 27 Jan 2023 11:05:11 +0000 Subject: [PATCH 051/111] fix: typo --- lib/telegram/commands/addEvidence.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/telegram/commands/addEvidence.ts b/lib/telegram/commands/addEvidence.ts index f7199f7..bae87c2 100644 --- a/lib/telegram/commands/addEvidence.ts +++ b/lib/telegram/commands/addEvidence.ts @@ -19,7 +19,7 @@ const contract_en = new web3.eth.Contract( const contract_es = new web3.eth.Contract( _contract, - process.env.REALITIO_ARBITRATOR_EN + process.env.REALITIO_ARBITRATOR_ES ) var botAddress: string; const NodeCache = require( "node-cache" ); From fcc8cff6a930fcefad9452fcd4599e62505e1180 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Fri, 27 Jan 2023 15:23:41 +0000 Subject: [PATCH 052/111] fix: simplfy query --- lib/cron.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/cron.ts b/lib/cron.ts index 4a3668e..7980a67 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -397,8 +397,6 @@ const delayCheck = async (realityQuestions: string, lastPageUpdated: number, tim for(const data of moderationActionsDelay.realityQuestionAnsweredNotFinalizedDelayed){ //console.log(data.moderationInfo.UserHistory.group) - if (!data.moderationInfo.dispute.id || data.moderationInfo.dispute.id === "null" ) - continue; const settings = validate(data.moderationInfo.UserHistory.group.groupID); // settings[1] language @@ -579,9 +577,6 @@ message messageBackup moderationType rulesUrl -dispute{ - id - } UserHistory{ countBrokeRulesArbitrated group { From f7c473caef50a6c51995981327f6b9311dfe349e Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Fri, 27 Jan 2023 15:45:41 +0000 Subject: [PATCH 053/111] fix: msg format --- lib/telegram/assets/langNew.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/telegram/assets/langNew.json b/lib/telegram/assets/langNew.json index a59ac3b..fbd69b1 100644 --- a/lib/telegram/assets/langNew.json +++ b/lib/telegram/assets/langNew.json @@ -313,7 +313,7 @@ "Option": "Opción", "Evidence": "Evidencia", "MessageSent": "Mensaje enviado", - "Desc1": "Envío de evidencia automatizado por el bot Kleros Moderate. Por favor, compruebe la autenticidad. El archivo adjunto es un mensaje de copia de seguridad de un mensaje enviado en el chat." + "Desc1": "Envío de evidencia automatizado por el bot Kleros Moderate. Por favor, compruebe la autenticidad. El archivo adjunto es un mensaje de copia de seguridad de un mensaje enviado en el chat" }, "multilang": { "en": "Grupo inglés conectado", @@ -340,7 +340,7 @@ "anon": "El usuario es anónimo. Pide a los administradores que deshabiliten los administradores anónimos para moderar el comportamiento de los administradores.", "bot": "Los bots no pueden ser denunciados.", "admin": "Los informes de administración están desactivados. Los informes de administración pueden activarse con `/adminreportable`.", - "reported": "El mensaje ya está [notificado]", + "reported": "El mensaje ya está [reportado]", "norules": "No se han encontrado reglas para este mensaje.", "noallowance": "Ha agotado su asignación diaria de informes." }, @@ -368,7 +368,7 @@ "already": "Ya comenzó." }, "welcome": { - "welcome": "Hola, soy Susie, un bot [Kleros Moderate](https://kleros.io/moderate/). Necesito permiso de un administrador para /start. ¿Cómo puedo ayudar con la moderación? Pregunto '¿Un usuario ha infringido las normas?' en la plataforma de crowdsourcing [Reality.Eth](https://realityeth.github.io/).n2. La pregunta se responde con un juego de escalada usando xDai en [Gnosis Chain](https://www.gnosis.io/).\n3. La respuesta se puede disputar en el tribunal [Kleros](https://kleros.io/).\n\nPara saber más, [DM](https://t.me/SusieTheKlerosModeratorBot?start=help) mío, lee mis [docs](https://kleros.gitbook.io/docs/products/moderate/susie), o haz una pregunta en @SusieSupport." + "welcome": "Hola, soy Susie, un bot [Kleros Moderate](https://kleros.io/moderate/). Necesito permiso de un administrador para /start. ¿Cómo puedo ayudar con la moderación?\n\n 1. Pregunto\n\n'¿Un usuario ha infringido las normas?'n\n\nen la plataforma de crowdsourcing [Reality.Eth](https://realityeth.github.io/).\n2. La pregunta se responde con un juego de escalada usando xDai en [Gnosis Chain](https://www.gnosis.io/).\n3. La respuesta se puede disputar en el tribunal [Kleros](https://kleros.io/).\n\nPara saber más, [DM](https://t.me/SusieTheKlerosModeratorBot?start=help) mío, lee mis [docs](https://kleros.gitbook.io/docs/products/moderate/susie), o haz una pregunta en @SusieSupport." }, "defaultRules": "https://ipfs.kleros.io/ipfs/QmSHAjfD1MYPtyopFoXcUQ5Ny3sfs5re1yz3h3TZ5qGDsp/Kleros%20Moderate%20Normas%20comunitarias.pdf", "help": { From 16daa03b04ca264028b8645ae54bff2af0f1cc3d Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Fri, 27 Jan 2023 15:48:05 +0000 Subject: [PATCH 054/111] fix: 3 confirmation default --- lib/telegram/commands/socialConsensus.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/telegram/commands/socialConsensus.ts b/lib/telegram/commands/socialConsensus.ts index e3923aa..ba370b8 100644 --- a/lib/telegram/commands/socialConsensus.ts +++ b/lib/telegram/commands/socialConsensus.ts @@ -24,8 +24,8 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: Teleg if (callbackQuery.from.id == Number(calldata[4])) return; - //if (calldata.length > 5 && callbackQuery.from.id == Number(calldata[5])) - // return; + if (calldata.length > 5 && callbackQuery.from.id == Number(calldata[5])) + return; const markdown = { inline_keyboard: [ @@ -55,7 +55,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: Teleg message_thread_id: msg.message_thread_id } try{ - if (newConfirmations > 1){ + if (newConfirmations > 2){ const user = (await queue.add(async () => {try{const val = await bot.getChatMember(String(msg.chat.id), String(calldata[1])) return val}catch{}})).user; const fromUsername = user.username || user.first_name || `no-username-set`; From 2f29bc859587201bd8a1936469e4831babbc69a4 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Fri, 27 Jan 2023 17:11:09 +0000 Subject: [PATCH 055/111] fix: 5 dai default --- lib/bot-core.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bot-core.ts b/lib/bot-core.ts index dfe01ad..08faedb 100644 --- a/lib/bot-core.ts +++ b/lib/bot-core.ts @@ -16,7 +16,7 @@ interface RealityBanResult { } export const reportUser = (batchedSend:any, lang: string, hasBanningPermission: boolean, fromUsername: string, UserID: string, platform: string, group: string, inviteURL: string, groupID: string, rules: string, message: string, messageBackup: string, reportedBy: string, isPrivate: boolean): RealityBanResult => { - const minBond = utils.parseUnits('5', 12); // 5 DAI + const minBond = utils.parseUnits('5', 18); // 5 DAI const delim = '\u241f'; const question = fromUsername+delim+UserID+delim+platform+delim+group+delim+inviteURL+delim+groupID+delim+rules+delim+message+delim+messageBackup+delim+reportedBy ; const template_id = lang === 'es'? Number(process.env.TEMPLATE_ID_ES): Number(process.env.TEMPLATE_ID_EN) From ad8adfd9b339f21a392de8e0ab6256f33e247c97 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Fri, 27 Jan 2023 18:43:06 +0000 Subject: [PATCH 056/111] fix: captcha --- lib/telegram/commands/greeting.ts | 11 +++++++---- lib/telegram/index.ts | 5 +++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/telegram/commands/greeting.ts b/lib/telegram/commands/greeting.ts index 8ddf933..1afdc87 100644 --- a/lib/telegram/commands/greeting.ts +++ b/lib/telegram/commands/greeting.ts @@ -18,6 +18,8 @@ const callback = async (db: any, queue: any, bot: any, settings: groupSettings, if (!myQueue) myQueue = queue + if(!msg.new_chat_member) + return console.log('WELCOME!') const lang_code = msg?.from?.language_code let msg_greeting = '' @@ -35,7 +37,7 @@ const callback = async (db: any, queue: any, bot: any, settings: groupSettings, [ { text: langJson[settings.lang].greeting.captcha, - callback_data: '5|'+String(msg.from.id) + callback_data: '5|'+String(msg.new_chat_member?.id) } ] ] @@ -50,19 +52,20 @@ const callback = async (db: any, queue: any, bot: any, settings: groupSettings, [ { text: langJson[settings.lang].greeting.captcha, - callback_data: '5|'+String(msg.from.id) + callback_data: '5|'+String(msg.new_chat_member?.id) } ] ] } }; - const msg_greeting_full = `${langJson[settings.lang].greeting.greeting0} [${msg.from.first_name}](tg://user?id=${msg.from.id}). ${msg_greeting}${langJson[settings.lang].greeting.greeting1}(${settings.rules}). ${langJson[settings.lang].greeting.greeting2}` + const new_member_name = (msg.new_chat_member?.username || msg.new_chat_member?.first_name || `no-username-set`); + const msg_greeting_full = `${langJson[settings.lang].greeting.greeting0} [${new_member_name}](tg://user?id=${msg.new_chat_member?.id}). ${msg_greeting}${langJson[settings.lang].greeting.greeting1}(${settings.rules}). ${langJson[settings.lang].greeting.greeting2}` console.log('full') console.log(msg_greeting_full) let msg_welcome; if(settings.captcha){ const options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false}; - queue.add(async () => {try{await bot.restrictChatMember(msg.chat.id, msg.from.id, options)}catch (e){console.log(e)}}); + queue.add(async () => {try{await bot.restrictChatMember(msg.chat.id, msg.new_chat_member?.id, options)}catch (e){console.log(e)}}); msg_welcome = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, msg_greeting_full, msg.chat.is_forum? optsThread: opts) return val}catch(e){console.log(e)}}); } else if (settings.greeting_mode){ diff --git a/lib/telegram/index.ts b/lib/telegram/index.ts index 11a0955..e2e6978 100644 --- a/lib/telegram/index.ts +++ b/lib/telegram/index.ts @@ -153,9 +153,10 @@ bot.on("chat_member", async function (msg: any) { */ bot.on("new_chat_members", async function (chatMemberUpdated: any) { - + if(!chatMemberUpdated.new_chat_member?.id) + return; console.log(chatMemberUpdated) - if(!hasStarted(chatMemberUpdated.chat.id)||throttled(chatMemberUpdated.from.id)||chatMemberUpdated.chat.type !== "supergroup") + if(!hasStarted(chatMemberUpdated.chat.id)||throttled(chatMemberUpdated.new_chat_member?.id)||chatMemberUpdated.chat.type !== "supergroup") return; console.log('hmmm1') From eeebfc29825365882054ad5a39e41e5fcd03f12f Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Fri, 27 Jan 2023 19:25:59 +0000 Subject: [PATCH 057/111] fix: no report garbage collection --- lib/telegram/commands/report.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/telegram/commands/report.ts b/lib/telegram/commands/report.ts index a46cd19..b544e95 100644 --- a/lib/telegram/commands/report.ts +++ b/lib/telegram/commands/report.ts @@ -177,7 +177,7 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b if (!reportRequestMsg) return myCache.set([msg.chat.id, msg.reply_to_message.message_id].toString(),`${msg.chat.is_forum? `${msg.message_thread_id}/${reportRequestMsg.message_id}`:''}${reportRequestMsg.message_id}`) ; - myCacheGarbageCollectionSlow.set(reportRequestMsg.message_id, msg.chat.id) + //myCacheGarbageCollectionSlow.set(reportRequestMsg.message_id, msg.chat.id) return; } catch(e){ console.log(e) From edbf44c78323a76e8dd7efbca2e04a12e860326b Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Mon, 6 Feb 2023 09:33:59 +0000 Subject: [PATCH 058/111] feat: removed delay --- lib/cron.ts | 71 +++++++++++++++++++++-------------------------------- 1 file changed, 28 insertions(+), 43 deletions(-) diff --git a/lib/cron.ts b/lib/cron.ts index 7980a67..cc8cc9d 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -37,49 +37,33 @@ const exit = async () => { const privateKey = process.env.PRIVATE_KEY const account = web3.eth.accounts.privateKeyToAccount(privateKey) web3.eth.accounts.wallet.add(account) - console.log(history) const currentTime = Math.floor(Date.now()/1000) let currentBlock = await web3.eth.getBlockNumber() if (!history) history = { - last_timestamp: currentTime -30, + last_timestamp: currentTime, last_block: currentBlock } - console.log(history.last_timestamp) - console.log(history.last_block) - // hardcode values for tests - - //history.last_timestamp = 1674496352 - //history.last_block = 8362931 - let timestampNew: number; + console.log(history.last_timestamp) + console.log(history.last_block) + let timestampLastUpdated = history.last_timestamp - let realitio_bot_checkpoint = Math.floor(timestampNew / 1800) - 1 - while (1){ - timestampNew = Math.floor(Date.now()/1000)-30 - const questionDelay = await update(timestampNew, timestampLastUpdated, botaddress); - if(questionDelay) - delayCheck(questionDelay, 0,timestampNew,timestampLastUpdated,botaddress) - // every 30 min - if (Math.floor(timestampNew / 1800) > realitio_bot_checkpoint){ - realitio_bot_checkpoint = Math.floor(timestampNew / 1800) - const currentBlock = await web3.eth.getBlockNumber() - const updateBlock = Math.min(history.last_block+1000, currentBlock) - try{ - await realitio_bot(web3, history.last_block, updateBlock, process.env.REALITY_ETH_V30, process.env.REALITIO_ARBITRATOR_EN); - await realitio_bot(web3, history.last_block, updateBlock, process.env.REALITY_ETH_V30, process.env.REALITIO_ARBITRATOR_ES); - } catch (e){ - console.log(e) - } - history.last_block = updateBlock - } - timestampLastUpdated = timestampNew - setCron(db, history.last_block,timestampNew) - await delay(30000) + const isUpdated = await update(currentTime, timestampLastUpdated, botaddress); + const updateBlock = Math.min(history.last_block+1000, currentBlock) + try{ + await realitio_bot(web3, history.last_block, updateBlock, process.env.REALITY_ETH_V30, process.env.REALITIO_ARBITRATOR_EN); + await realitio_bot(web3, history.last_block, updateBlock, process.env.REALITY_ETH_V30, process.env.REALITIO_ARBITRATOR_ES); + } catch (e){ + console.log(e) } + history.last_block = updateBlock + if (isUpdated) + timestampLastUpdated = currentTime + setCron(db, history.last_block,timestampLastUpdated) })() -const update = async (timestampNew: number, timestampLastUpdated: number,botaddress: string): Promise =>{ +const update = async (timestampNew: number, timestampLastUpdated: number,botaddress: string): Promise =>{ const reports = {}; let delayQuestions = "" @@ -104,8 +88,9 @@ const update = async (timestampNew: number, timestampLastUpdated: number,botaddr queryModeration ); console.log(JSON.stringify(moderationActions)) - + var isUpdated = false; for (const data of moderationActions.disputesFinal) { + isUpdated = true const settings = validate(data.moderationInfo.UserHistory.group.groupID); // settings[1] language try{ @@ -132,6 +117,7 @@ const update = async (timestampNew: number, timestampLastUpdated: number,botaddr } for (const data of moderationActions.disputesAppealPossible) { + isUpdated = true const settings = validate(data.moderationInfo.UserHistory.group.groupID); const msgLink = data.moderationInfo.message; const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; @@ -168,6 +154,7 @@ const update = async (timestampNew: number, timestampLastUpdated: number,botaddr } for (const data of moderationActions.disputesCreated) { + isUpdated = true const settings = validate(data.moderationInfo.UserHistory.group.groupID); // settings[1] language const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; @@ -209,6 +196,7 @@ const update = async (timestampNew: number, timestampLastUpdated: number,botaddr } for (const data of moderationActions.disputesAppealFunded) { + isUpdated = true const settings = validate(data.moderationInfo.UserHistory.group.groupID); const msgLink = data.moderationInfo.message; const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; @@ -256,6 +244,7 @@ const update = async (timestampNew: number, timestampLastUpdated: number,botaddr */ for(const data of moderationActions.realityQuestionAnsweredFinalized){ + isUpdated = true const settings = validate(data.moderationInfo.UserHistory.group.groupID); // settings[1] language try{ @@ -270,6 +259,7 @@ for(const data of moderationActions.realityQuestionAnsweredFinalized){ } } for(const data of moderationActions.realityQuestionAnsweredNotFinalized){ + isUpdated = true //console.log(data.moderationInfo.UserHistory.group) const settings = validate(data.moderationInfo.UserHistory.group.groupID); // settings[1] language @@ -306,17 +296,14 @@ for(const data of moderationActions.realityQuestionAnsweredNotFinalized){ } } } - if(settings.enforcement){ - delayQuestions += `"${data.id}",` - } else { - handleTelegramUpdate(db, bot, settings, data.moderationInfo, timestampNew, data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001", false, false); - } + handleTelegramUpdate(db, bot, settings, data.moderationInfo, timestampNew, data.currentAnswer === "0x0000000000000000000000000000000000000000000000000000000000000001", false, false); } catch(e){ console.log(e) } } // promise queue example for(const data of moderationActions.sheriffs){ + isUpdated = true const settings = validate(data.group.groupID); // settings[1] language try{ @@ -333,6 +320,7 @@ for(const data of moderationActions.realityQuestionAnsweredNotFinalized){ } for(const data of moderationActions.deputySheriffs){ + isUpdated = true const settings = validate(data.group.groupID); // settings[1] language try{ @@ -348,6 +336,7 @@ for(const data of moderationActions.realityQuestionAnsweredNotFinalized){ } for(const data of moderationActions.ranks){ + isUpdated = true const settings = validate(data.group.groupID); // settings[1] language try{ @@ -372,11 +361,7 @@ for(const data of moderationActions.realityQuestionAnsweredNotFinalized){ } } await queue.onIdle() - - if (delayQuestions.length > 0) - return delayQuestions.substring(0,delayQuestions.length-1); - else - return "" + return isUpdated } const delay = (delayInms) => { From 26b0edb5c39a868826d504d65b74f7a3146b986e Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Mon, 6 Feb 2023 09:34:12 +0000 Subject: [PATCH 059/111] fix: captcha --- lib/telegram/commands/captcha.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/telegram/commands/captcha.ts b/lib/telegram/commands/captcha.ts index 01225c5..8b1eb8d 100644 --- a/lib/telegram/commands/captcha.ts +++ b/lib/telegram/commands/captcha.ts @@ -16,8 +16,8 @@ const callback = async (queue: any, bot: any, settings: groupSettings, msg: any) if (!myQueue) myQueue = queue try{ - - + if (!msg.new_chat_participant?.id) + return; const opts = { parse_mode: 'Markdown', disable_web_page_preview: true, @@ -26,8 +26,8 @@ const callback = async (queue: any, bot: any, settings: groupSettings, msg: any) [ { text: 'I agree to follow the rules.', - callback_data: '5|'+String(msg.from.id) - } + callback_data: '5|'+String(msg.new_chat_participant?.id) + } ] ] } @@ -42,13 +42,13 @@ const callback = async (queue: any, bot: any, settings: groupSettings, msg: any) [ { text: 'I agree to follow the rules.', - callback_data: '5|'+String(msg.from.id) + callback_data: '5|'+String(msg.new_chat_participant?.id) } ] ] } }; - const msg_welcome = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `Welcome [${msg.from.first_name}](tg://user?id=${msg.from.id}) ${langJson[settings.lang].greeting2}(${settings.rules}). ${langJson[settings.lang].greeting3}`, msg.chat.is_forum? optsThread: opts) + const msg_welcome = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `Welcome [${msg.from.first_name}](tg://user?id=${msg.new_chat_participant?.id}) ${langJson[settings.lang].greeting2}(${settings.rules}). ${langJson[settings.lang].greeting3}`, msg.chat.is_forum? optsThread: opts) return val}catch{}}); if(!msg_welcome) return From 09312443267cb24c91c0a4e89bdac3ab3e1903ae Mon Sep 17 00:00:00 2001 From: shotaro Date: Mon, 6 Feb 2023 09:35:22 +0000 Subject: [PATCH 060/111] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cc4c876..5ccbf4d 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ Command | Description | Group Admin | Normal user /setrules | `[by reply/username/id]` Set chat rules from the quoted message | ✅ | ❌ /setrules [url] | Set chat rules from the specified url | ✅ | ❌ /rules | Get chat rules | ✅ | ✅ -/report | `[by reply/username/id]` Reports a user | ✅ | ❌ +/report | `[by reply/username/id]` Reports a user | ✅ | ✅ /evidence [questionId] | `[by reply/username/id]` Adds the quoted message as evidence to the arbitrator of `questionId` | ✅ | ✅ ### Attribution From 49d2d3b4f1dd98f9ea3be5100e3e4366aa8662fe Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Mon, 6 Feb 2023 09:36:04 +0000 Subject: [PATCH 061/111] fix: cron no delay --- ecosystem.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/ecosystem.config.js b/ecosystem.config.js index 506ba4f..b0e3624 100644 --- a/ecosystem.config.js +++ b/ecosystem.config.js @@ -20,6 +20,7 @@ module.exports = { autorestart: false, watch: false, ignore_watch: ['\.git', 'node_modules', 'database\.db', 'database\.db-journal'], + cron_restart: '* * * * *', env: { NODE_ENV: 'development' } From a9d7fdfc046943c39d46d7633061aeae9649a7fe Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Mon, 6 Feb 2023 10:02:56 +0000 Subject: [PATCH 062/111] fix: typos --- lib/cron.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/cron.ts b/lib/cron.ts index cc8cc9d..c52a6f1 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -435,12 +435,12 @@ const validate = (chatId: string): groupSettings=> { } const calcPenalty = (ban_level: number, timestamp_finalized: number): number => { - if(ban_level == 1) - return timestamp_finalized + 86400 + if(ban_level == 3) + return timestamp_finalized + 31536000 else if (ban_level == 2) return timestamp_finalized + 604800 - else (ban_level == 3) - return timestamp_finalized + 31536000 + else + return timestamp_finalized + 86400 } const calcPenaltyPhrase = (settings: groupSettings, ban_level: number, enforcement: boolean, finalize: boolean, realityURL: string): string => { @@ -530,7 +530,7 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, for (const ban_level of calculateHistory) if (timestamp_most_recent< ban_level.timestamp_active) - timestamp_most_recent = ban_level. timestamp_active + timestamp_most_recent = ban_level.timestamp_active if (calcPenalty(calculateHistory.length, timestamp_most_recent) > timestampNew) liftbans = false From 5eec7dc47904423a50fd1a578f9cdb27e95597ae Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Mon, 6 Feb 2023 10:09:51 +0000 Subject: [PATCH 063/111] feat: 1 dai default min bond --- lib/bot-core.ts | 2 +- lib/telegram/assets/langNew.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/bot-core.ts b/lib/bot-core.ts index 08faedb..84cd4fe 100644 --- a/lib/bot-core.ts +++ b/lib/bot-core.ts @@ -16,7 +16,7 @@ interface RealityBanResult { } export const reportUser = (batchedSend:any, lang: string, hasBanningPermission: boolean, fromUsername: string, UserID: string, platform: string, group: string, inviteURL: string, groupID: string, rules: string, message: string, messageBackup: string, reportedBy: string, isPrivate: boolean): RealityBanResult => { - const minBond = utils.parseUnits('5', 18); // 5 DAI + const minBond = utils.parseUnits('1', 18); // 5 DAI const delim = '\u241f'; const question = fromUsername+delim+UserID+delim+platform+delim+group+delim+inviteURL+delim+groupID+delim+rules+delim+message+delim+messageBackup+delim+reportedBy ; const template_id = lang === 'es'? Number(process.env.TEMPLATE_ID_ES): Number(process.env.TEMPLATE_ID_EN) diff --git a/lib/telegram/assets/langNew.json b/lib/telegram/assets/langNew.json index fbd69b1..28ff30d 100644 --- a/lib/telegram/assets/langNew.json +++ b/lib/telegram/assets/langNew.json @@ -191,7 +191,7 @@ "Language1": "🗣️ *Languages* 🗣️\n\nSusie's replies can be changed to one of the languages below.\n\n- EN (English)\n- ES (Español)\n\nContent moderation requires a nuanced understanding of context and language. Please make sure to set the appropriate language for your community for effective moderation.\n\n*Admin commands*: \n- `/lang`: Set your preferred language.", "Topics1": "ℹ️ *Topics* ℹ️\n\nTopics allow large groups to focus discussion in dedicated **topic** chats. Susie supports topics. When changing a group to topic mode, you will need to /start Susie again.\n\n*Admin commands*:\n- `/start`: Start topic mode.", "Evidence1": "🔍 *Evidence* 🔍\n\nTo prevent important messages from deletion, pre-emptively, messages can be saved as evidence.\n\n*User commands*:\n- `/evidence` : Saves message as evidence.", - "Report1": "🚨 *Report* 🚨\n\nReports create content moderation questions on the crowdsourcing platform Reality.Eth asking,\n\n***Did the user break the rules?***\n\nThe question can be answered yes/no with a bond (5 xDAI). Answers can be disputed in the Kleros court.\n\nSuccessful reports result in escalating penalties (1 day, 1 week, 1 year ban).\n\n*User commands*:\n- `/report` : Reports message.\n- `/info`: Returns active reports\n\n*Admin commands*:\n-`/adminreportable` Toggles reportability of admins.\n- `/trial` Toggles trial mode where users are not penalized", + "Report1": "🚨 *Report* 🚨\n\nReports create content moderation questions on the crowdsourcing platform Reality.Eth asking,\n\n***Did the user break the rules?***\n\nThe question can be answered yes/no with a bond (1 xDAI). Answers can be disputed in the Kleros court.\n\nSuccessful reports result in escalating penalties (1 day, 1 week, 1 year ban).\n\n*User commands*:\n- `/report` : Reports message.\n- `/info`: Returns active reports\n\n*Admin commands*:\n-`/adminreportable` Toggles reportability of admins.\n- `/trial` Toggles trial mode where users are not penalized", "Rules1": "📄 *Rules* 📄\n\nEvery groups starts with [default rules](https://ipfs.kleros.io/ipfs/Qme3Qbj9rKUNHUe9vj9rqCLnTVUCWKy2YfveQF8HiuWQSu/Kleros%20Moderate%20Community%20Rules.pdf).\n\n***Rule Writing Tips***:\n\n- State the group culture in a preamble.\n- Number each rule.\n- Be specific.\n\n*User commands*:\n- `/rules`: Returns current rules\n*Admin commands*:\n- `/setrules` or : Sets the rules to the url or message", "Court1": "⚖️ *Court* ⚖️\n\nModeration questions are resolved by the [Kleros Court](https://kleros.gitbook.io/docs/) with a jury of moderators. If the jury made a mistake, the case can be appealed, drawing a larger pool of jurors and providing an opportunity to provide more context, analysis, and arguments.\n\nIf you would like a chance to serve as a jury member, get PNK ([Gnosis Chain](https://swapr.eth.link/#/swap?chainId=100) or [Mainnet](https://app.uniswap.org/#/swap?outputCurrency=0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d&inputCurrency=ETH)) and [stake](https://court.kleros.io/) in the Kleros court.\n\nTo discuss the merits of a dispute, see @klerosjuror. To learn more about Kleros, ask a question in @Kleros", "Lawyer1": "🧑‍⚖️ *Find a Lawyer* 🧑‍⚖️\n\nDisputes over content moderation questions can be complicated.\n\nIf you need help arguing your case in the Kleros court, consider asking help from a Kleros [lawyer](https://t.me/+9fvGGkGfSZ1hZDBk).", @@ -380,7 +380,7 @@ "Language1": "🗣️ *Idiomas* 🗣️\n\nLas respuestas de Susie pueden cambiarse a uno de los siguientes idiomas.\n\n- EN (English)\n- ES (Español)\n\nLa moderación de contenidos requiere una comprensión matizada del contexto y del lenguaje. Por favor, asegúrese de establecer el idioma apropiado para su comunidad para una moderación efectiva. \n\n*Comandos de administración*:\n`/lang`: Establezca su idioma preferido.", "Topics1": "ℹ️ *Temas* ℹ️\n\nLos temas permiten a los grandes grupos centrar el debate en chats dedicados a **temas**. Susie es compatible con los temas. Cuando cambie un grupo a modo de tema, necesitará /iniciar Susie de nuevo.\n\n*Comandos de administrador*:\n- `/start`: Inicia el modo por temas.", "Evidence1": "🔍 *Evidencia* 🔍\n\nPara evitar que se borren mensajes importantes, de forma preventiva, se pueden guardar mensajes como evidencia.\n\n*Comandos de usuario*:\n- `/evidence` : Guarda el mensaje como evidencia.", - "Report1": "🚨 *Informe* 🚨 \n\nLos informes crean preguntas de moderación de contenidos en la plataforma de crowdsourcing Reality.Eth preguntando,\n\n'¿el usuario infringió las normas?'\n\nLa pregunta puede responderse sí/no con un bono (5 xDAI). Las respuestas pueden ser impugnadas en el tribunal Kleros.\n\nLos informes exitosos resultan en sanciones escalonadas (1 día, 1 semana, 1 año de prohibición).\n\n*Comandos de usuario*:\n- `/report` : Informa del mensaje.\n- `/info`: Devuelve los informes activos.n\n*Comandos de administrador*:\n-`/adminreportable` Activa la posibilidad de informar de los administradores.\n- `/trial` Activa el modo de prueba en el que los usuarios no son penalizados.", + "Report1": "🚨 *Informe* 🚨 \n\nLos informes crean preguntas de moderación de contenidos en la plataforma de crowdsourcing Reality.Eth preguntando,\n\n'¿el usuario infringió las normas?'\n\nLa pregunta puede responderse sí/no con un bono (1 xDAI). Las respuestas pueden ser impugnadas en el tribunal Kleros.\n\nLos informes exitosos resultan en sanciones escalonadas (1 día, 1 semana, 1 año de prohibición).\n\n*Comandos de usuario*:\n- `/report` : Informa del mensaje.\n- `/info`: Devuelve los informes activos.n\n*Comandos de administrador*:\n-`/adminreportable` Activa la posibilidad de informar de los administradores.\n- `/trial` Activa el modo de prueba en el que los usuarios no son penalizados.", "Rules1": "📄 *Reglas* 📄\n\nTodos los grupos empiezan con [reglas por defecto](https://ipfs.kleros.io/ipfs/QmSHAjfD1MYPtyopFoXcUQ5Ny3sfs5re1yz3h3TZ5qGDsp/Kleros%20Moderate%20Normas%20comunitarias.pdf). \n\n***Consejos para la redacción de reglas***:\n\n -Enuncie la cultura del grupo en un preámbulo.\n -Numere cada regla.\nSea específico.\n\n*Comandos de usuario*:\n-`/rules`: Devuelve las reglas.\n*Comandos de administrador*:\n- `/setrules` o : Establece las reglas a la url o mensaje.", "Court1": "⚖️ *Corte* ⚖️\n\nLas preguntas de moderación las resuelve el [Kleros Court](https://kleros.gitbook.io/docs/) con un jurado de moderadores. Si el jurado cometió un error, el caso puede ser apelado, atrayendo a un grupo más grande de miembros del jurado y proporcionando la oportunidad de proporcionar más contexto, análisis y argumentos.\n\nSi desea tener la oportunidad de servir como miembro del jurado, obtenga PNK ([Gnosis Chain](https://swapr.eth.link/#/swap?chainId=100) o [Mainnet](https://app.uniswap.org/#/swap?outputCurrency=0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d&inputCurrency=ETH)) y [stake](https://court.kleros.io/) en el tribunal de Kleros.\n\nPara discutir el fondo de una disputa, consulte @klerosjuror.", "Lawyer1": "🧑‍⚖️ *Busque un abogado* 🧑‍⚖️ \n\nLas disputas sobre informes pueden ser complicadas.\n\nSi necesita ayuda para defender su caso ante el tribunal kleros, considere pedir ayuda a un [abogado] kleros(https://t.me/+9fvGGkGfSZ1hZDBk).", From 310701e3d4e62b78bbaa9a00572ab634f53d4233 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Mon, 6 Feb 2023 10:53:10 +0000 Subject: [PATCH 064/111] fix: report info format --- lib/telegram/commands/getReports.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/telegram/commands/getReports.ts b/lib/telegram/commands/getReports.ts index bfa20a5..0ad0ba5 100644 --- a/lib/telegram/commands/getReports.ts +++ b/lib/telegram/commands/getReports.ts @@ -63,8 +63,8 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, group_id = msg.text.substring(16,30) user_id = msg.text.substring(30,40) federation_id = msg.text.substring(40) - } else if (msg.text.length > 39){ - user_id = msg.text.substring(30,40) + } else if (msg.text.length >= 39){ + user_id = msg.text.substring(30) group_id = msg.text.substring(16,30) } else if (msg.text.length > 29){ group_id = msg.text.substring(16,30) From 5d920571fa683cd09700ae414a43b34c74e9f628 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Mon, 6 Feb 2023 11:05:17 +0000 Subject: [PATCH 065/111] fix: missing key value --- lib/telegram/assets/langNew.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/telegram/assets/langNew.json b/lib/telegram/assets/langNew.json index 28ff30d..e4f02df 100644 --- a/lib/telegram/assets/langNew.json +++ b/lib/telegram/assets/langNew.json @@ -1,5 +1,6 @@ { "en":{ + "answer": "answer", "reputation": { "sheriff": "There's a new sheriff in town", "deputy": "There's a new deputy sheriff in town", @@ -214,6 +215,7 @@ } }, "es":{ + "answer": "respuesta", "reputation": { "sheriff": "Hay un nuevo sheriff en la ciudad", "deputy": "Hay un nuevo ayudante del sheriff en la ciudad", From fe544a2dba8cc7a109130d7e4350e3e0b84afe99 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Mon, 6 Feb 2023 15:00:03 +0000 Subject: [PATCH 066/111] chore: msg format --- lib/telegram/assets/langNew.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/telegram/assets/langNew.json b/lib/telegram/assets/langNew.json index e4f02df..e3d9542 100644 --- a/lib/telegram/assets/langNew.json +++ b/lib/telegram/assets/langNew.json @@ -98,7 +98,7 @@ "greeting": { "multilang": "Este grupo representa a la comunidad de lengua inglesa. La comunidad de lengua española se encuentra en este [grupo]", "greeting0": "Hi 👋 Welcome", - "greeting1": "Welcome, this group is moderated with [Kleros Moderate](https://kleros.io/moderate/). Please make sure to follow the [community rules]", + "greeting1": "This group is moderated with [Kleros Moderate](https://kleros.io/moderate/). Please make sure to follow the [community rules]", "greeting2": "Users who break the rules can be reported by replying to a message with the command `/report`.", "captcha": "I agree to follow the rules." }, From 1c1510ec4168fdbb1097cef288cbb2362ffba07e Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Mon, 6 Feb 2023 15:24:25 +0000 Subject: [PATCH 067/111] chore: msg format --- lib/telegram/commands/getReports.ts | 2 +- lib/telegram/commands/report.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/telegram/commands/getReports.ts b/lib/telegram/commands/getReports.ts index 0ad0ba5..31f9864 100644 --- a/lib/telegram/commands/getReports.ts +++ b/lib/telegram/commands/getReports.ts @@ -103,7 +103,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, const MsgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + report.msg_id; const msgTimehours = new Date(report.timestamp_msg*1000).toUTCString(); const reportState = report.finalized? langJson[settings.lang].getReports.reportFinal : langJson[settings.lang].getReports.reportCurrent; - reportMessage += ` - [${langJson[settings.lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), [Message](${MsgLink}), Sent ${msgTimehours.substring(0,12)}([${langJson[settings.lang].socialConsensus.consensus5}](${report.msgBackup})), ${reportState} ${langJson[settings.lang].answer}, ${reportAnswer}${report.finalized? ".":`, \`/evidence ${report.evidenceIndex}\`.`}\n`; + reportMessage += ` - [${langJson[settings.lang].getReports.reportMessage3}](https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${report.question_id}), [Message](${MsgLink}), Sent ${msgTimehours.substring(0,12)}([${langJson[settings.lang].socialConsensus.consensus5}](${report.msgBackup})), ${reportState} ${langJson[settings.lang].answer}, ${reportAnswer}${report.finalized? "":`, \`/evidence ${report.evidenceIndex}\``}\n`; }); if(federation_id){ const reportsFederation = getReportsUserInfoFederation(db, 'telegram', user_id, federation_id,group_id); diff --git a/lib/telegram/commands/report.ts b/lib/telegram/commands/report.ts index b544e95..7fc3fd5 100644 --- a/lib/telegram/commands/report.ts +++ b/lib/telegram/commands/report.ts @@ -244,9 +244,9 @@ const reportMsg = async (queue: any, settings: groupSettings, db: any, bot: any, addReport(db, questionId, 'telegram', String(msg.chat.id), reportedUserID, fromUsername , msgId, Number(msgDate),evidenceIndex, msgBackup); console.log(msgLink) if (settings.lang === "en") - queue.add(async () => {try{bot.sendMessage(settings.channelID, `[${fromUsername}](tg://user?id=${reportedUserID})'s conduct due to this [message](${msgLink}) ([backup](${msgBackup})) is reported for breaking the [rules](${rules}).\n\nDid *${fromUsername}* break the rules? The [question](${appealUrl}) can be answered with a minimum bond of 5 DAI. Need assistance answering the question? [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpgnosis) me for help : )\n\nTo save a record, reply to messages you want saved with \`/evidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: settings.thread_id_notifications , parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + queue.add(async () => {try{bot.sendMessage(settings.channelID, `[${fromUsername}](tg://user?id=${reportedUserID})'s conduct due to this [message](${msgLink}) ([backup](${msgBackup})) is reported for breaking the [rules](${rules}).\n\nDid *${fromUsername}* break the rules? The [question](${appealUrl}) can be answered with a minimum bond of 1 DAI. Need assistance answering the question? [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpgnosis) me for help : )\n\nTo save a record, reply to messages you want saved with \`/evidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: settings.thread_id_notifications , parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); else if (settings.lang === "es") - queue.add(async () => {try{bot.sendMessage(settings.channelID, `La conducta de [${fromUsername}](tg://user?id=${reportedUserID}) a este [mensaje](${msgLink}) ([backup](${msgBackup})) es denunciada por infringir las [reglas](${rules}).\n\nHa infringido el usuario *${fromUsername}* las reglas? La [pregunta](${appealUrl}) puede responderse con un bono mínimo de 5 DAI. Necesitas ayuda para responder a la pregunta? [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpgnosis) me para obetener ayuda : )\n\nPara guardar un mensaje, responda a los mensajes que desee guardar con \`/evidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: settings.thread_id_notifications , parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + queue.add(async () => {try{bot.sendMessage(settings.channelID, `La conducta de [${fromUsername}](tg://user?id=${reportedUserID}) a este [mensaje](${msgLink}) ([backup](${msgBackup})) es denunciada por infringir las [reglas](${rules}).\n\nHa infringido el usuario *${fromUsername}* las reglas? La [pregunta](${appealUrl}) puede responderse con un bono mínimo de 1 DAI. Necesitas ayuda para responder a la pregunta? [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpgnosis) me para obetener ayuda : )\n\nPara guardar un mensaje, responda a los mensajes que desee guardar con \`/evidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: settings.thread_id_notifications , parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); return [appealUrl, evidenceIndex]; } catch (e) { console.log(e); From a1052b724772e9a2aa2414dc0a0240e8be0025eb Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Mon, 6 Feb 2023 16:45:06 +0000 Subject: [PATCH 068/111] chore: increased report, evidence limits --- lib/telegram/commands/addEvidence.ts | 10 +++++----- lib/telegram/commands/report.ts | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/telegram/commands/addEvidence.ts b/lib/telegram/commands/addEvidence.ts index bae87c2..1ddd24f 100644 --- a/lib/telegram/commands/addEvidence.ts +++ b/lib/telegram/commands/addEvidence.ts @@ -347,8 +347,8 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, } const reportAllowance = getAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id)); if (!reportAllowance){ - setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), 3, 14, Math.ceil( new Date().getTime() / 1000)); - } else if ((Math.ceil( new Date().getTime() / 1000) < reportAllowance.timestamp_refresh + 5760) && reportAllowance.evidence_allowance == 0 ){ + setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), 9, 29, Math.ceil( new Date().getTime() / 1000)); + } else if ((Math.ceil( new Date().getTime() / 1000) < reportAllowance.timestamp_refresh + 5760) && reportAllowance.evidence_allowance < 1 ){ try{ const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].addevidence.allowance) return val}catch{}}); @@ -359,10 +359,10 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, console.log(e) } } else{ - const newReportAllowance = reportAllowance.report_allowance + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800); - const newEvidenceAllowance = reportAllowance.evidence_allowance + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800)*5 - 1; + const newReportAllowance = reportAllowance.report_allowance + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800)*3; + const newEvidenceAllowance = reportAllowance.evidence_allowance + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800)*10 - 1; const newRefreshTimestamp = reportAllowance.timestamp_refresh + Math.floor((Math.ceil( new Date().getTime() / 1000) - reportAllowance.timestamp_refresh)/28800)*28800; - setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), Math.min(newReportAllowance,3), Math.min(newEvidenceAllowance,15), newRefreshTimestamp); + setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), Math.min(newReportAllowance,9), Math.min(newEvidenceAllowance,30), newRefreshTimestamp); } try { diff --git a/lib/telegram/commands/report.ts b/lib/telegram/commands/report.ts index 7fc3fd5..135d0a9 100644 --- a/lib/telegram/commands/report.ts +++ b/lib/telegram/commands/report.ts @@ -138,8 +138,8 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b if((reporter.status === "administrator" || reporter.status === "creator")){ console.log(reporter.status) } else if (!reportAllowance){ - setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), 2, 15, currentTimeMs); - } else if (currentTimeMs < reportAllowance.timestamp_refresh + 28800 && reportAllowance.report_allowance == 0 ){ + setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), 9, 30, currentTimeMs); + } else if (currentTimeMs < reportAllowance.timestamp_refresh + 28800 && reportAllowance.report_allowance < 1 ){ console.log(msg) const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].report.noallowance, (msg.chat.is_forum && msg.is_topic_message)? String(msg.message_thread_id): {}) return val}catch (e){console.log(e)}}); @@ -148,10 +148,10 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b myCacheGarbageCollection.set(resp.message_id, msg.chat.id) return; } else{ - const newReportAllowance = reportAllowance.report_allowance + Math.floor((currentTimeMs - reportAllowance.timestamp_refresh)/28800) - 1; - const newEvidenceAllowance = reportAllowance.evidence_allowance + Math.floor((currentTimeMs - reportAllowance.timestamp_refresh)/28800)*5; + const newReportAllowance = reportAllowance.report_allowance + Math.floor((currentTimeMs - reportAllowance.timestamp_refresh)/28800)*3 - 1; + const newEvidenceAllowance = reportAllowance.evidence_allowance + Math.floor((currentTimeMs - reportAllowance.timestamp_refresh)/28800)*10; const newRefreshTimestamp = reportAllowance.timestamp_refresh + Math.floor((currentTimeMs - reportAllowance.timestamp_refresh)/28800)*28800; - setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), Math.min(newReportAllowance,3), Math.min(newEvidenceAllowance,15), newRefreshTimestamp); + setAllowance(db, 'telegram', String(msg.chat.id), String(msg.from.id), Math.min(newReportAllowance,9), Math.min(newEvidenceAllowance,30), newRefreshTimestamp); } console.log(msg) console.log(msgId) From c147cce53f8eb7b4a3f30c2032dbc94ebf7bb4ee Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Fri, 10 Feb 2023 14:22:46 +0000 Subject: [PATCH 069/111] feat: forgiveness and warnings --- lib/create-db.ts | 36 +++++-- lib/cron.ts | 148 +++++++++++++++++++++------ lib/db.ts | 84 ++++++++++++--- lib/telegram/assets/langNew.json | 44 +++++--- lib/telegram/commands/forgive.ts | 55 ++++++++++ lib/telegram/commands/getReports.ts | 5 +- lib/telegram/commands/report.ts | 11 +- lib/telegram/commands/setWarnmode.ts | 60 +++++++++++ lib/telegram/index.ts | 145 +++++++++++++++----------- 9 files changed, 450 insertions(+), 138 deletions(-) create mode 100644 lib/telegram/commands/forgive.ts create mode 100644 lib/telegram/commands/setWarnmode.ts diff --git a/lib/create-db.ts b/lib/create-db.ts index 6308612..928a4d9 100644 --- a/lib/create-db.ts +++ b/lib/create-db.ts @@ -30,6 +30,7 @@ const Database = require('better-sqlite3'); enforcement BIT, lang TEXT, rules TEXT, + warn_mode BIT, PRIMARY KEY (platform, group_id))` ); @@ -78,14 +79,29 @@ const Database = require('better-sqlite3'); * `timestamp` the timestamp when the rules were set. */ await db.exec( - `CREATE TABLE rules ( - platform TEXT, - group_id TEXT, - rules TEXT, - timestamp INTEGER, - msg_id TEXT, - PRIMARY KEY (platform, group_id, timestamp))` - ); + `CREATE TABLE rules ( + platform TEXT, + group_id TEXT, + rules TEXT, + timestamp INTEGER, + msg_id TEXT, + PRIMARY KEY (platform, group_id, timestamp))` + ); + + /** + * `platform` can be `telegram`, `reddit`, etc. + * `group_id` is the id of the group on the platform (eg. group on telegram, subreddit on reddit, etc.). + * `rules` the group rules. eg ipfs cid string. + * `timestamp` the timestamp when the rules were set. + */ + await db.exec( + `CREATE TABLE forgiveness ( + platform TEXT, + group_id TEXT, + user_id TEXT, + timestamp INTEGER, + PRIMARY KEY (platform, group_id, user_id))` + ); /** * `question_id` is the id of the question in reality.eth @@ -96,7 +112,7 @@ const Database = require('better-sqlite3'); * `active` indicates whether the user is currently banned. * `finalized` indicates if the question has finalized. */ - await db.exec( + await db.exec( `CREATE TABLE reports ( question_id TEXT PRIMARY KEY, platform TEXT, @@ -117,6 +133,8 @@ const Database = require('better-sqlite3'); )` ); + + /** * `platform` can be `telegram`, `reddit`, etc. * `federation_id` is the user_id of the federation owner on the platform (eg. group on telegram, subreddit on reddit, etc.). diff --git a/lib/cron.ts b/lib/cron.ts index c52a6f1..bd8e129 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -1,5 +1,5 @@ require('dotenv').config() -import {openDb, getGroupSettings, getRule, getCron, getMultilangGroup, getFederationChannel, getInviteURL, getFederatedFollowingBanHistory, getLocalBanHistory, getFederatedBanHistory, setCron, getGroupsInAndFollowingFederation, getReportMessageTimestampAndActive, setReport} from "./db"; +import {openDb, getGroupSettings, getRule, getCron, getWarn, getForgiveness, getFederationChannel, getInviteURL, getFederatedFollowingBanHistory, getLocalBanHistory, getFederatedBanHistory, setCron, getGroupsInAndFollowingFederation, getReportMessageTimestampAndActive, setReport} from "./db"; import request from "graphql-request"; import {BigNumber} from "ethers"; import TelegramBot from "node-telegram-bot-api"; @@ -11,7 +11,7 @@ const ModeratorBot = require('node-telegram-bot-api'); const Web3 = require('web3') const realitio_bot = require('./realitioReporting') const db = openDb(); -const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: false, testEnvironment: false}); +const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: false, testEnvironment: true}); const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCount: true}); // Only need DB for // - channelID @@ -49,7 +49,11 @@ const exit = async () => { console.log(history.last_block) let timestampLastUpdated = history.last_timestamp - const isUpdated = await update(currentTime, timestampLastUpdated, botaddress); + console.log('##LASTUPDATED') + console.log(timestampLastUpdated) + timestampLastUpdated = await update(currentTime, timestampLastUpdated, botaddress); + console.log('##LASTUPDATED') + console.log(timestampLastUpdated) const updateBlock = Math.min(history.last_block+1000, currentBlock) try{ await realitio_bot(web3, history.last_block, updateBlock, process.env.REALITY_ETH_V30, process.env.REALITIO_ARBITRATOR_EN); @@ -58,12 +62,10 @@ const exit = async () => { console.log(e) } history.last_block = updateBlock - if (isUpdated) - timestampLastUpdated = currentTime setCron(db, history.last_block,timestampLastUpdated) })() -const update = async (timestampNew: number, timestampLastUpdated: number,botaddress: string): Promise =>{ +const update = async (timestampNew: number, timestampLastUpdated: number,botaddress: string): Promise =>{ const reports = {}; let delayQuestions = "" @@ -79,10 +81,10 @@ const update = async (timestampNew: number, timestampLastUpdated: number,botaddr // jannies deputysheriff const lastPageUpdated = 0; const queryModeration = getQuery(lastPageUpdated, timestampLastUpdated, botaddress, timestampNew) - + let timestampUpdated = timestampLastUpdated //console.log(queryModeration); //console.log('graphtime'); - //console.log(queryModeration) + console.log(queryModeration) const moderationActions = await request( process.env.MODERATE_SUBGRAPH, queryModeration @@ -91,6 +93,8 @@ const update = async (timestampNew: number, timestampLastUpdated: number,botaddr var isUpdated = false; for (const data of moderationActions.disputesFinal) { isUpdated = true + if (data.timestampLastUpdated > timestampUpdated) + timestampUpdated = data.timestampLastUpdated const settings = validate(data.moderationInfo.UserHistory.group.groupID); // settings[1] language try{ @@ -118,6 +122,8 @@ const update = async (timestampNew: number, timestampLastUpdated: number,botaddr for (const data of moderationActions.disputesAppealPossible) { isUpdated = true + if (data.timestampLastAppealPossible > timestampUpdated) + timestampUpdated = data.timestampLastAppealPossible const settings = validate(data.moderationInfo.UserHistory.group.groupID); const msgLink = data.moderationInfo.message; const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; @@ -155,6 +161,8 @@ const update = async (timestampNew: number, timestampLastUpdated: number,botaddr for (const data of moderationActions.disputesCreated) { isUpdated = true + if (data.timestampLastUpdated > timestampUpdated) + timestampUpdated = data.timestampLastUpdated const settings = validate(data.moderationInfo.UserHistory.group.groupID); // settings[1] language const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; @@ -197,6 +205,8 @@ const update = async (timestampNew: number, timestampLastUpdated: number,botaddr for (const data of moderationActions.disputesAppealFunded) { isUpdated = true + if (data.timestampLastUpdated > timestampUpdated) + timestampUpdated = data.timestampLastUpdated const settings = validate(data.moderationInfo.UserHistory.group.groupID); const msgLink = data.moderationInfo.message; const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${data.moderationInfo.id}`; @@ -245,6 +255,10 @@ const update = async (timestampNew: number, timestampLastUpdated: number,botaddr for(const data of moderationActions.realityQuestionAnsweredFinalized){ isUpdated = true + console.log("DDDDDDATA") + console.log(data) + if (data.deadline > timestampUpdated) + timestampUpdated = data.deadline const settings = validate(data.moderationInfo.UserHistory.group.groupID); // settings[1] language try{ @@ -260,6 +274,8 @@ for(const data of moderationActions.realityQuestionAnsweredFinalized){ } for(const data of moderationActions.realityQuestionAnsweredNotFinalized){ isUpdated = true + if (data.timestampLastUpdated > timestampUpdated) + timestampUpdated = data.timestampLastUpdated //console.log(data.moderationInfo.UserHistory.group) const settings = validate(data.moderationInfo.UserHistory.group.groupID); // settings[1] language @@ -304,6 +320,8 @@ for(const data of moderationActions.realityQuestionAnsweredNotFinalized){ // promise queue example for(const data of moderationActions.sheriffs){ isUpdated = true + if (data.timestampLastUpdatedSheriff > timestampUpdated) + timestampUpdated = data.timestampLastUpdatedSheriff const settings = validate(data.group.groupID); // settings[1] language try{ @@ -321,6 +339,8 @@ for(const data of moderationActions.realityQuestionAnsweredNotFinalized){ for(const data of moderationActions.deputySheriffs){ isUpdated = true + if (data.timestampLastUpdatedDeputySheriff > timestampUpdated) + timestampUpdated = data.timestampLastUpdatedDeputySheriff const settings = validate(data.group.groupID); // settings[1] language try{ @@ -337,6 +357,8 @@ for(const data of moderationActions.realityQuestionAnsweredNotFinalized){ for(const data of moderationActions.ranks){ isUpdated = true + if (data.timestampStatusUpdated > timestampUpdated) + timestampUpdated = data.timestampStatusUpdated const settings = validate(data.group.groupID); // settings[1] language try{ @@ -361,7 +383,7 @@ for(const data of moderationActions.realityQuestionAnsweredNotFinalized){ } } await queue.onIdle() - return isUpdated + return timestampUpdated } const delay = (delayInms) => { @@ -435,12 +457,12 @@ const validate = (chatId: string): groupSettings=> { } const calcPenalty = (ban_level: number, timestamp_finalized: number): number => { - if(ban_level == 3) - return timestamp_finalized + 31536000 + if(ban_level == 1) + return timestamp_finalized + 86400 else if (ban_level == 2) return timestamp_finalized + 604800 else - return timestamp_finalized + 86400 + return timestamp_finalized + 31536000 } const calcPenaltyPhrase = (settings: groupSettings, ban_level: number, enforcement: boolean, finalize: boolean, realityURL: string): string => { @@ -451,56 +473,103 @@ const calcPenaltyPhrase = (settings: groupSettings, ban_level: number, enforceme else if (ban_level == 2) return finalize? enforcement? 'segunda vez y está sujeto a una prohibición de 1 semana' : 'segunda vez y se recomienda una prohibición de 1 semana': enforcement? `segunda vez y se silencia durante 1 día durante el resto del periodo del [informe](${realityURL})`: `segunda vez y se le recomienda un silencio de 1 día para el resto del periodo del [informe](${realityURL})` else - return finalize? enforcement? 'tercera vez y está sujeto a una prohibición de 1 mes' : 'tercera vez y se recomienda una prohibición de 1 mes' : enforcement? `trecera vez y se silencia durante 1 día durante el resto del periodo del [informe](${realityURL})`: `tercera vez y se le recomienda un silencio de 1 día por el resto del período del [informe](${realityURL})` + return finalize? enforcement? 'tercera vez y está sujeto a una prohibición de 1 año' : 'tercera vez y se recomienda una prohibición de 1 año' : enforcement? `trecera vez y se silencia durante 1 día durante el resto del periodo del [informe](${realityURL})`: `tercera vez y se le recomienda un silencio de 1 día por el resto del período del [informe](${realityURL})` } else { if(ban_level == 1) return finalize? enforcement? 'first time and is subject to a 1 day ban' : 'first time and is recommended a 1 day ban' : enforcement? `first time and is muted for 1 day during the remainder of the [report](${realityURL})`: `first time and is recommended a 1 day mute for the remainder of the [report](${realityURL})` else if (ban_level == 2) return finalize? enforcement? 'second time and is subject to a 1 week ban' : 'second time and is recommended a 1 week ban': enforcement? `second time and is muted for 1 day during the remainder of the [report](${realityURL})`: `second time and is recommended a 1 day mute for the remainder of the [report](${realityURL})` else - return finalize? enforcement? 'third time and is subject to a 1 month ban' : 'third time and is recommended a 1 month ban' : enforcement? `third time and is muted for 1 day during the remainder of the [report](${realityURL})`: `third time and is recommended a 1 day mute for the remainder of the [report](${realityURL})` + return finalize? enforcement? 'third time and is subject to a 1 year ban' : 'third time and is recommended a 1 year ban' : enforcement? `third time and is muted for 1 day during the remainder of the [report](${realityURL})`: `third time and is recommended a 1 day mute for the remainder of the [report](${realityURL})` } } + const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, moderationInfo: any, timestampNew: number, restrict: boolean, finalize: boolean, disputed: boolean) => { try{ console.log('UPDATE#########') console.log(settings) const reportInfo = getReportMessageTimestampAndActive(db, moderationInfo.id) if (!reportInfo) return; + + const timestamp_forgiven = getForgiveness(db, 'telegram',moderationInfo.UserHistory.group.groupID,moderationInfo.UserHistory.user.userID) + const warnings = getWarn(db,'telegram',String(moderationInfo.UserHistory.group.groupID)) + let calculateHistory = [] if (settings.federation_id){ - calculateHistory = getFederatedBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,settings.federation_id,finalize) + calculateHistory = getFederatedBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,settings.federation_id,finalize, timestamp_forgiven) } else if (settings.federation_id_following){ - calculateHistory = getFederatedFollowingBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,moderationInfo.UserHistory.group.groupID,settings.federation_id_following,finalize) + calculateHistory = getFederatedFollowingBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,moderationInfo.UserHistory.group.groupID,settings.federation_id_following,finalize, timestamp_forgiven) } else - calculateHistory = getLocalBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,moderationInfo.UserHistory.group.groupID,finalize) + calculateHistory = getLocalBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,moderationInfo.UserHistory.group.groupID,finalize, timestamp_forgiven) const ban_level_history = calculateHistory.length setReport(db, moderationInfo.id,restrict,true,finalize,disputed, finalize? 0 : (restrict? timestampNew: 0), finalize? timestampNew: 0) if (settings.federation_id){ - calculateHistory = getFederatedBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,settings.federation_id,finalize) + calculateHistory = getFederatedBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,settings.federation_id,finalize, timestamp_forgiven) } else { if (settings.federation_id_following){ - calculateHistory = getFederatedFollowingBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,moderationInfo.UserHistory.group.groupID,settings.federation_id_following,finalize) + calculateHistory = getFederatedFollowingBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,moderationInfo.UserHistory.group.groupID,settings.federation_id_following,finalize, timestamp_forgiven) } else - calculateHistory = getLocalBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,moderationInfo.UserHistory.group.groupID,finalize) + calculateHistory = getLocalBanHistory(db, 'telegram', moderationInfo.UserHistory.user.userID,moderationInfo.UserHistory.group.groupID,finalize, timestamp_forgiven) } - const ban_level_current = calculateHistory.length + const ban_level_current = calculateHistory.length console.log(calculateHistory) const groups = settings.federation_id? getGroupsInAndFollowingFederation(db,'telegram',settings.federation_id) : [{group_id: moderationInfo.UserHistory.group.groupID}] const realityURL = `https://reality.eth.limo/app/#!/network/${process.env.CHAIN_ID}/question/${process.env.REALITY_ETH_V30}-${moderationInfo.id}`; - - if (restrict){ + if(restrict && finalize && ban_level_current > ban_level_history && ban_level_current <= warnings){ + // finalize warning + if(settings.enforcement){ + const options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false}; + queue.add(async () => {try{await bot.restrictChatMember(moderationInfo.UserHistory.group.groupID, moderationInfo.UserHistory.user.userID, options)}catch (e){console.log(e)}}); + const msg_apologize = settings.lang === 'es'? `la conducta de [${moderationInfo.UserHistory.user.username}](tg://user?id=${moderationInfo.UserHistory.user.userID}) por este [mensaje](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) viola las [reglas](${moderationInfo.rulesUrl}). Esta es la ${ban_level_current == 1 ? "primera" : ban_level_current == 2? "segunda": "trecera"} warn del usario *${moderationInfo.UserHistory.user.username}*. Por favor, revise las [reglas](${moderationInfo.rulesUrl}) y discúlpese.` : `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}). This is [${moderationInfo.UserHistory.user.username}](tg://user?id=${moderationInfo.UserHistory.user.userID})'s ${ban_level_current == 1 ? "first" : ban_level_current == 2? "second": "third"} warning.\n\nPlease review the [rules](${moderationInfo.rulesUrl}) and apologize.` + const opts = { + parse_mode: 'Markdown', + disable_web_page_preview: true, + reply_markup: { + inline_keyboard: [ + [ + { + text: langJson[settings.lang].apologize, + callback_data: '5|'+moderationInfo.UserHistory.user.userID + } + ] + ] + } + }; + const optsThread = { + parse_mode: 'Markdown', + message_thread_id: settings.thread_id_welcome, + disable_web_page_preview: true, + reply_markup: { + inline_keyboard: [ + [ + { + text: langJson[settings.lang].apologize, + callback_data: '5|'+moderationInfo.UserHistory.user.userID + } + ] + ] + } + }; + queue.add(async () => {try{const val = await bot.sendMessage(settings.channelID, msg_apologize, settings.thread_id_notifications? optsThread: opts) + return val}catch(e){console.log(e)}}); + } + } + else if (!finalize && ban_level_current <= warnings){ + // no optimistic warning + } + else if (restrict){ // TODO federation subscriptions - - if (ban_level_current > ban_level_history){ - const parole = calcPenalty(ban_level_current,timestampNew) + if (ban_level_current > ban_level_history && ban_level_current > warnings){ + const parole = calcPenalty(ban_level_current-warnings,timestampNew) + if (settings.enforcement){ if(finalize){ + // if message reported timestamp is before the most recent finalized ban / penality, users deserve a second chance, no action taken // philosophy is only escalate the penalties after the user is warned with a temporary ban. // this report changed penalties, recalculate all @@ -515,14 +584,17 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, } } } - const msg_enforcement = settings.lang === 'es'? `la conducta de *${moderationInfo.UserHistory.user.username}* por este [mensaje](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) mensaje viola las [reglas](${moderationInfo.rulesUrl}) por ${calcPenaltyPhrase(settings, ban_level_current, settings.enforcement, finalize, realityURL)}.` : `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}) for the ${calcPenaltyPhrase(settings, ban_level_current, settings.enforcement, finalize, realityURL)}.` + const msg_enforcement = settings.lang === 'es'? `la conducta de *${moderationInfo.UserHistory.user.username}* por este [mensaje](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) viola las [reglas](${moderationInfo.rulesUrl}) por ${calcPenaltyPhrase(settings, ban_level_current-warnings, settings.enforcement, finalize, realityURL)}.` : `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}) for the ${calcPenaltyPhrase(settings, ban_level_current-warnings, settings.enforcement, finalize, realityURL)}.` queue.add(async () => {try{await bot.sendMessage(settings.channelID, msg_enforcement, settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown',disable_web_page_preview: true}: {parse_mode: 'Markdown',disable_web_page_preview: true})}catch{}}); } else{ const i = calculateHistory.findIndex(e => e.question_id === moderationInfo.id); if (i > -1) { - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}) for the ${calcPenaltyPhrase(settings, ban_level_current, settings.enforcement, finalize, realityURL)}.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true})}catch{}}); - } else - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}). The conduct occured before *${moderationInfo.UserHistory.user.username}*'s latest confirmed report, so the user is recommended to get a second chance --- they should have been penalized already.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true})}catch{}}); + const msg_info = settings.lang === 'es'? `La conducta de *${moderationInfo.UserHistory.user.username}* debido a este mensaje(${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violó las [reglas](${moderationInfo.rulesUrl}) por ${calcPenaltyPhrase(settings, ban_level_current-warnings, settings.enforcement, finalize, realityURL)}.`:`*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}) for the ${calcPenaltyPhrase(settings, ban_level_current-warnings, settings.enforcement, finalize, realityURL)}.` + queue.add(async () => {try{await bot.sendMessage(settings.channelID, msg_info,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true})}catch{}}); + } else{ + const msg_info = settings.lang === 'es'? `La conducta de *${moderationInfo.UserHistory.user.username}* debido a este mensaje(${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violó las [reglas](${moderationInfo.rulesUrl}). La conducta se produjo antes del último informe confirmado de *${moderationInfo.UserHistory.user.username}*, por lo que no se aplican sanciones.` : `*${moderationInfo.UserHistory.user.username}*'s conduct due to this [message](${moderationInfo.message}) ([backup](${moderationInfo.messageBackup})) violated the [rules](${moderationInfo.rulesUrl}). The conduct occured before *${moderationInfo.UserHistory.user.username}*'s latest confirmed report, so no penalties are applied.` + queue.add(async () => {try{await bot.sendMessage(settings.channelID, msg_info,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown', disable_web_page_preview: true}: {parse_mode: 'Markdown', disable_web_page_preview: true})}catch{}}); + } } } else if (ban_level_current < ban_level_history){ let liftbans = true; @@ -532,7 +604,7 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, if (timestamp_most_recent< ban_level.timestamp_active) timestamp_most_recent = ban_level.timestamp_active - if (calcPenalty(calculateHistory.length, timestamp_most_recent) > timestampNew) + if (calcPenalty(ban_level_current-warnings, timestamp_most_recent) > timestampNew) liftbans = false if(liftbans){ if (settings.enforcement) @@ -549,7 +621,7 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, queue.add(async () => {try{await bot.sendMessage(settings.channelID, msg_update,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); } else { const msg_update = settings.lang === "en" ? `*${moderationInfo.UserHistory.user.username}* has other active reports and should remain restricted.` : `*${moderationInfo.UserHistory.user.username}* tiene otros informes activos y debe permanecer restringido.` - queue.add(async () => {try{await bot.sendMessage(settings.channelID, `*${moderationInfo.UserHistory.user.username}* has other active reports and should remain restricted.`,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + queue.add(async () => {try{await bot.sendMessage(settings.channelID, msg_update,settings.thread_id_notifications? {message_thread_id: settings.thread_id_notifications, parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); } } } catch(e){ @@ -561,6 +633,7 @@ const moderationInfoContent = ` id message messageBackup moderationType +deadline rulesUrl UserHistory{ countBrokeRulesArbitrated @@ -580,26 +653,31 @@ const getQuery = (lastPageUpdated: number, timestampLastUpdated: number, botaddr return `{ disputesFinal: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastUpdated_gt: ${timestampLastUpdated}, timestampLastUpdated_lt: ${timestampNew}, finalRuling_not: null, moderationInfo_: {askedBy: "${botaddress}"}}) { id + timestampLastUpdated finalRuling ${moderationInfo} } disputesAppealPossible: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastAppealPossible_gt: ${timestampLastUpdated}, timestampLastAppealPossible_lt: ${timestampNew}, finalRuling: null, moderationInfo_: {askedBy: "${botaddress}"}}) { id + timestampLastAppealPossible currentRuling ${moderationInfo} } disputesAppeal: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastAppeal_gt: ${timestampLastUpdated}, timestampLastAppeal_lt: ${timestampNew}, finalRuling: null, moderationInfo_: {askedBy: "${botaddress}"}}) { id + timestampLastAppeal currentRuling ${moderationInfo} } disputesCreated: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastUpdated_gt: ${timestampLastUpdated}, timestampLastUpdated_lt: ${timestampNew}, finalRuling: null, currentRuling: null, rulingFunded: null, moderationInfo_: {askedBy: "${botaddress}"}}) { id + timestampLastUpdated ${moderationInfo} } disputesAppealFunded: moderationDisputes(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastAppealPossible_gt: ${timestampLastUpdated}, , timestampLastAppealPossible_lt: ${timestampNew}, rulingFunded_not: null, moderationInfo_: {askedBy: "${botaddress}"}}) { id rulingFunded + timestampLastAppealPossible currentRuling ${moderationInfo} } @@ -608,6 +686,7 @@ return `{ } realityQuestionAnsweredFinalized: realityChecks(first: 1000, skip: ${lastPageUpdated*1000}, where: {deadline_gt: ${timestampLastUpdated}, dispute: null, deadline_lt: ${timestampNew}, moderationInfo_: {askedBy: "${botaddress}"}}) { id + deadline timestampLastUpdated currentAnswer timeServed @@ -615,12 +694,13 @@ return `{ } realityQuestionAnsweredNotFinalized: realityChecks(first: 1000, skip: ${lastPageUpdated*1000}, where: {deadline_gt: ${timestampNew}, dispute: null, timestampLastUpdated_gt: ${timestampLastUpdated}, timestampLastUpdated_lt: ${timestampNew}, moderationInfo_: {askedBy: "${botaddress}"}}) { id - currentAnswer timestampLastUpdated + currentAnswer ${moderationInfo} } sheriffs: jannies(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastUpdatedSheriff_gt: ${timestampLastUpdated}, timestampLastUpdatedSheriff_lt: ${timestampNew}, group_: {botAddress: "${botaddress}"}}) { id + timestampLastUpdatedSheriff group{ groupID } @@ -632,6 +712,7 @@ return `{ } deputySheriffs: jannies(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampLastUpdatedDeputySheriff_gt: ${timestampLastUpdated}, timestampLastUpdatedDeputySheriff_lt: ${timestampNew}, group_: {botAddress: "${botaddress}"}}) { id + timestampLastUpdatedDeputySheriff group{ groupID } @@ -643,6 +724,7 @@ return `{ } ranks: userHistories(first: 1000, skip: ${lastPageUpdated*1000}, where: {timestampStatusUpdated_gt: ${timestampLastUpdated}, timestampStatusUpdated_lt: ${timestampNew}, group_: {botAddress: "${botaddress}", platform: "Telegram"}}) { status + timestampStatusUpdated user{ userID } diff --git a/lib/db.ts b/lib/db.ts index 2c2d16e..9b6361b 100644 --- a/lib/db.ts +++ b/lib/db.ts @@ -21,6 +21,20 @@ const setLang = (db: any, platform: string, groupId: string, lang: string) => { } } +const setWarn = (db: any, platform: string, groupId: string, warnmode: number) => { + try{ + const stmt = db.prepare( + `INSERT INTO groups (platform, group_id, warn_mode) + VALUES (?, ?, ?) + ON CONFLICT(platform, group_id) DO UPDATE SET + warn_mode=?;`); + const info = stmt.run(platform, groupId, warnmode, warnmode); + } catch(err) { + console.log("db error: setWarn"); + console.log(err); + } +} + const joinFederation = (db: any, platform: string, groupId: string, federation_id: string) => { try{ const stmt = db.prepare( @@ -588,8 +602,8 @@ const getGroupsInAndFollowingFederation = (db: any, platform: string, federation } } -const getLocalBanHistory = (db: any, platform: string, userId: string, group_id: string, finalized: boolean) => { - const base = getLocalBanHistoryBase(db, platform, userId, group_id, finalized) +const getLocalBanHistory = (db: any, platform: string, userId: string, group_id: string, finalized: boolean, timestamp_forgiven: number) => { + const base = getLocalBanHistoryBase(db, platform, userId, group_id, finalized, timestamp_forgiven) if (!base) return []; @@ -606,14 +620,14 @@ const getLocalBanHistory = (db: any, platform: string, userId: string, group_id: return [base, banLevel1, banLevel2] } -const getLocalBanHistoryBase = (db: any, platform: string, userId: string, group_id: string, finalized: boolean) => { +const getLocalBanHistoryBase = (db: any, platform: string, userId: string, group_id: string, finalized: boolean, timestamp_forgiven: number) => { try{ const stmt = db.prepare(` SELECT question_id, timestamp_active, timestamp_finalized, timestamp_report as timestamp FROM reports - WHERE platform = ? AND user_id = ? ${finalized? 'AND finalized = 1': ''} AND active = 1 AND group_id = ? + WHERE platform = ? AND user_id = ? ${finalized? 'AND finalized = 1': ''} AND active = 1 AND timestamp_msg > ? AND group_id = ? ORDER BY timestamp_report ASC`) - return stmt.get(platform, userId, group_id); + return stmt.get(platform, userId, timestamp_forgiven, group_id); } catch (err){ console.log("db error: getLocalBanHistoryBase" + err); } @@ -632,8 +646,8 @@ const getLocalBanHistoryInduction = (db: any, platform: string, userId: string, } } -const getFederatedBanHistory = (db: any, platform: string, userId: string, federation_id: string, finalized: boolean) => { - const base = getFederatedBanHistoryBase(db, platform, userId, federation_id, finalized) +const getFederatedBanHistory = (db: any, platform: string, userId: string, federation_id: string, finalized: boolean, timestamp_forgiven: number) => { + const base = getFederatedBanHistoryBase(db, platform, userId, federation_id, finalized, timestamp_forgiven) if (!base) return []; @@ -651,7 +665,7 @@ const getFederatedBanHistory = (db: any, platform: string, userId: string, feder return [base, banLevel1, banLevel2] } -const getFederatedBanHistoryBase = (db: any, platform: string, userId: string, federation_id: string, finalized: boolean) => { +const getFederatedBanHistoryBase = (db: any, platform: string, userId: string, federation_id: string, finalized: boolean, timestamp_forgiven: number) => { try{ /* SELECT question_id, timestamp_active, timestamp_report as timestamp @@ -661,13 +675,13 @@ const getFederatedBanHistoryBase = (db: any, platform: string, userId: string, f const stmt = db.prepare(` SELECT question_id, timestamp_active, timestamp_finalized, timestamp_report as timestamp FROM reports - WHERE platform = ? AND user_id = ? ${finalized? 'AND finalized = 1': ''} AND active = 1 AND group_id IN ( + WHERE platform = ? AND user_id = ? ${finalized? 'AND finalized = 1': ''} AND active = 1 AND timestamp_msg > ? AND group_id IN ( SELECT group_id FROM groups WHERE federation_id = ? AND platform = ? ) order by timestamp_report asc;`); - return stmt.get(platform, userId, federation_id, platform); + return stmt.get(platform, userId, timestamp_forgiven, federation_id, platform); } catch (err){ console.log("db error: getFederatedBanHistoryBase" + err); } @@ -690,8 +704,8 @@ const getFederatedBanHistoryInduction = (db: any, platform: string, userId: stri } } -const getFederatedFollowingBanHistory = (db: any, platform: string, userId: string, group_id: string, federation_id: string, finalized: boolean) => { - const base = getFederatedFollowingBanHistoryBase(db, platform, userId, group_id, federation_id, finalized) +const getFederatedFollowingBanHistory = (db: any, platform: string, userId: string, group_id: string, federation_id: string, finalized: boolean, timestamp_forgiven: number) => { + const base = getFederatedFollowingBanHistoryBase(db, platform, userId, group_id, federation_id, finalized, timestamp_forgiven) if (!base) return []; @@ -708,18 +722,18 @@ const getFederatedFollowingBanHistory = (db: any, platform: string, userId: stri return [base, banLevel1, banLevel2] } -const getFederatedFollowingBanHistoryBase = (db: any, platform: string, userId: string, group_id: string, federation_id: string, finalized: boolean) => { +const getFederatedFollowingBanHistoryBase = (db: any, platform: string, userId: string, group_id: string, federation_id: string, finalized: boolean, timestamp_forgiven: number) => { try{ const stmt = db.prepare(` SELECT question_id, timestamp_active, timestamp_finalized, timestamp_report as timestamp FROM reports - WHERE platform = ? AND user_id = ? ${finalized? 'AND finalized = 1': ''} AND active = 1 AND (group_id = ? OR group_id IN ( + WHERE platform = ? AND user_id = ? ${finalized? 'AND finalized = 1': ''} AND active = 1 AND timestamp_msg > ? AND (group_id = ? OR group_id IN ( SELECT group_id FROM groups WHERE federation_id = ? AND platform = ? )) order by timestamp_report asc;`); - return stmt.get(platform, userId, group_id, federation_id, platform); + return stmt.get(platform, userId, timestamp_forgiven, group_id, federation_id, platform); } catch (err){ console.log("db error: getFederatedBanHistoryBase" + err); } @@ -838,6 +852,16 @@ const getLang = (db:any, platform: string, groupId: string): string => { } } +const getWarn = (db:any, platform: string, groupId: string): number => { + try{ + const stmt = db.prepare('SELECT warn_mode FROM groups WHERE platform = ? AND group_id = ?'); + return stmt.get(platform, groupId)?.warn_mode || 0; + } catch(err){ + console.log("db error: getWarn"); + console.log(err); + } +} + const getReportMessageTimestampAndActive = (db:any, question_id: string): {timestamp_report: number, active: number, timestamp_msg: number} | undefined => { try{ const stmt = db.prepare('SELECT timestamp_msg, active, timestamp_report FROM reports WHERE question_id = ?'); @@ -870,6 +894,31 @@ const setRules = (db:any, platform: string, groupId: string, rules: string, time } } +const getForgiveness = (db:any, platform: string, groupId: string, userId: string): any => { + try{ + const stmt = db.prepare(` + SELECT * FROM forgiveness + WHERE platform = ? AND group_id = ? AND user_id = ?`); + return stmt.get(platform, groupId, userId)?.timestamp || 0; + } catch(err){ + console.log("db error: getForgiveness " + err); + } +} + +const setForgiveness = (db:any, platform: string, groupId: string, userId: string, timestamp: number) => { + try{ + const stmt = db.prepare( + `INSERT INTO forgiveness (platform, group_id, user_id, timestamp) + VALUES (?, ?, ?, ?) + ON CONFLICT(platform, group_id, user_id) DO UPDATE SET + timestamp=?;`); + const info = stmt.run(platform, groupId, userId, timestamp, timestamp); + } catch(err) { + console.log("db error: setRules"); + console.log(err); + } +} + const setRulesCustom = (db:any, platform: string, groupId: string, rules: string, timestamp: number, msg_id: string) => { try{ const stmt = db.prepare( @@ -895,7 +944,6 @@ const getRule = (db:any, platform: string, groupId: string, timestamp: number): } } - const addReport = ( db: any, questionId: string, @@ -953,6 +1001,8 @@ export { getInviteURL, existsQuestionId, setInviteURL, + getWarn, + setWarn, getInviteURLChannel, setInviteURLChannel, getThreadIDWelcome, @@ -986,6 +1036,8 @@ export { setFederationInviteURLChannel, getChannelID, getActiveReportsInfo, + setForgiveness, + getForgiveness, leaveFederation, getGroupFederation, getFederationChannel, diff --git a/lib/telegram/assets/langNew.json b/lib/telegram/assets/langNew.json index e3d9542..45acdbf 100644 --- a/lib/telegram/assets/langNew.json +++ b/lib/telegram/assets/langNew.json @@ -1,6 +1,11 @@ { "en":{ "answer": "answer", + "apologize": "I'm sorry", + "warnConfirm": "Warning limit set.", + "warn": "Select a warn limit", + "forgive": "The user is forgiven, all bans and mutes are lifted.", + "forgiven": "The user was forgiven for messages sent before ", "reputation": { "sheriff": "There's a new sheriff in town", "deputy": "There's a new deputy sheriff in town", @@ -216,6 +221,11 @@ }, "es":{ "answer": "respuesta", + "apologize": "Lo siento", + "warn": "Seleccione un límite de advertencia", + "warnConfirm": "Límite de advertencia establecido.", + "forgiven": "El usuario fue perdonado por los mensajes enviados antes de", + "forgive": "El usuario es perdonado, todos los bans y mutes son levantados.", "reputation": { "sheriff": "Hay un nuevo sheriff en la ciudad", "deputy": "Hay un nuevo ayudante del sheriff en la ciudad", @@ -261,32 +271,32 @@ }, "getAccount": "Bot dirección", "info": { - "evidence": "¿De qué usuario trata el informe?", - "noevidence": "No hay informes a los que añadir evidencia en tu grupo.", - "get": "Obtener información del informe", - "DM": "DM mí para información de informe : )", + "evidence": "¿De qué usuario trata la denuncia?", + "noevidence": "No hay denuncias a los que añadir evidencia en tu grupo.", + "get": "Obtener información sobre la denuncia", + "DM": "DM para información de denuncia : )", "report1": "rompió las reglas al menos", "report2": "vece(s) y está prohibido hasta que", - "fed": "Informes federales para " + "fed": "Denuncias federales para " }, "captcha": { "on": "Captcha está activado.", "off": "Captcha está desactivado." }, "getReports" :{ - "noReports": "No hay informes", + "noReports": "No hay denuncias", "broke": "rompió las reglas.", "nobreak": "no rompió las reglas.", "reportFinal": "final", "reportCurrent": "actual", - "noActiveReports": "No hay informes de respuesta activos.", - "specificUser": "Para encontrar todos los informes de un usuario concreto, responde a su mensaje con `/info`.", - "reportMessage": "Informes con respuesta activa", + "noActiveReports": "No hay denuncias de respuesta activos.", + "specificUser": "Para encontrar todos las denuncias de un usuario concreto, responde a su mensaje con `/info`.", + "reportMessage": "denuncias con respuesta activa", "reportMessage1": "denunciado por mensaje enviado", "reportMessage2": "backup", - "reportMessage3": "Informe", + "reportMessage3": "Denuncia", "reportMessage4": "respuesta actual", - "ReportsFor": "Informes locales contestados para" + "ReportsFor": "Denuncias locales contestados para" }, "rules" : "La conducta de los usuarios se modera de acuerdo con las siguientes [reglas]", "rulesUpdated" : "Normas [actualizadas]", @@ -338,13 +348,13 @@ "setrules": "`/setrules` debe utilizarse en respuesta a un mensaje o seguido de una URL." }, "report": { - "expired": "Vive y deja vivir. Este mensaje es de hace más de una semana. La próxima vez intenta hacer el informe antes.", + "expired": "Vive y deja vivir. Este mensaje es de hace más de una semana. La próxima vez intenta hacer el denuncia antes.", "anon": "El usuario es anónimo. Pide a los administradores que deshabiliten los administradores anónimos para moderar el comportamiento de los administradores.", "bot": "Los bots no pueden ser denunciados.", - "admin": "Los informes de administración están desactivados. Los informes de administración pueden activarse con `/adminreportable`.", + "admin": "Las denuncia de administración están desactivados. Las denuncias de administración pueden activarse con `/adminreportable`.", "reported": "El mensaje ya está [reportado]", "norules": "No se han encontrado reglas para este mensaje.", - "noallowance": "Ha agotado su asignación diaria de informes." + "noallowance": "Ha agotado su asignación diaria de denuncia." }, "socialConsensus" : { "confirm": "confirmar", @@ -370,7 +380,7 @@ "already": "Ya comenzó." }, "welcome": { - "welcome": "Hola, soy Susie, un bot [Kleros Moderate](https://kleros.io/moderate/). Necesito permiso de un administrador para /start. ¿Cómo puedo ayudar con la moderación?\n\n 1. Pregunto\n\n'¿Un usuario ha infringido las normas?'n\n\nen la plataforma de crowdsourcing [Reality.Eth](https://realityeth.github.io/).\n2. La pregunta se responde con un juego de escalada usando xDai en [Gnosis Chain](https://www.gnosis.io/).\n3. La respuesta se puede disputar en el tribunal [Kleros](https://kleros.io/).\n\nPara saber más, [DM](https://t.me/SusieTheKlerosModeratorBot?start=help) mío, lee mis [docs](https://kleros.gitbook.io/docs/products/moderate/susie), o haz una pregunta en @SusieSupport." + "welcome": "Hola, soy Susie, un bot [Kleros Moderate](https://kleros.io/moderate/). Necesito permiso de un administrador para /start. ¿Cómo puedo ayudar con la moderación?\n\n 1. Pregunto\n\n'¿Un usuario ha infringido las normas?'n\n\nen la plataforma de crowdsourcing [Reality.Eth](https://realityeth.github.io/).\n2. La pregunta se responde con un juego de escalada usando xDai en [Gnosis Chain](https://www.gnosis.io/).\n3. La respuesta se puede disputar en el tribunal [Kleros](https://kleros.io/).\n\nPara saber más, [DM](https://t.me/SusieTheKlerosModeratorBot?start=help), lee mis [docs](https://kleros.gitbook.io/docs/products/moderate/susie), o haz una pregunta en @SusieSupport." }, "defaultRules": "https://ipfs.kleros.io/ipfs/QmSHAjfD1MYPtyopFoXcUQ5Ny3sfs5re1yz3h3TZ5qGDsp/Kleros%20Moderate%20Normas%20comunitarias.pdf", "help": { @@ -382,10 +392,10 @@ "Language1": "🗣️ *Idiomas* 🗣️\n\nLas respuestas de Susie pueden cambiarse a uno de los siguientes idiomas.\n\n- EN (English)\n- ES (Español)\n\nLa moderación de contenidos requiere una comprensión matizada del contexto y del lenguaje. Por favor, asegúrese de establecer el idioma apropiado para su comunidad para una moderación efectiva. \n\n*Comandos de administración*:\n`/lang`: Establezca su idioma preferido.", "Topics1": "ℹ️ *Temas* ℹ️\n\nLos temas permiten a los grandes grupos centrar el debate en chats dedicados a **temas**. Susie es compatible con los temas. Cuando cambie un grupo a modo de tema, necesitará /iniciar Susie de nuevo.\n\n*Comandos de administrador*:\n- `/start`: Inicia el modo por temas.", "Evidence1": "🔍 *Evidencia* 🔍\n\nPara evitar que se borren mensajes importantes, de forma preventiva, se pueden guardar mensajes como evidencia.\n\n*Comandos de usuario*:\n- `/evidence` : Guarda el mensaje como evidencia.", - "Report1": "🚨 *Informe* 🚨 \n\nLos informes crean preguntas de moderación de contenidos en la plataforma de crowdsourcing Reality.Eth preguntando,\n\n'¿el usuario infringió las normas?'\n\nLa pregunta puede responderse sí/no con un bono (1 xDAI). Las respuestas pueden ser impugnadas en el tribunal Kleros.\n\nLos informes exitosos resultan en sanciones escalonadas (1 día, 1 semana, 1 año de prohibición).\n\n*Comandos de usuario*:\n- `/report` : Informa del mensaje.\n- `/info`: Devuelve los informes activos.n\n*Comandos de administrador*:\n-`/adminreportable` Activa la posibilidad de informar de los administradores.\n- `/trial` Activa el modo de prueba en el que los usuarios no son penalizados.", + "Report1": "🚨 *Denuncia* 🚨 \n\nLas denuncias crean preguntas de moderación de contenidos en la plataforma de crowdsourcing Reality.Eth preguntando,\n\n'¿el usuario infringió las normas?'\n\nLa pregunta puede responderse sí/no con un bono (1 xDAI). Las respuestas pueden ser impugnadas en el tribunal Kleros.\n\nLas denuncias exitosos resultan en sanciones escalonadas (1 día, 1 semana, 1 año de prohibición).\n\n*Comandos de usuario*:\n- `/report` : Informa del mensaje.\n- `/info`: Devuelve las denuncias activos.n\n*Comandos de administrador*:\n-`/adminreportable` Activa la posibilidad de informar de los administradores.\n- `/trial` Activa el modo de prueba en el que los usuarios no son penalizados.", "Rules1": "📄 *Reglas* 📄\n\nTodos los grupos empiezan con [reglas por defecto](https://ipfs.kleros.io/ipfs/QmSHAjfD1MYPtyopFoXcUQ5Ny3sfs5re1yz3h3TZ5qGDsp/Kleros%20Moderate%20Normas%20comunitarias.pdf). \n\n***Consejos para la redacción de reglas***:\n\n -Enuncie la cultura del grupo en un preámbulo.\n -Numere cada regla.\nSea específico.\n\n*Comandos de usuario*:\n-`/rules`: Devuelve las reglas.\n*Comandos de administrador*:\n- `/setrules` o : Establece las reglas a la url o mensaje.", "Court1": "⚖️ *Corte* ⚖️\n\nLas preguntas de moderación las resuelve el [Kleros Court](https://kleros.gitbook.io/docs/) con un jurado de moderadores. Si el jurado cometió un error, el caso puede ser apelado, atrayendo a un grupo más grande de miembros del jurado y proporcionando la oportunidad de proporcionar más contexto, análisis y argumentos.\n\nSi desea tener la oportunidad de servir como miembro del jurado, obtenga PNK ([Gnosis Chain](https://swapr.eth.link/#/swap?chainId=100) o [Mainnet](https://app.uniswap.org/#/swap?outputCurrency=0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d&inputCurrency=ETH)) y [stake](https://court.kleros.io/) en el tribunal de Kleros.\n\nPara discutir el fondo de una disputa, consulte @klerosjuror.", - "Lawyer1": "🧑‍⚖️ *Busque un abogado* 🧑‍⚖️ \n\nLas disputas sobre informes pueden ser complicadas.\n\nSi necesita ayuda para defender su caso ante el tribunal kleros, considere pedir ayuda a un [abogado] kleros(https://t.me/+9fvGGkGfSZ1hZDBk).", + "Lawyer1": "🧑‍⚖️ *Busque un abogado* 🧑‍⚖️ \n\nLas disputas sobre denuncias pueden ser complicadas.\n\nSi necesita ayuda para defender su caso ante el tribunal kleros, considere pedir ayuda a un [abogado] kleros(https://t.me/+9fvGGkGfSZ1hZDBk).", "Privacy1": "🕵️ *Privacidad* 🕵️\n\nPara proporcionar contexto, los usuarios pueden solicitar a Susie que guarde mensajes para presentarlos como evidencia en su nombre. Susie gestiona la moderación de grupos privados y públicos de forma diferente,\n\n- *** Grupos Privados ***: Los moderadores dependen únicamente de las evidencia presentadas\n\n- *** Grupos Públicos ***: Los moderadores tienen acceso a todo el historial del chat público.", "Notifications1": "🔔 *Notificaciones* 🔔\n\nLas notificaciones pueden enviarse a un canal independiente para no saturar el grupo principal.\n\nCómo habilitar canales de notificación:\n\n1. Crea un canal\n2. Añade a Susie\n3. Susie enviará un ID de canal\n4. Utiliza ese ID de canal para establecer notificaciones con /setchannel en el grupo original\n\n*Comandos de usuario*:\n- `/notificaciones`: Devuelve el canal de notificaciones actual\n*Comandos de administrador*:\n- `/setchannel` : Establece el canal de notificaciones en el id de canal especificado\n- `/setfedchannel` : Establece el canal de notificaciones para su federación en el id de canal especificado", "Federations1": "🌐 *Federaciones*\n\nModerar un solo grupo es difícil, ¿pero gestionar varios lo es aún más? ¿Tienes que bloquear manualmente a los spammers en todos tus grupos? Con las federaciones, Susie puede aplicar una prohibición a un usuario en todos los grupos federados.\n\n*Comandos de usuario*:\n- `/fedinfo`: Devuelve la federación actual: Crea una federación- `/joinfed`: Une el grupo actual a una federación", diff --git a/lib/telegram/commands/forgive.ts b/lib/telegram/commands/forgive.ts new file mode 100644 index 0000000..1d2bcf9 --- /dev/null +++ b/lib/telegram/commands/forgive.ts @@ -0,0 +1,55 @@ +import * as TelegramBot from "node-telegram-bot-api"; +import {setForgiveness} from "../../db"; +import { groupSettings } from "../../../types"; +import langJson from "../assets/langNew.json"; + +/* + * /report + */ +const regexp = /^\/forgive\s?(.+)?/ +const NodeCache = require( "node-cache" ); +const myCacheGarbageCollection = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); + +var myBot; +var myQueue; + +myCacheGarbageCollection.on("expired",function(key,value){ + myQueue.add(async () => {try{await myBot.deleteMessage(value, key)}catch{}}); + }); +const callback = async (queue: any, db:any, settings: groupSettings, bot: any, botId: number, msg: any, match: string[]) => { + try{ + if (!myBot) + myBot = bot + if (!myQueue) + myQueue = queue + if (!msg.reply_to_message) { + const resp = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].error.reply, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + return val}catch{}}); + if (!resp) + return + myCacheGarbageCollection.set(resp.message_id, msg.chat.id) + return; + } + const channelUserSusie = await queue.add(async () => {try{const val = await bot.getChatMember(msg.chat.id, botId) + return val}catch(e){console.log(e)}}); + if(!channelUserSusie) + return + + const forgivenUser = String(msg.reply_to_message.from.id); + const currentTimeMs = Math.floor(Date.now()/1000); + setForgiveness(db, 'telegram', String(msg.chat.id), forgivenUser,currentTimeMs) + const permissions = await queue.add(async () => {try{const val = (await bot.getChat(msg.chat.id)).permissions + return val}catch (e){console.log(e)}}) + console.log(permissions) + if(!permissions) + return + queue.add(async () => {try{await bot.restrictChatMember(msg.chat.id, msg.reply_to_message.from.id, permissions)}catch{}}); + queue.add(async () => {try{await bot.unbanChatMember(msg.chat.id, msg.reply_to_message.from.id, {only_if_banned: true})}catch (e){console.log(e)}}); + queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, langJson[settings.lang].forgive, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {}) + return val}catch{}}); + } catch(e){ + console.log(e) + } +} + +export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/commands/getReports.ts b/lib/telegram/commands/getReports.ts index 31f9864..a40e4d1 100644 --- a/lib/telegram/commands/getReports.ts +++ b/lib/telegram/commands/getReports.ts @@ -1,7 +1,7 @@ import * as TelegramBot from "node-telegram-bot-api"; const escape = require('markdown-escape') import langJson from "../assets/langNew.json"; -import {getReportsUserInfo ,getActiveReportsInfo,getReportsUserInfoFederation, getInviteURL,getLocalBanHistory, getFederatedBanHistory, getFederatedFollowingBanHistory, getTitle} from "../../db"; +import {getReportsUserInfo ,getActiveReportsInfo,getForgiveness, getReportsUserInfoFederation, getInviteURL,getLocalBanHistory, getFederatedBanHistory, getFederatedFollowingBanHistory, getTitle} from "../../db"; import { groupSettings } from "../../../types"; const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); @@ -72,7 +72,8 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, return; if(user_id){ - const banHistory = federation_id? (msg.text.length > 55 ? getFederatedFollowingBanHistory(db,'telegram',user_id,group_id,federation_id,false) : getFederatedBanHistory(db, 'telegram',user_id,federation_id,false)): getLocalBanHistory(db,'telegram',user_id,group_id,false) + const timestamp_forgiven = getForgiveness(db, 'telegram',group_id, user_id) + const banHistory = federation_id? (msg.text.length > 55 ? getFederatedFollowingBanHistory(db,'telegram',user_id,group_id,federation_id,false,timestamp_forgiven) : getFederatedBanHistory(db, 'telegram',user_id,federation_id,false,timestamp_forgiven)): getLocalBanHistory(db,'telegram',user_id,group_id,false,timestamp_forgiven) const reports = getReportsUserInfo(db, 'telegram', group_id, user_id); const user = await queue.add(async () => {try{const val = await bot.getChatMember(group_id, user_id) return val}catch{}}) diff --git a/lib/telegram/commands/report.ts b/lib/telegram/commands/report.ts index 135d0a9..a8fffd9 100644 --- a/lib/telegram/commands/report.ts +++ b/lib/telegram/commands/report.ts @@ -1,5 +1,5 @@ import * as TelegramBot from "node-telegram-bot-api"; -import {setInviteURL, getInviteURL, getRule,getAllowance, setAllowance, addReport, getRecordCount, getQuestionId} from "../../db"; +import {setInviteURL,getInviteURL, getRule,getAllowance, setAllowance, addReport, getRecordCount, getQuestionId, getForgiveness} from "../../db"; import { groupSettings } from "../../../types"; import {upload} from "./addEvidence" import {reportUser} from "../../bot-core"; @@ -55,6 +55,13 @@ const callback = async (queue: any, db:any, settings: groupSettings, bot: any, b return; } + const forgiveness = getForgiveness(db,'telegram', String(msg.chat.id),String(msg.reply_to_message.from.id)) + const msg_date = new Date(forgiveness*1000).toUTCString() + if (forgiveness > msg.reply_to_message.date){ + queue.add(async () => {try{await bot.sendMessage(msg.chat.id, langJson[settings.lang].forgiven+msg_date, msg.chat.is_forum? {message_thread_id: msg.message_thread_id}: {})}catch{}}); + return + } + // WHO WATCHES THE WATCHMEN?? // can't ban bots if (msg.reply_to_message.from.is_bot){ @@ -246,7 +253,7 @@ const reportMsg = async (queue: any, settings: groupSettings, db: any, bot: any, if (settings.lang === "en") queue.add(async () => {try{bot.sendMessage(settings.channelID, `[${fromUsername}](tg://user?id=${reportedUserID})'s conduct due to this [message](${msgLink}) ([backup](${msgBackup})) is reported for breaking the [rules](${rules}).\n\nDid *${fromUsername}* break the rules? The [question](${appealUrl}) can be answered with a minimum bond of 1 DAI. Need assistance answering the question? [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpgnosis) me for help : )\n\nTo save a record, reply to messages you want saved with \`/evidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: settings.thread_id_notifications , parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); else if (settings.lang === "es") - queue.add(async () => {try{bot.sendMessage(settings.channelID, `La conducta de [${fromUsername}](tg://user?id=${reportedUserID}) a este [mensaje](${msgLink}) ([backup](${msgBackup})) es denunciada por infringir las [reglas](${rules}).\n\nHa infringido el usuario *${fromUsername}* las reglas? La [pregunta](${appealUrl}) puede responderse con un bono mínimo de 1 DAI. Necesitas ayuda para responder a la pregunta? [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpgnosis) me para obetener ayuda : )\n\nPara guardar un mensaje, responda a los mensajes que desee guardar con \`/evidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: settings.thread_id_notifications , parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); + queue.add(async () => {try{bot.sendMessage(settings.channelID, `La conducta de [${fromUsername}](tg://user?id=${reportedUserID}) a este [mensaje](${msgLink}) ([backup](${msgBackup})) es denunciada por infringir las [reglas](${rules}).\n\nHa infringido el usuario *${fromUsername}* las reglas? La [pregunta](${appealUrl}) puede responderse con un bono mínimo de 1 DAI. Necesitas ayuda para responder a la pregunta? [DM](https://t.me/${process.env.BOT_USERNAME}?start=helpgnosis) para obetener ayuda : )\n\nPara guardar un mensaje, responda a los mensajes que desee guardar con \`/evidence ${evidenceIndex}\``, msg.chat.is_forum? {message_thread_id: settings.thread_id_notifications , parse_mode: 'Markdown'}: {parse_mode: 'Markdown'})}catch{}}); return [appealUrl, evidenceIndex]; } catch (e) { console.log(e); diff --git a/lib/telegram/commands/setWarnmode.ts b/lib/telegram/commands/setWarnmode.ts new file mode 100644 index 0000000..b54ba26 --- /dev/null +++ b/lib/telegram/commands/setWarnmode.ts @@ -0,0 +1,60 @@ +import * as TelegramBot from "node-telegram-bot-api"; +import langJson from "../assets/langNew.json"; +import { groupSettings } from "../../../types"; +/* + * /warnmode ? + */ +const regexp = /^\/warnmode/ + +const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { + const opts = msg.chat.is_forum? { + message_thread_id: msg.message_thread_id, + parse_mode: 'Markdown', + reply_markup: { + inline_keyboard: [ + [ + { + text: '1', + callback_data: `7|${msg.from.id}|1` + }, + { + text: '2', + callback_data: `7|${msg.from.id}|2` + }, + { + text: '3', + callback_data: `7|${msg.from.id}`+'|3' + } + ] + ] + } + }: { + parse_mode: 'Markdown', + reply_markup: { + inline_keyboard: [ + [ + { + text: '0', + callback_data: `7|${msg.from.id}|0` + }, + { + text: '1', + callback_data: `7|${msg.from.id}|1` + }, + { + text: '2', + callback_data: `7|${msg.from.id}|2` + }, + { + text: '3', + callback_data: `7|${msg.from.id}`+'|3' + } + ] + ] + } + } + console.log('yo') + queue.add(async () => {try{await bot.sendMessage(msg.chat.id,langJson[settings.lang].warn,opts)}catch(e){console.log(e)}}) +} + +export {regexp, callback}; \ No newline at end of file diff --git a/lib/telegram/index.ts b/lib/telegram/index.ts index e2e6978..053cb5e 100644 --- a/lib/telegram/index.ts +++ b/lib/telegram/index.ts @@ -5,6 +5,7 @@ import * as setRulesCommand from "../../lib/telegram/commands/setRules"; import * as getRules from "../../lib/telegram/commands/getRules"; import * as getLeaderboard from "../../lib/telegram/commands/getLeaderboard"; import * as addEvidenceHelp from "../../lib/telegram/commands/addEvidenceHelp"; +import * as forgive from "../../lib/telegram/commands/forgive"; import * as report from "../../lib/telegram/commands/report"; import * as fedinfo from "../../lib/telegram/commands/fedinfo"; import * as welcome from "../../lib/telegram/commands/welcome"; @@ -22,13 +23,14 @@ import * as newFed from "../../lib/telegram/commands/newfed"; import * as joinFed from "../../lib/telegram/commands/joinfed"; import * as start from "../../lib/telegram/commands/start"; import * as setLanguage from "../../lib/telegram/commands/setLanguage"; +import * as setWarnmode from "../../lib/telegram/commands/setWarnmode"; import * as setChannel from "../../lib/telegram/commands/setChannel"; import * as setChannelFed from "../../lib/telegram/commands/setChannelFed"; import * as getChannel from "../../lib/telegram/commands/getChannel"; import * as getReports from "../../lib/telegram/commands/getReports"; import langJson from "./assets/langNew.json"; import {groupSettings, groupSettingsUnderspecified} from "../../types"; -import {openDb, getGroupSettings, getRule, getReportsUserInfoActive,getFederatedBanHistory, getFederatedFollowingBanHistory, getLocalBanHistory, eraseThreadID} from "../db"; +import {openDb, getGroupSettings, getForgiveness, setWarn, getWarn, getRule, getReportsUserInfoActive,getFederatedBanHistory, getFederatedFollowingBanHistory, getLocalBanHistory, eraseThreadID} from "../db"; const Web3 = require('web3') const {default: PQueue} = require('p-queue'); const queue = new PQueue({intervalCap: 20, interval: 1000,carryoverConcurrencyCount: true}); @@ -55,7 +57,7 @@ const batchedSend = _batchedSend( federation_id_following: '' } const ModeratorBot = require('node-telegram-bot-api'); -const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: {params: {"allowed_updates": JSON.stringify(["my_chat_member","message","callback_query", "new_chat_members"])}}, testEnvironment: false}); +const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: {params: {"allowed_updates": JSON.stringify(["my_chat_member","message","callback_query", "new_chat_members"])}}, testEnvironment: true}); //const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: true, testEnvironment: true}); //bot. @@ -152,67 +154,19 @@ bot.on("chat_member", async function (msg: any) { }) */ + bot.on("new_chat_members", async function (chatMemberUpdated: any) { if(!chatMemberUpdated.new_chat_member?.id) return; console.log(chatMemberUpdated) if(!hasStarted(chatMemberUpdated.chat.id)||throttled(chatMemberUpdated.new_chat_member?.id)||chatMemberUpdated.chat.type !== "supergroup") return; - - console.log('hmmm1') - const settings = validate(chatMemberUpdated.chat); - console.log('hmmm2') - let calculateHistory = [] - if (settings.federation_id) - calculateHistory = getFederatedBanHistory(db, 'telegram', String(chatMemberUpdated.new_chat_member.id),settings.federation_id,true) - else if (settings.federation_id_following) - calculateHistory = getFederatedFollowingBanHistory(db, 'telegram', String(chatMemberUpdated.new_chat_member.id),String(chatMemberUpdated.chat.id),settings.federation_id_following,true) - else - calculateHistory = getLocalBanHistory(db, 'telegram', String(chatMemberUpdated.new_chat_member.id),String(chatMemberUpdated.chat.id),true) - - console.log('wtf') - console.log(calculateHistory) - - // todo notify groups about federal outlaws when enforcement is false - - if (calculateHistory.length > 0){ - var max_timestamp = 0 - for (const ban of calculateHistory){ - if (ban.timestamp_finalized > max_timestamp) - max_timestamp = ban.timestamp_finalized - } - const parole_time = calcPenalty(calculateHistory.length, max_timestamp) - if (settings.enforcement && parole_time*1000 > Date.now()){ - queue.add(async () => {try{await bot.banChatMember(chatMemberUpdated.chat.id, chatMemberUpdated.new_chat_member.id, {until_date: parole_time})}catch{}}) - return - } - } - - let calculateHistoryActive = [] - if (settings.federation_id) - calculateHistoryActive = getFederatedBanHistory(db, 'telegram', String(chatMemberUpdated.new_chat_member.id),settings.federation_id,false) - else if (settings.federation_id_following) - calculateHistoryActive = getFederatedFollowingBanHistory(db, 'telegram', String(chatMemberUpdated.new_chat_member.id),String(chatMemberUpdated.chat.id),settings.federation_id_following,false) - else - calculateHistoryActive = getLocalBanHistory(db, 'telegram', String(chatMemberUpdated.new_chat_member.id),String(chatMemberUpdated.chat.id),false) - - console.log('wtf') - console.log(calculateHistoryActive) - - if (calculateHistoryActive.length > 0){ - var max_timestamp = 0 - for (const ban of calculateHistoryActive){ - if (ban.timestamp_active > max_timestamp) - max_timestamp = ban.timestamp_active - } - const parole_time = calcPenalty(calculateHistoryActive.length, max_timestamp) - if (settings.enforcement && parole_time > Date.now()){ - const options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false, until_date: parole_time}; - queue.add(async () => {try{await bot.restrictChatMember(chatMemberUpdated.chat.id, chatMemberUpdated.new_chat_member.id, options)}catch{}}) - return; - } - } + const settings = validate(chatMemberUpdated.chat); + const penalized = checkHistory(chatMemberUpdated.chat, chatMemberUpdated.new_chat_member?.id) + // no captcha or greeting replay for penalized users, means they already joined once before. + if(penalized) + return if(settings.captcha || settings.greeting_mode) greeting.callback(db, queue, bot, settings, chatMemberUpdated); }); @@ -272,12 +226,14 @@ bot.on('callback_query', async function onCallbackQuery(callbackQuery: TelegramB console.log(callbackQuery.from.id) if (callbackQuery.from.id !== Number(calldata[1])) return; + const penalized = checkHistory(callbackQuery.message.chat, callbackQuery.from.id) const permissions = await queue.add(async () => {try{const val = (await bot.getChat(callbackQuery.message.chat.id)).permissions return val}catch (e){console.log(e)}}) console.log(permissions) if(!permissions) return - queue.add(async () => {try{await bot.restrictChatMember(callbackQuery.message.chat.id, callbackQuery.from.id, permissions)}catch{}}); + if (!penalized) + queue.add(async () => {try{await bot.restrictChatMember(callbackQuery.message.chat.id, callbackQuery.from.id, permissions)}catch{}}); queue.add(async () => {try{await bot.deleteMessage(callbackQuery.message.chat.id, callbackQuery.message.message_id)}catch{}}) } else if (Number(calldata[0]) === 6){ const member = await queue.add(async () => {try{const val = await bot.getChatMember(callbackQuery.message.chat.id, callbackQuery.from.id) @@ -288,8 +244,17 @@ bot.on('callback_query', async function onCallbackQuery(callbackQuery: TelegramB queue.add(async () => {try{await bot.deleteMessage(callbackQuery.message.chat.id, callbackQuery.message.message_id)}catch{}}) start.callback(queue, db, settings,bot,String(botId),callbackQuery.message,[],batchedSend, true) } + } else if (Number(calldata[0]) === 7){ + console.log(callbackQuery.from.id) + console.log(Number(calldata[1])) + if (callbackQuery.from.id !== Number(calldata[1])) + return; + setWarn(db, 'telegram', String(callbackQuery.message.chat.id), Number(calldata[2])) + queue.add(async () => {try{await bot.deleteMessage(callbackQuery.message.chat.id, callbackQuery.message.message_id)}catch{}}) + queue.add(async () => {try{await bot.sendMessage(callbackQuery.message.chat.id,langJson[settings.lang].warnConfirm)}catch(e){console.log(e)}}) + } - }); +}); const commands: {regexp: RegExp, callback: any}[] = [ getAccount, @@ -303,6 +268,7 @@ const commands: {regexp: RegExp, callback: any}[] = [ toggleCaptcha, help, newFed, + forgive, getChannel, toggleAdminReportable, leaveFed, @@ -313,9 +279,10 @@ const commands: {regexp: RegExp, callback: any}[] = [ addEvidence, getReports, setLanguage, + setWarnmode ]; -const adminOnlyCommands = [joinFed, toggleEnforce, multilang, leaveFed, newFed, toggleCaptcha, setLanguage, setChannelFed, setChannel, toggleWelcome, toggleAdminReportable, start, setRulesCommand ] +const adminOnlyCommands = [joinFed, setWarnmode, forgive, toggleEnforce, multilang, leaveFed, newFed, toggleCaptcha, setLanguage, setChannelFed, setChannel, toggleWelcome, toggleAdminReportable, start, setRulesCommand ] const settingUpateCommands = [setLanguage, toggleEnforce, setRulesCommand, joinFed, setChannel, toggleWelcome, toggleCaptcha, toggleAdminReportable] commands.forEach((command) => { @@ -476,4 +443,64 @@ const checkMigration = async (groupSettings: groupSettings, chat: any): Promise< return groupSettings } + +const checkHistory = (chat: TelegramBot.Chat, userid: number): boolean => { + + const timestamp_forgiven = getForgiveness(db, 'telegram',String(chat.id), String(userid)) + const warnings = getWarn(db,'telegram',String(chat.id)) + console.log('hmmm1') + const settings = validate(chat); + console.log('hmmm2') + let calculateHistory = [] + if (settings.federation_id) + calculateHistory = getFederatedBanHistory(db, 'telegram', String(userid),settings.federation_id,true,timestamp_forgiven) + else if (settings.federation_id_following) + calculateHistory = getFederatedFollowingBanHistory(db, 'telegram', String(userid),String(chat.id),settings.federation_id_following,true,timestamp_forgiven) + else + calculateHistory = getLocalBanHistory(db, 'telegram', String(userid),String(chat.id),true,timestamp_forgiven) + + // todo notify groups about federal outlaws when enforcement is false + let ban_level = Math.max(calculateHistory.length - warnings, 0) + + if (ban_level > 0){ + var max_timestamp = 0 + for (const ban of calculateHistory){ + if (ban.timestamp_finalized > max_timestamp) + max_timestamp = ban.timestamp_finalized + } + const parole_time = calcPenalty(ban_level, max_timestamp) + if (settings.enforcement && parole_time*1000 > Date.now()){ + queue.add(async () => {try{await bot.banChatMember(chat.id, userid, {until_date: parole_time})}catch{}}) + return true + } + } + + let calculateHistoryActive = [] + if (settings.federation_id) + calculateHistoryActive = getFederatedBanHistory(db, 'telegram', String(userid),settings.federation_id,false,timestamp_forgiven) + else if (settings.federation_id_following) + calculateHistoryActive = getFederatedFollowingBanHistory(db, 'telegram', String(userid),String(chat.id),settings.federation_id_following,false,timestamp_forgiven) + else + calculateHistoryActive = getLocalBanHistory(db, 'telegram', String(userid),String(chat.id),false,timestamp_forgiven) + + console.log('wtf') + console.log(calculateHistoryActive) + ban_level = Math.max(calculateHistoryActive.length - warnings, 0) + if (ban_level > 0){ + var max_timestamp = 0 + for (const ban of calculateHistoryActive){ + if (ban.timestamp_active > max_timestamp) + max_timestamp = ban.timestamp_active + } + const parole_time = calcPenalty(ban_level, max_timestamp) + if (settings.enforcement && parole_time > Date.now()){ + const options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false, until_date: parole_time}; + queue.add(async () => {try{await bot.restrictChatMember(chat.id, userid, options)}catch{}}) + return true; + } + } + if (calculateHistoryActive.length > 0) + return true +} + console.log('Telegram bot ready...'); \ No newline at end of file From d7ddb5d3c66cfe77d8cd49a2613a13f1e0148f24 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Fri, 10 Feb 2023 14:26:01 +0000 Subject: [PATCH 070/111] fix: turn off test env --- lib/cron.ts | 2 +- lib/telegram/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/cron.ts b/lib/cron.ts index bd8e129..a87340e 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -11,7 +11,7 @@ const ModeratorBot = require('node-telegram-bot-api'); const Web3 = require('web3') const realitio_bot = require('./realitioReporting') const db = openDb(); -const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: false, testEnvironment: true}); +const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: false, testEnvironment: false}); const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCount: true}); // Only need DB for // - channelID diff --git a/lib/telegram/index.ts b/lib/telegram/index.ts index 053cb5e..6586ef3 100644 --- a/lib/telegram/index.ts +++ b/lib/telegram/index.ts @@ -57,7 +57,7 @@ const batchedSend = _batchedSend( federation_id_following: '' } const ModeratorBot = require('node-telegram-bot-api'); -const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: {params: {"allowed_updates": JSON.stringify(["my_chat_member","message","callback_query", "new_chat_members"])}}, testEnvironment: true}); +const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: {params: {"allowed_updates": JSON.stringify(["my_chat_member","message","callback_query", "new_chat_members"])}}, testEnvironment: false}); //const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: true, testEnvironment: true}); //bot. From db1bee33f4722c4cf249e03451a077a904791ac5 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Fri, 10 Feb 2023 14:27:31 +0000 Subject: [PATCH 071/111] fix: thread warnings --- lib/telegram/commands/setWarnmode.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/telegram/commands/setWarnmode.ts b/lib/telegram/commands/setWarnmode.ts index b54ba26..cc01b77 100644 --- a/lib/telegram/commands/setWarnmode.ts +++ b/lib/telegram/commands/setWarnmode.ts @@ -13,6 +13,10 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, reply_markup: { inline_keyboard: [ [ + { + text: '0', + callback_data: `7|${msg.from.id}|0` + }, { text: '1', callback_data: `7|${msg.from.id}|1` From c27a7da9d1973db24a3336039eba958f0e105e76 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Fri, 10 Feb 2023 14:32:10 +0000 Subject: [PATCH 072/111] fix: lang format --- lib/telegram/assets/langNew.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/telegram/assets/langNew.json b/lib/telegram/assets/langNew.json index 45acdbf..58e6c90 100644 --- a/lib/telegram/assets/langNew.json +++ b/lib/telegram/assets/langNew.json @@ -273,8 +273,8 @@ "info": { "evidence": "¿De qué usuario trata la denuncia?", "noevidence": "No hay denuncias a los que añadir evidencia en tu grupo.", - "get": "Obtener información sobre la denuncia", - "DM": "DM para información de denuncia : )", + "get": "DM : )", + "DM": "DM para información sobre la denuncia : )", "report1": "rompió las reglas al menos", "report2": "vece(s) y está prohibido hasta que", "fed": "Denuncias federales para " From a716bedb03d73f3822d74f71ce7dd3489886a3d2 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Fri, 10 Feb 2023 15:17:52 +0000 Subject: [PATCH 073/111] fix: rules format --- lib/telegram/commands/getRules.ts | 2 +- lib/telegram/commands/greeting.ts | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/telegram/commands/getRules.ts b/lib/telegram/commands/getRules.ts index 63d2f5a..a1ee904 100644 --- a/lib/telegram/commands/getRules.ts +++ b/lib/telegram/commands/getRules.ts @@ -25,7 +25,7 @@ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, if (ruleObj?.msg_id){ const MsgLink = 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + ruleObj.msg_id; console.log(MsgLink) - msgresponse = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].rules}(${MsgLink}).`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id, disable_web_page_preview: false}:{parse_mode: "Markdown", disable_web_page_preview: false}) + msgresponse = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, `${langJson[settings.lang].rules}(${MsgLink}) ([backup](${settings.rules})).`,msg.chat.is_forum? {parse_mode: "Markdown", message_thread_id: msg.message_thread_id, disable_web_page_preview: false}:{parse_mode: "Markdown", disable_web_page_preview: false}) return val}catch{}}); if(!msgresponse) return; diff --git a/lib/telegram/commands/greeting.ts b/lib/telegram/commands/greeting.ts index 1afdc87..3e01800 100644 --- a/lib/telegram/commands/greeting.ts +++ b/lib/telegram/commands/greeting.ts @@ -1,7 +1,7 @@ import * as TelegramBot from "node-telegram-bot-api"; import langJson from "../assets/langNew.json"; import {groupSettings} from "../../../types"; -import {getMultilangGroup} from "../../db" +import {getMultilangGroup, getRule} from "../../db" const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 90, checkperiod: 120 } ); @@ -58,14 +58,17 @@ const callback = async (db: any, queue: any, bot: any, settings: groupSettings, ] } }; + const ruleObj = getRule(db,'telegram', String(msg.chat.id),Math.floor(Date.now()/1000)) + const MsgLink = ruleObj? 'https://t.me/c/' + String(msg.chat.id).substring(4) + '/' + ruleObj.msg_id : ''; const new_member_name = (msg.new_chat_member?.username || msg.new_chat_member?.first_name || `no-username-set`); - const msg_greeting_full = `${langJson[settings.lang].greeting.greeting0} [${new_member_name}](tg://user?id=${msg.new_chat_member?.id}). ${msg_greeting}${langJson[settings.lang].greeting.greeting1}(${settings.rules}). ${langJson[settings.lang].greeting.greeting2}` + const msg_greeting_full = `${langJson[settings.lang].greeting.greeting0} [${new_member_name}](tg://user?id=${msg.new_chat_member?.id}). ${msg_greeting}${langJson[settings.lang].greeting.greeting1}(${MsgLink}) ([backup](${settings.rules})). ${langJson[settings.lang].greeting.greeting2}` console.log('full') - console.log(msg_greeting_full) let msg_welcome; + + if(settings.captcha){ const options = {can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_pin_messages: false}; - queue.add(async () => {try{await bot.restrictChatMember(msg.chat.id, msg.new_chat_member?.id, options)}catch (e){console.log(e)}}); + queue.add(async () => {try{await bot.restrictChatMember(msg.chat.id, msg.new_chat_member?.id, options)}catch (e){console.log(e)}}); msg_welcome = await queue.add(async () => {try{const val = await bot.sendMessage(msg.chat.id, msg_greeting_full, msg.chat.is_forum? optsThread: opts) return val}catch(e){console.log(e)}}); } else if (settings.greeting_mode){ From da97becb993301c8cfe7838bb315429ebc7719a7 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Fri, 10 Feb 2023 15:28:34 +0000 Subject: [PATCH 074/111] fix: regex strict --- lib/telegram/commands/addEvidence.ts | 2 +- lib/telegram/commands/getChannel.ts | 2 +- lib/telegram/commands/getReports.ts | 2 +- lib/telegram/commands/getRules.ts | 2 +- lib/telegram/commands/help.ts | 2 +- lib/telegram/commands/report.ts | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/telegram/commands/addEvidence.ts b/lib/telegram/commands/addEvidence.ts index 1ddd24f..cc37856 100644 --- a/lib/telegram/commands/addEvidence.ts +++ b/lib/telegram/commands/addEvidence.ts @@ -262,7 +262,7 @@ const submitEvidence = async (batchedSend: any, evidencePath: string, questionId /* * /evidence [questionId] */ -const regexp = /\/evidence/ +const regexp = /^\/evidence/ const regexpFull = /\/evidence (.+)/ const regexpFullReason = /\/evidence (.+) (.+)/ diff --git a/lib/telegram/commands/getChannel.ts b/lib/telegram/commands/getChannel.ts index fc016f3..c6a75c6 100644 --- a/lib/telegram/commands/getChannel.ts +++ b/lib/telegram/commands/getChannel.ts @@ -13,7 +13,7 @@ myCache.on("expired",function(key,value){ /* * /notifications */ -const regexp = /\/notifications/ +const regexp = /^\/notifications/ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { if (!myBot) diff --git a/lib/telegram/commands/getReports.ts b/lib/telegram/commands/getReports.ts index a40e4d1..36d2201 100644 --- a/lib/telegram/commands/getReports.ts +++ b/lib/telegram/commands/getReports.ts @@ -13,7 +13,7 @@ myCache.on("expired",function(key,value){ /* * /getreports */ -const regexp = /\/info/ +const regexp = /^\/info/ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botid: number, msg: any) => { if (!myBot) myBot = bot diff --git a/lib/telegram/commands/getRules.ts b/lib/telegram/commands/getRules.ts index a1ee904..ee5c14c 100644 --- a/lib/telegram/commands/getRules.ts +++ b/lib/telegram/commands/getRules.ts @@ -13,7 +13,7 @@ myCache.on("expired",function(key,value){ /* * /rules */ -const regexp = /\/rules/ +const regexp = /^\/rules/ const callback = async (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { if (!myBot) diff --git a/lib/telegram/commands/help.ts b/lib/telegram/commands/help.ts index 81b77f7..b7967a4 100644 --- a/lib/telegram/commands/help.ts +++ b/lib/telegram/commands/help.ts @@ -5,7 +5,7 @@ import { groupSettings } from "../../../types"; /* * /help */ -const regexp = /\/help/ +const regexp = /^\/help/ const helpgnosis = (queue: any, db: any, settings: groupSettings, bot: any, botId: number, msg: any) => { const lang_code = msg?.from?.language_code diff --git a/lib/telegram/commands/report.ts b/lib/telegram/commands/report.ts index a8fffd9..2041866 100644 --- a/lib/telegram/commands/report.ts +++ b/lib/telegram/commands/report.ts @@ -8,7 +8,7 @@ import langJson from "../assets/langNew.json"; /* * /report */ -const regexp = /\/report\s?(.+)?/ +const regexp = /^\/report\s?(.+)?/ // cacheIndex => groupID,reported message id => [pending report message id] const NodeCache = require( "node-cache" ); const myCache = new NodeCache( { stdTTL: 900, checkperiod: 1200 } ); From 42a25bf7b4cea4b73428934b960fcd055900a064 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Fri, 10 Feb 2023 17:07:30 +0000 Subject: [PATCH 075/111] fix: table consistency --- lib/db.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/db.ts b/lib/db.ts index 9b6361b..9f86ab4 100644 --- a/lib/db.ts +++ b/lib/db.ts @@ -897,7 +897,7 @@ const setRules = (db:any, platform: string, groupId: string, rules: string, time const getForgiveness = (db:any, platform: string, groupId: string, userId: string): any => { try{ const stmt = db.prepare(` - SELECT * FROM forgiveness + SELECT * FROM forgivness WHERE platform = ? AND group_id = ? AND user_id = ?`); return stmt.get(platform, groupId, userId)?.timestamp || 0; } catch(err){ @@ -908,7 +908,7 @@ const getForgiveness = (db:any, platform: string, groupId: string, userId: strin const setForgiveness = (db:any, platform: string, groupId: string, userId: string, timestamp: number) => { try{ const stmt = db.prepare( - `INSERT INTO forgiveness (platform, group_id, user_id, timestamp) + `INSERT INTO forgivness (platform, group_id, user_id, timestamp) VALUES (?, ?, ?, ?) ON CONFLICT(platform, group_id, user_id) DO UPDATE SET timestamp=?;`); From 7b18756933ddebd5646f9f7bd42eddff6e56a620 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Fri, 10 Feb 2023 17:45:39 +0000 Subject: [PATCH 076/111] fix: cron bug --- lib/cron.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/cron.ts b/lib/cron.ts index a87340e..7f88803 100644 --- a/lib/cron.ts +++ b/lib/cron.ts @@ -11,7 +11,7 @@ const ModeratorBot = require('node-telegram-bot-api'); const Web3 = require('web3') const realitio_bot = require('./realitioReporting') const db = openDb(); -const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: false, testEnvironment: false}); +const bot: any = new ModeratorBot(process.env.BOT_TOKEN, {polling: false, testEnvironment: true}); const queue = new PQueue({intervalCap: 10, interval: 1000,carryoverConcurrencyCount: true}); // Only need DB for // - channelID @@ -559,7 +559,7 @@ const handleTelegramUpdate = async (db: any, bot: any, settings: groupSettings, return val}catch(e){console.log(e)}}); } } - else if (!finalize && ban_level_current <= warnings){ + else if (!finalize && ban_level_current <= warnings && warnings != 0){ // no optimistic warning } else if (restrict){ From 619b863c9a641d6ee06d4b70c70d452638ec8501 Mon Sep 17 00:00:00 2001 From: shotaronowhere Date: Tue, 1 Aug 2023 18:32:29 +0100 Subject: [PATCH 077/111] fix: small bug --- lib/telegram/assets/langNew.json | 2 +- package.json | 12 ++++----- ...55tica de resoluci\303\263n de dudas .pdf" | Bin 0 -> 898618 bytes subgraph/subgraph.yaml | 24 +++++++++--------- 4 files changed, 18 insertions(+), 20 deletions(-) create mode 100644 "rules/Kleros Moderate x Reality.eth Oracle - Pol\303\255tica de resoluci\303\263n de dudas .pdf" diff --git a/lib/telegram/assets/langNew.json b/lib/telegram/assets/langNew.json index 58e6c90..d298fcf 100644 --- a/lib/telegram/assets/langNew.json +++ b/lib/telegram/assets/langNew.json @@ -14,7 +14,7 @@ "NeighborhoodWatch": "🤝 ***Neighborhood Watch Recognition*** 🤝\n\n The Neighborhood Watch recognition is given to members who help protect their community. Thank you for your service 🙏" }, "notifications": { - "getfed": "The notifications for this group's federation are sent to this [channel]", + "getFed": "The notifications for this group's federation are sent to this [channel]", "notset": "Notifications channel for this group is not set. Ask an admin to `/setchannel`", "get": "I send moderation notifications to this [channel]", "set": "/setchannel must be followed by a channel id. If you need more help, ", diff --git a/package.json b/package.json index 10f89a1..065d762 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "@graphprotocol/graph-cli": "^0.25.1", "@graphprotocol/graph-ts": "^0.27.0", "@types/node-telegram-bot-api": "^0.57.1", - "better-sqlite3": "^7.6.2", + "better-sqlite3": "^8.4.0", "cache-manager": "^5.1.3", "dotenv": "^10.0.0", "ethers": "^5.5.2", @@ -22,8 +22,6 @@ "function-batch": "^1.1.2", "p-queue": "^6.6.2", "pm2": "^5.2.0", - "sqlite": "^4.0.23", - "sqlite3": "^5.0.2", "web3": "^1.8.1", "urbit-ob": "^5.0.1" }, @@ -44,10 +42,10 @@ "typechain:build": "npx typechain --target ethers-v5 --out-dir lib/typechain lib/abi/*.json", "graph:codegen": "cd subgraph && graph codegen", "graph:build": "cd subgraph && graph build", - "graph:deploy": "cd subgraph && graph deploy --node https://api.thegraph.com/deploy/ rodsouto/telegram-moderator-bot", - "graph:create-local": "cd subgraph && graph create --node http://localhost:8020/ rodsouto/telegram-moderator-bot", - "graph:remove-local": "cd subgraph && graph remove --node http://localhost:8020/ rodsouto/telegram-moderator-bot", - "graph:deploy-local": "cd subgraph && graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 rodsouto/telegram-moderator-bot", + "graph:deploy": "cd subgraph && graph deploy --node https://api.thegraph.com/deploy/ shotaronowhere/kleros-moderate-gnosis-chain", + "graph:create-local": "cd subgraph && graph create --node http://localhost:8020/ shotaronowhere/kleros-moderate-gnosis-chain", + "graph:remove-local": "cd subgraph && graph remove --node http://localhost:8020/ shotaronowhere/kleros-moderate-gnosis-chain", + "graph:deploy-local": "cd subgraph && graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 shotaronowhere/kleros-moderate-gnosis-chain", "pm2:start": "pm2 start ecosystem.config.js", "pm2:stop-all": "pm2 stop all", "pm2:delete-all": "pm2 delete all", diff --git "a/rules/Kleros Moderate x Reality.eth Oracle - Pol\303\255tica de resoluci\303\263n de dudas .pdf" "b/rules/Kleros Moderate x Reality.eth Oracle - Pol\303\255tica de resoluci\303\263n de dudas .pdf" new file mode 100644 index 0000000000000000000000000000000000000000..8fb38f66feb118b920be4687a2bf67242831168c GIT binary patch literal 898618 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%0AO69rOwp2=^+VyJA!^B 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%0At#XMb+=>l;_)E4YHCV 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 z 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

    N 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

  • 5b%FFH)%yf#q;A@g(+^L=cR)k)5G<>S;!JczYdjM0j!p= zpx@2$tVND8{85KTw3pO)%5*hg;E6h4GdbMhtoRAgFHR>Mbzs+87LchHp z*dd7ePfFAo0SdA(wYy}k*pmi{l77r#&E=26cr^G37K9Z3 zdqwUlHaO%}O#mB|6_??Aa)*ntzjKW83yh^=5zzT4pyU1L!>2H-dX_!)bpc2~!16sf zYt9IzT1t5Yq0>{#IgD)pUbpo6(H3M~<@D(ZwE)JGj)7`Q*uR6s_pG_6eO+h^^cE@T^`6{Hggbx zpKq0=B_=7_LQYdmjWEtOtO1B4RrZui48IdYV{ad)z9ts*&9GMs2S#O z*HUii+jCY$OxCtcMyKb8BfU9k5*;dtYuB3?*ZW9#g|X49W6?T%*nw~A)_hoiy;`@0 zjH4RWPE3D#88c2VSb1`Ulc635U(643_qLRet4#)MuJ9=A(co`M!nkL7L~dbkcZsXh zh>K8bvS>ij+jy}C^lX9d0axCS`QwxNQ>k0Ia&R9%FqjhZIokp@rTN~|aXauSp6)N< zcdzjwn9XddYZ$2)pfMnH(az@u^C37jqEvFAK+ylq=k#czaABfyBS7DKK)BPqI3;)BZt)pMmst_^SY= zLGp9w@Rxt6Q8xs}e39WfjIPr?LU1S01!V1MLVt7Hwqph~a_kPsuPWDPMacV#Ar5?6 z|3$!`|11C*nbL6a{_>aCm?$yrtz#~tqHuO*8qr1!7MK{Q2BkvEHrapU?VCt6d%?)j zTd06p0%Poj62-oMuPZ+b{Tg+#mS*^VOE^08_^0{w_>j5z)%oYh!m%5irRk z`mb0z5MJ0qGk)JH5N`GF|5S~si;0qK*kz+?C@=1oOwfVwKk0?6R?Ca;6OtFaY< zOy>g7;{l6xF;VWeJTwM8xfY|-Dcjdqcc1OhU((CIv`GL;N@Yl`;mS;5_w=sRgb~!R z`2BIgxNPR)ojrewmXgK($uBLfRQ+iflo^&fv`fm#X;$|;T0>qoNl>8IQ5vthyR8;4 zo52EGQnM|k^~b69h3)ob%=4vbK?*DF)0N*zl!>SMQY=fTbs3e6)9IsyC5ic=kh9H7 zLdH@9on`?34*pRBwfaS7HHfx2F>;j(e`(^kOx&K9)b%4$rt8z=c})(aT&l4&@=M4~ zhKsi3ANhH!hr@i9C1B^~7qQ&F@q=QaAw?nLI9FBz?j8q>lUVuIZ&^GTHknMw9T!fd za@Ho*dHC${5YF~WziO$sr#Gh(S-jemdYHcb=YCVo`c4IK;rNrVUyr{M2_k66yNYnx z^?U_6Kf6fbmw0Kcf4sGVYEfirrKu^l{KmUIuy!}NOhzQ4_nva=@?GI)uDoB~R=sFe z+~1*KI*{ZQe}o0>W9$4(3KM@mJ^$?~2nve@kk^Nz?|dRtUeB6#xP+}9`*hCz)$86l zppx{b5j{c6xqtXZ=;`I^RQkE&bdywNsoRz>WIHc7;Q zfJ8zMEuZU|O_3^?i0kyvB{8f6_QB@IA{tH>0gtw#Lmv_^fn;c_#7_J##AS*c)uL;h zXsZK;I+5T##Fq+R11QG~nq`=5=w$0k{6@eMp&Fb8lqGvRppwb6y}oy^&1l+3b^5vH z6X)|XNf>jzh|*yHN&TP#7j@t#NTf!dZSy3*5Rt<1(JNZLCTAaU54=x#u4@JCMr1QQd}t&*-Ixd|O&<|ZCw$E((@pW+SYS}tM)VkB znPC9CP$R^g6y>Tfs2Cd)YL@5kl+yH z6`_-;B@s4JTD*SN(Fob(9 zK>RO&e3jwH1!4cZvzy|Gg0Rf^K+Vn3ETiERy2u~^36+3|2;ZZkagqMnm?=3(c9;AN zQd{rf7R{J5KW60$9vS!i2H~9$Aw^c1K>_&HGiQI5!kxLn1?JvNu04t{h!15GG8l=P zTfiLF$vIHgqlIZde?NF7gmGLr>>Y?=YYbVE_q?jt5{48>*=qsm$`Po3edejAW?o0U52{s?b6naz{Gu`9?$X zi^)y>=8;Z^F_2+M_%GeoZ53foz#sRZTeUDQu;wbVXvlHf4xt;90>t)Ler0+Ehf|cU z`yArs7@Yj|BEG@xK&i~MshPIyK8C{J2cZpJ#n;xCthI5`;~=aTm^Ms84Lm)hnyA`a z%4C5nT8|=RL8q?)=BwWszvjFPQiC?Q9YQWpXM8SUxora%#%amWdQ-ww&vDTF4WPT% zxZ{P$z8@S6i@Qc*UE+kQe?|gP+2j-;Tp`!+BG6d#z6MA;jE{h*^oJB-p%UT<$ZHFR z2DNq$j*vLvbB>D5VVcr04vxxe7dDgt3&uqnOFD8#$Gw1(r(Otyig7M}l5gIXK9MZ58L>huRHcWl$45y5Um|s6VsR1becDFy^E_mrtr;du8`xY6~-I)PgwZk8hanZgD`nNXQ>l*5y^*SH3$Zrx?yc}QBSA|?suVdeVaRJ zq23a$i=n(>JTg@T{2*4ER*7qwl1PO08{fagMJ8URUygm8&bKZf5rWHoT=Dah23qc^ z!Z-o5L=ra+078`5c&jH7aRHnEnY$)nB4QYX9of+voQ8}h#o}0~CKgpamDZLvK4?%V zS}Vv*=DO@qpiM!Ig+uwBBMqi9m#4s|q)l_e5E(I35!KppfE)-%9B0d5`v@bjIN1nO zdZz*i(gq#NeroPwa@GzV+djuAs$3R41^WJ~U;GujTlMIR8%8>0z=0-tNi*WYm$a$t zoF(;%;0vQOj9ucN&d?>2uj1<|gUF^vkKb@&c5=R0(>7aC4idrHhaGR3e&t93p|aSO zWL-n^xKgUpqP5zpcz8Yc;0}^#(-aIFy zHfsm5!9paXM0~+tc;bY0X+vI!>`JhRo|B8p2+L0uaPyWo?0;8F@}$Bl z%J7nY`Y9IhGvBSLC>VCyUpfrM$|tlKt;UdI$eQ4uU1i5q(1@T-X5tD(SVKP#$vXpp zSP1sFLfUuK&8J@I<{*{5!Tb77f*(n#Rj3tvJ)_yht%KJNLvRV!Y;k~UBs)R|hm3}1 zicdjD4Ia`m0f2p}Bfw%QsomR308Ptp`{sRL#*$|Jl zD>_I6+7`ue8nR85N)+y280@t*XTqp0{nlyvVyQD~^M$7%-3V8h5)FZ2zarUyuHza> zrwbLbvn?wktx6K37z)>pDx|$FGRIfhw>8+j;)DHdjSuBM*84w#7)=u_F#g(Kctbag z$x0;xoIZA!qE1JYTpBrVdrOIE8ECPJUj%wgxKIL9rT=jNuYww%5g;rqDCAd_nA5Em zFot7-%FHF;`X2Y!*z&NPdjEAPGc@dMWDYh__O|zu4uh6zn0?%P1L_k>_$yQuC(*{J&&+hx;T9>qd;;cEz z^PB=@;4Np+Gs&zC;D3ok=l0J_XhNFIrcN7}y;}*%SjpWdS&eFO9yZi$J3mXhJp(Jjw7=j&Rd0G>L7H^Hnve)3z zbFSs>_;bCVN7>O1k<^$mbL#WtHSscCdO=_bwyQglSmCilEFL(C0^QgFB{ijQB7zWu zF%<8hUgrG%jT?4!{v!w-(NRXI5(U;ScOR9Qs%-VL`%d{14~*2D4|kNlyJ%^+XnnVd zI?xmbU@}$nx#BDwT?Z5e`nCfAlaB5rVDXPXQZWm4F=QrIt9^G2IHuEbhVF@%{xP0z z$QfG>w?I0Au|S-0CK=5o%uUWZFhBg$=BK%Iz;gOj=ZGLZF3|%c3_Da-Wd>|r7e-y5!UT{E%q-s1J zbKFv|^9{h@By5d>Q7tIKXo^aj7g=V~Yi1sbtaZe6?j==+pH{4(i;=}4WS|+K*jHD= z0MC;du?rT!A&t^-yS#QVrp5`4g(3^>@u*0_BrTWLgBX-S{DNRI^&50IM3`OaJ@5)6 zVcp^sL5@j~X<24%_rB{EPQqZe&VdxESl%QPmCue-9d9W+xnPCjFA; zz;W|QtWV&rW3gbSDj}Rsln!=D_d%^8i4>zKMRwa2jhfrwbK84)x|8Pg)s|2 zw2)0vDYP2YpXeHoXJpwFYt%OJ_3I5@xwJ*tsp1yfN?Lq)r6jx{q>zn~C}x%O5kRMK z4~MB0su$8gf%xixfv&3laL04R&wD6^6x~7kxV74*@ER=8(4nfj6tVhGv~y3 z+alOiw_D;qUIu~7k!a?lS9Y_1+0?sv;ZI^bj*z>-%bCGPM-Rl5fb$1VkVJpfq~{7Q zDeay@Zv^#3{0g&*Q+Mh~qpkK%gf~TvvQKCiGw^0GB`(^c8wiDnh+>bvwo+UHMjLN z;|kdJql6|?{2_wN`Yx;hoZ`58CrMBi9D_;12K^b@rN)HB%M>VeK}ZJNa=*H@2g`@X`JM_GZ2HQ+g@wN?Pnb)p5<2D z`c@%eskq^ma&4LX>7StQKU7-wzM1xG5g+0l!3(-Q&^#a|(1nC2FB+5215WC74(-7_ zYUB|^7S#|qPzUU`U`uEfy(PD9`@b~MwpW;(&;$~U5qRl)$iU%ES}cl~&HzVllC%8G z>KWn5-^2`|sE(n3G!Y~8*tIpka5{O{x9in+1pg6CuOIkf{wI|o>h072t0av7zgeaK zEx+Uc^UxPSwWyEke_~5ie!!|HW>>8K2AXz3Y;^mQiTjCB_=)wxf_fg_i@Q7oa5p^x zJzIc`1?l##pQHrmvx5Io%n(3^4Yxmq(Pccz9?2@i#uo}qwiA19cFP6F?b2LqCarec ztv-g8xtUT`xeWeVW9>bl3&|lqRWFq>ko53XhJN7_y3G@WHTvIOg2ol(FUVnmwyTp7 zwb0YQny$lVC+2mB=6!zlM^LTQYH_*h&-8kI7)|GKa?ozDUVE?5;rY^+Pp8`caC@vO z9(i)GEYPAa*@) zeVf}I5wG((&?~E=qN3mH*@w&q=uZ}SceWNd)Va!}(b(uFXS{SA@jUreE>kC4m}Ncu zO85Wb>MNt#T%)C1C{nb=T}p9xcY+jmf);mocP~)f-QC>^l;Z9Zq*!ow0$+xzYTG&s}`wqng5`TuQOI-CjL~5V?xWATSY1cx=O z;Wq~+dxe_muEOnV~nX$ozr|5FK2aZ)IGQNl;UU|+f0bJ~ty5sWbrGP=!Xpi=|C9^YrK;l}|f z^jq!Ms|C%tpZAaLQ%jg2T&-?Ds`2~*DJl*H=-l|1ijanBUoN2hGHRc0Axko`1>Vz? zd~5)uRPmHKLU3gwhwFaZU#=0pNK-l=r0hR^%AxAKlBO#v_hIIldy*|%mvV3===bu5 zIX;>~LJ-PI8d1x=QbuH03C9A1CFdrKCL3L{^s`8BS(+Wm)#^+`lt4-*LL}MK{8E1g zDQUzgj4<^~^8|UmKVNUZ-s*!@fb&K~wx#dGZRazBiJ4i*k(vPzlwglnc^Lb~-Ljt3JK z+_=|c`e$On#{Qgp>dNR#Ge1uGDs@A5$CQ(g&+e@;LkpAAl)d5eLqKA1vGropfaz?( z_wXq80}T9ApHhAmy>ZWaBArhcB^6xuUGl#9 z)&HX$+9eH|Ow8m*MOI`QrpdNA!0yLz_2>B}XB!4jU4qU1AX%KL)!DP7A388yx1Db6 zRH+^HXKI{i4)LSRe9Mz43yWL&>ZC9qg-|IQ4|!_ev9+osQTpgAqmPNG+hb8x0~J|y zn-G`r4^5?@>E&6G`#0-h!EO^H7q5@OOYS)Db*dueXcdS-@Agj2P2VyK=9V#J5$^w9 z9ZfQ$y*ivebwA&e3VD5qg*;cvFzV^)2}5q?xHo-ZOHg}IOMi{j>UVqXjbgK0Umr}7 z@;dD<*Bk3~FgskWwb~EVLVs;`dvoieFM-i>1ifo)7j>cHtCZ=qt0e?kICz`-f_kL! z^`~94#6><&SLmx%pKF0k_O}?-9T<4iN(sOgPodZjh(o!tkJ!=R5c&_J>!S?+44HKijDk#fv$C#M1 z|EpHXDPwfp2V%oRLpxFu@#A^_mAVs%^z?K=m) z0aT${!6l15#R$NH-h`R(cZSf^HH)>VZgKGh9t_tv`;dEloqMw0G#B&UvfdQVf6h!4 zIvN{R%?dZ<2pJ|KgUyyMV^HAMgR)O3FJeo2u)BqrzU2pc77m9}H!u=E-jf1<1Qr$LsyG?9gf;d0n&bb%o}By}-5cKJaQi z87tlJyPpMwKto-9Co(vp$;gZHY;TTpCGy9M)z91Eq+8xPI%_YF*P>g@dL1rzC&0Fn z!b0Pd<@!Ww#W0TBM12w=A4G2b4j0qDg5nk?@qcm%gvN1H2mfSX+j1SarP-c*U*`S1 zq;5^=X}JoDo>-c~FsBMMCcMH{E2mXnKU+D35wA(2<9hEhHx_w7h=h&RULL(D>yC7SSlwplQ==&6~=d3Kv zQpEG5bw_ltvKhlj%aAzJG11y(<@4p3-AZ)v@+qWtZ8ypFvHX9!dIo;!p9Vl?`(8 z6;<=69E;>k3cOOIQxwMq+TkT{NT?S@l5WD#?Lw^&(ULzHrL8SMsk2Uj zCa{0AvDw=vo$E2$qzB-#J^Yc&|M=^(^%kORQ4lvy#0}6$wdM@xL7kg`?E6*BqZ51g zvUtXYF?*~uv~AVoUts7Vbs$S z+xgX2btQ9MQNr*}nA`p4y=88Ph4oHVGp3M^-YUuY-~WzwIYUR_;}pbrshL`1|mI;pMiVm z8ZKee5scMU<>xPd-?iNYZ;}Z4eKTwMBo$@Yj0_}0!3XL-QIl%OSJ~*UbVRsuO};w zQgI}GwdPYfI`vN3!JX#@nW<>{6Alg>n*vi$7ut!7m%mf`GI)$C`qi`(7;97f-OE=--DE`JK^q^j zl1kLZ{_JKnEq;{z6L^bih$O;EIS4!g%rUqzwX8S)c2Qv86`L~$RoXx_U6l8w4X+S0 zjR|dgSM1hRWLur5Wp^^8(A;OLZT1!hGfdgZtWRSBCG3PAeSs3VbFF%tHM78FnX2Rvi9E_Urd`_Qn62 z9h-@+EQ@!Sb(q5ZB%{@Fi!zg`ycogJMQ z;!s@G@a}BZnw^_RdW8c=8;=exo+uOUFM~Xg~g|% zIooMgYYevXq~;{_&yt-%8J=cAuEp;=hw!BzW`Iu0B$H#G#1=2GV+8SVXQ1>5GCF&X zN+pm*enzVp_>9lN+(n1-+V&MEi%9IY>S}*91#U+>6)Pt9qkoH0;+e3C&i$_kW$a`| zy`<{2o}~ zh(jfQjbNL_J{s%D9<9O{vsv0$x;%kPc#qdKPw2~^$H!l9PfU@A4AUtw_iG?de;Nd5 zEGZ#XSK)LW(v~Ej6Wc7WTS#m4{4chkxzLLK{!b__Pa|WgivD~vu68Shs?L7B&f90% zI?&|es+uYqCOYl9?|p}J)P281S2e5kd|&35hT@1edQGpx2BUGtpM4gqfb<$wJf2tc z&@53V{Vr&%Fx<4$&ud&0rB~iIzL%$e;!53LeSo(fItTgw`8uu`mG28%cpLRPec!h+ ztxd&Q9*D5dun_6Jo3@;`u>=GT_7oot&WQ}7MmXXJCt0PmrZeV#gv#FPFiL(0yZ3Qs zV6$_MnQNcv8TA-4l~I7!ktTzf#IVR1i2?DMK|7Ji>4 z+RHE#eTcQ}d1`^d3c_Ec8st%P|65u0X9+tk3q?NYY+`Ouo{I`W4$lbz1XqPtr7~f+ z3kV^+GJR>Y7#_PDcY|JLTQCbRBUeXaEvcm}{ONKQo4xBsJ47O#?vaBfQ^lt3DBjdG z@av|0r60SJv>*-mW|>0aYkk7oCu?Iqw!ODAt}O>{VmSRFco}k>A(TZrYe53R=xaIa z>xJO&ElQ4w>8QKH1pK(7mW(aTAss&(-@lr$7}Q|knk8uaG%wm5!&o>+S0h)USG%<} zq|$UCN9H^X6skE>14*>XYne@uYM2R;-Ei3+I7PtZjW&$>=zByo z!gSKm*{0Lzk)o=)LY zmdr8!jkaQrzT>^PMU`v)HHtd0oz>%8o1T$X;e1EkAP7@R4`O^}txd0kbFsH?l-#`f z2Uc!lkeRN!Xd5b7;6nQ>IwhJv+mL7GW$Ekv%OSe}`Y+i5->nLp_Tjj{X+e6duu6vM zX?onA5+ZY}?J^q4>0DieD_=yR`2h4?KH{1+K=;ePd(d7D8c3RklAFkSa}bvcjqDlN zsHrV=B`$~6^uGd6R_FRX9SxJSTtgw9{y+3Y3?Y=d=$0$VClzY67|}$q=z$yLhaYzFrlmet3W0 zOo?q_-ON)xo`o@R?^w36Zbn`Lci39CDz;{>D$~^DSUN+^21Vbhz8=;m8JFnSor5Nq z`ijA-G4yh&GHc@DmS?ROgFIq6u+;f>Bv&J$xNWLT>s5%!FUp?j+PwKvn|x?N32~Q?WW+Ca+$#h_lwGEsGUs$`Cv9N$Lg*>s4qar|a;%@|I+nE(GR>eDD`-!U$`*At z!3L;KPQ$lrw=S?KZA`8ZjnEwuC1O2%JcKAI;S2*Ids1S~F!Obym>0`Rq#IS>O4mm2 z&9Kj)9+hU>lE%WMw^g)j;%(7qZNWQYs$>X&ksZ5EtMTQm?Ho_NOADqu*ZUR}%^M@B zO<3_e1e3tT)dIDR{x^&l-~b+OdR|-o`NQ#mb$(>tOMlYms1CMImQYO;krBc$Oie3a z&wB~&q(r3lO0)U3oDC%9cQky~Wz03jpL{??Zq*U^t)e(C7J>-qdXGMfD`h3jY4;kpc$f&IHp98;=# zLBX^f{l8W5tIV2WOwbOzKi=`@=il;fxc6ypa`1uS7BCsH5s(#PvZGIzmqrvoyE9*n zMyqTHnOdA2trH2(;XY|%nkJ~h!CK2msLS<1vM5C{2jLt~VIy7}ce8B1V0DoaTF&;k z?dpt}tC~TU;x=cWSzt__8`ZNP)fx3gKgMos(}p&?vZsVo?e-DIE1Dold#hQo?t(vm z($wXL-C%_=ZafhPhGx``QoCX;PC8tZ3T@f9|I4$AvOIi~HScY~_7Wxu&}|;RR!uUaS2rZAou8wm|CO&D`IsU;`rbMFNiNT*^n z73al3;PbQ+{r2K_Fy0tVpOck-`?qf)l{x2UwvK+!yBiGj-q(Y@G5*bL;pyqNl|Qbq zQZ31)%cfS4+mLt30>%0Xc!f%lYmVD`$myq3}2JNlOPJg|D|ReHROw*iHH(kp3XY>!gS#pM4#Dfr6QtO_SP=zI zPN=(R1vGN8!Rx$z??2IMk?JWnToA&;C`#VORl#m^urM7#ZRy}+rBl>U9wJ>3=xE<*M4+P>G} ztl=)_tiWeX)VYWJ3CxW#pQk_i)+se34s+;+mh!AAa`|gKoMq$<4v*_D;jf&M%fhb0OWW@i$ zpc|}n|1#_6RXH+$X;LfQk_K&_km0UdUyQJY9X;X-2IxN&yaV}Ew05DhR2u^3;xA=L)=L3531LBwbD|TsnsnpY{ZcsN+TBo%?17p>*mvD~{d^RHctO`o zE)Sgm*%hPaZgc5{Bsf-l%8R=_!b=1|I3e=T#I&M3Zl;!036|LRPk5;i^ltxu#tOs2 zzc)2qa^x`aQi0sYmTsPne-?vRkMr;RE5Lh+2MY=YY#d+vxWDiUl@^$-7OYtJ$_-bm zthF6OXAUmnDhjTqV?of?jJRuHTYPhsk*u<-y~noQUrpOj{#Y2QX%f{{d79Mo7ELA< z@OZbnt}~O{`!F@<%}r|X^mjY`R?&X*1#*~(YvK%m5X_zl;+=y!-5-x@(cQ-dJ6&E^ zD6iutvwCQuhobYGd$xg)|I=Skm;x5*7nlfSg&d)|*;OjdUemV=;m|64H7oF)Le@J2 zN9`_0=VmBW_^ykigDV}?D7w5+3J!dgv_ke1t1^@CoG72rK+s6HPp<{ez(+a+!wzGN zX+|+s(wgzL4_ki|O?VGUHo18{Ms-WQ4}y^! z(skimO5&e_M;eT2kFl|4iql?^?ZN*S@M-xFBe8Ve}6C}_(_a68P)U? zmdIDQj>(S~+|!Jb-+6fOxiwa^R$-zhk#t z*b+o$$dT`q>>D0Z6&7>FhTnaTIZQY-*&i>N8X3Pv?j)-SlJ1k1eU+J!njs%$*=%?R zLkiXfy@?KM@K)t-C~;-Zt%a=6LLZP8H=MPBYrRf`(Fr1vekpYYe7#LH|9(_kdb8R` z7%b2vds|b!ptD?Iv_aGBx3+nDntb2Ao{gv+eUxD~sF;udmPNeNCMm9XE4>-XF4Qo=$T+ zn24TFA8KkynFNo$pv#SXgMP2i*9XEIFPG4OV}vDJ;kLVr*M%WB=EHR^U%P{>*v3wG z(DUu&PU%$6{nw=lYrqnE(Po#Yv;6@sbO1$kiBRPNo6p9^YV763k_{?@QdB-xR_|Nj z_u)&v{Q;~|1sIH2eS?xh@9dXq;D2yW)?rnR@_6M4xqfw}9(FTyY@j?!iR_(SRSm88Pz@*{(ioD8D%>=U- zR-k>R`ytGRt@)18yZv6p#Zat@CRomk^)&4RB?77jW5%CowD4uAT5wPrA{g6E)gfJFxqj9=aaFLi=S2<5Bo==wYy!j zHvJhbICc05s$-wbAu(yOf4k1#~bbAJ8u4uJ9KNUUo!q4)P=M-Mu z6@>evgU`^#3{d}S040=v&a_XneV%Y@%kw6Gr#gIhSufOqCI%ZJs!#tE#Z?lVxV^@8 zUD{Aw^U8XGD_G*GUt77!OSLmtS<#tMjUHM< zM-6P0WB`h&NsjebyXp7Y)MrqtS!Vl;QM-1j&&)|JmEy#hM@mclNwi#t4Nna&px#BD zCuI1y*g2od!B{0qw#SDApRCOe;N0YE3=x51m=7O9;#TWbanVp^KG8M%VnBCLN#{7s zUv7#69ajSE)jB%g9N764r58n7{WJ7u#Q#cK68l1%pCEK2S@X@mtN50M$AU0n;*0I- zqy{tTK6@9x{~1JrpnMf{C|C=5Nmdp1e#|xR)%U+Sjo(DG@pm};ow#Y&>rtM$TQKL& z28666(jU}j^EjMc)SNFiWoc<$E+o`TwM_6kY+b9DF4cDWoULa=M-0NgS60({+(X^1 zCA}V(;2DYtv`K?DCB3!phR2I<8%0quy!ts*)y< zGCaREwK&A3O{#-VhiH!9f=1R#7H)ziIGk%|hq@Ge5M0*S9TxN>y*ka(+mG7wLD?xQ zzFK@r0yhFig4c49np^usXEYj#dhK1sIQTBshSVMhUswHR!>bGiEl7 zxB@~4N)yk+*w9ttXr6pgNiz)x+@T?zPTxQ%^2)n6;U=`^PYLIrTM0cpLi>vv^U*Zy zomAR}JHqQm)a2!5U`xYlFVWY>i}d{+dE1%3pf)>Bg#}R zSmTm^M`yi5l4ihOo$qVv@Iq6*idLlE3U`U{qu?IMw3}Cr_E{oF!lsnR#NSZi2L#+l7ia~)P->Mw!6}aMSSH8 z<)3bkms;)CSQ%&<-nwPB$H3awx1(;>AZ=w!&m0$kzRH>Xc^umVHXgCh_|eXD zq7|pir^-{gUkG)+))J#`SiC`m*rG@XK71+7QZsJ1#|J6_)5!6&;hgNe?MkgSO#DpR z;$wWz_X@hwq@m2oulxC2#gt@|X!ZmsYZ9;b4X3G&NROs_w>meIDJah=IM}t*f6O#F z^r@Y`qJ08I^PZbj?<+n);`97xA}#H-_ZwwEHewsh(Wxfafc_hGmzFeKk^rO<7W9EJcyvy<4;uC?sKex2>sA6+$ymRNZ$pZPiKtTx8n*35(@~ zIRD&c@-&2P%vy5HT6R8KCqI*@#vdAbb9a-MX(?Z_xSF*Af0FAQ9GxgRRh-f0M6ev8$t)cZvuRa7ND1l9!0`0&0M}{`&c`Cbr!cgRXj*XY9&Tjj; z%Ui1xK2575glZQGdsofdY5uEC+PODnm)g9~&?B*191}X)pokrZ8W*|zC1R5|RS9oT zjEhXJ>|c+J;8R>RJ|qRqgol;}JbJ_bN#&jhjeB@Xrx$>ctdpQK-z2c7~lJ{hKX8rfKFvwDkp7+IrVXY;Tm#lwwykF+cKN69@gJb1D zI2+|&(#T1yAm&K61i4f>1X%=hYKlMJDO$vv-`lM}(vS}HedI_!JS49rHNHMY<3Xc> zuYsFI3^VI7Q_J=IQ1(_c4{jW=rVAEtcvL;Ca zS!JuBl|N`a1#2%3@6#n48sxQ;WD+aAN%o8{4x*So6;Ungufoy|e?&StLjy?=5Yp^k z-fr#6nQLa$|FHov6o3bTd3oOl3r?^aNS}L(pBAFOCwI)eepcez9_G2`JpE){C$MfH z7^NnnYV|?J@u-+x1h~xvGjBIw<7h`Pu})C%u3>vO!4i5L2Xq9Si8YuMpQaI&WbZ)v zOFwE3#5HRg`I5iz4~OPEnN6|Oag-Rep7rrcrclB}A%OG)v793F-Y&r`1%igveFB14 z{}hzBaNyTP359~Gveb#XM=#8*hUM0AqjME7S%fZ`Xq_Ec*UsUmj5RS9iBaWw%)uAcj3e@!e?#yBRB5zhW@;hN+Kf@_U)IN2I$U}K!Hk(t_hX!tg zsEhk!e3pW$_QDQRQNz<8>qjXwx2LD{cQM0EsTH={F<*pAF(y;yeKoY^v^o6t+ZG3* z=q+27ld`x>XU5Vd(%)n?DOAS>1iNB1ClqytnVzM-h?TBlB7)`Xq3x*WB+B?d$1+-W zX}}b}(#_8hqQL&HgEqOHcckSbq0Mgk`yiJ%tQNIe**c#}=fk#tVYVoRM@;MyU2Rru3gFiC7!2 zgBY^H0e&t3T-phkeq*RlhGcI%@=8VVl$Aoie~$3u?TDfjX_k)n+gc%dui)eEbF^Yd zM~<*RQVImal}-db~>zKQ*p7*(rI*DKiSx7_xiLu z(s;mZz)0--`W(GcA7DpDJnHa#cj|Z>LtuU2x2PN!zZjPL$$DL-GH0^@I9s95F=66X z*u;@4IKQUUs)$H~Gv=P=bj7ofMFpi0@_c5Gz9>mq0!aq`km$xA?$V9Oa_1=9ud)LD z->0#pw@oHb@8+4)et&)`Lu6BcDhrB{8 !7pNLDx4d=^UHfk&+S;aYe9kpp0t9W+ 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ÐC=|C$d|}mo@%Ooy%9{mZ&u9l` z#S`$R3hxlu`~a5KWc_70CQ>n-!};-QZoMF42I$sO)AeErio@X;^1Az5YD38Yp&NIi z+}IiaNGD}3JDI6orJ%#>{xQM_aQC$+@6f8`jK*hE@Ln2&+Frq6cgE2x?5g|dq4^`H zQX%~qX4z5asR`I{8d3=Q{K)PO)}{=C9Gu-SVb<@vH9piq3~GPBoc|g;klZu}9yiAk znmYA?HR`K?r;$BX8HT@W(C8F%u@SxfND?sc?;N$1`5OqmoFseH)#xHR*airGP1))- zo_}ALD)Ukm-IF%z^6$y2kHf&O25b`m+3t9K!1RilrXIemswFViD+om&7gs7Y=sD%Y z10ZN{g#^>W7>goQdWKp^^{*rGQ?`ItMbnC~rb4$o#I~5`e0P7Jrwr6XP1V2q!WQQPvpenRkT#-X0S>VC6Rz{_6U{EbDy0lDm_dh?|x0 z0ffiFsAW8LMc`5ywUh+z2T@Dq5Cl9Z?2!xGay|iaHiU;73`nzT6#T8vfk&s)&3g61!7byzuxaKY0R>XZM8qVQ^VOW{p#}A_$720fBv&@KxpWwm_2b z1VG!LE&y<|zDYAjz&DhSa!Y=AQWnDluBzAT9O$?a(cfq$BKm#136B2BfRBTKy6wDn z)Y-2lfTq!nc0a{SW1GDyww`}m>4j{S&FcAs_h%;fgnmnH?MI?`L%xwbl zOTlZH;#VsjxQ)u@Rr+n6S5#58mk$`PzS|r4fkuLx zxvZDax`_lG#B{xsOaxM0HDN@^yAT^LPFx9HbFvmTj3`ZtDiK`^iENazsH5{vFZcDx z@m8djL2`pi1`R&1Q4i1Wwoy2z7moh~c6>0Osrg-Y2P##_l6-V(?Lyqfp|@9>aMOsh$DboXoK> z7(N@82{>&7!}uT0fC*CrFN@R;U|P@N>JmC>Je~~J3OO;~=PBxTFcMu^SjeWp;(@>1 zUy`id`dQ9+aH9v_GdnfZXvQ{4 zz6OH`rsU<6-!!*bWf1rg(Xw@d)TDs%9fU+JZZb*P-fzKz@lLdCWilNwj^J>>Sp$qo ztOgC+#Zw0+r^jze8Er06jz`t#MqMKG^wf_{87-Bqvfm{^>EEBr#@Z4*XJ8sI2vT;p zvrW{MXNWmZO55Em$dzNC&GEG~lbMniN?KOz-3~65oiR7}E(9_S9*k-^PV;!ZX@vZc7)vDh0F>YSf9}A2TVf%d z_`@mvNB~ifj7%{-cVU^k47_W|K`@9ui$dj`e zUSH14BUw`{Qd|ggaa5245q#66Dpa-Ex@!{Xd@GO;5*kMKoswj>YAG^O8Dc%SRw+GC zOk|7MqR@H~=+GCW8g)$WJ7wU5OmEsw1_OBvNbggX)Lcna+KT@ou}w07=73c?d2Ej3 z>TOD)J>gIB^IQuhD?5E$)jL)OsYP5f|vbk ztRRwf`C=ir+k3)*Ht_7R{i;8)43C~x8b1r!(nRyhfm7A4| zg|Jno**Sd93CGpRjcV-J5Ta*jGW9CXKSDQ-mul2JpNnnOY~~L`74?ph3K(@j+bQLX zfx(89yZt!Ko-KceNsif4dYLYgD%Y!JBbASfY!ccYi2evz=%P9!dX!F~OYp2Y0WXC5 z($~&2Gg>9uUpa=h>oA>60xH@dgR6UKmRWmk6>&^V-HrPBs0Fgff5)5xeMx|33qe|d z+VOf96&Xc4a7B_E8H=WjJ%hE~Wd6+1`)BtPr$ck=W99Psaq$Ykg0wLn7r{i}RKGng zR-sIHbm0)wUVx@24wwwh!|;gb1pk(}kB|x-m{~fA2CBfh{5bO~H|&F~Cib$mH$!yu z-9NZeeQDQ17ce&9J*H5;jLB&1N$plJ@EX3Xfsd$SKa^<`B_K%D0TK%`eAkV*t{aW= z%CCAlr>9zk2Lc${3x26%rr$?W7^RbW#m)7*6qm#YEGM03J0RdukO=H(&rzSt2OAB% zhu>>&P-XNqK1$VPl@*GX6m0s3rdPbjk-&BJ#&f-*QYv$^LVjEfT@EL1eA0E`pEONv zicuJ619M%Zhtp;y32S!2;%}VpGq9-*m?n@-EEws9uhH(L(F9EAv`7``V6B7QTE7fh zk)+f9{K@7$d{vbeNW3Yrp*jS~r$#9z|NOE(HCrwqvSDz@_!anC$b?&Q!A-Nf+~QNY zfYOUZGN`K%L%mj?`K-4#5|?4XUZ=M+<43bp#Y63RUV4(SRsdL6nECQ1`%Un3B>dcT z{X4|1HX!v`YGW4uGQxRUG9htxl~8bG0`IR=VOU4^)M-~~NZI;V!C4YjjOwY#v57_h z`g4b7Lvqu|`#p3*y`m&+w$bbS%hcI0`{9wQy4{=6C5W25s?CL)@=MR&_^KP$h4Rt5 z%$ueO^LjwRo> z;=XvcOuzn9T+g#&3@Z+f!i0iU-o5kTVuJ0Iiiv`~tc*ZVj#6SILs&>s@(^Zy2pMT8 zra3jLN{5G~E+L{mLt0+#egHYAVXUQ2$9Ie)nNiLOq)6yG^u7kfMJp?)b=33JSDuEC z!yAA^#d6#<9A|J6BHYk!%EpEcj$omh7GpVqFuB3&fJ^}H2iBM}<8 z?Y7DJ0?Qv`DA{lGy)U$kw~oCDc)Rd27Fej2_Ho{6><-BMC|K>FEH7`FLk=RH!TF-3 z?D!(=BY419qF&JYKfc*^I z{*q+m^T6p9)9!Cdu23&4H~q!uCkPnYB(cQ838>^h<`B<&_U`MC*#Vdy6*bSToBHMM zR5=3B#;Py`e=SdLn9!*Rc&6Lhi6y?R9klf))k7>oZXdFeES^iCCo@pdVv^BHJm zsQl}etykFm(1ahp)T}f>6$itkPY1bFB@**{RvG#pbKzsbT~W2rjRWOL(mjUksmOI>cc-bdknDMrHoexE*0Xn%gJ_PDx?60io z1RjNw!P?|o+%IAfSlp_r+O3*v6)j658UhLbN`Ry~?cEAcQA2kvNs^7GzLO&a$a1k_ zMC2^n($%>t55zZ?7^PmfYirNtNB&E913-kfH@O;%u=iKFAtuUZt#8=qQO!fF5){&R z-&-!wvh#X8dti5gN~7JT=iMGYo+Z6!GLA=xo+Gq*wg{6dsHZs;g%n;KjQJ1evtRw) zY`Z7o+B*HGYcdq*2(l=m5El^7%E`i(PcYgOQ z-xve~>9xBj{q_GThoEa!i@m~fF@8x0Xq`f8s!wnlvg_P6pxz5jGQOynaUD(xB>1}G ze$-75$BKY&_T{SaXFL(Ih01!onaehoT@5}@_#gC;Aeo~%9WT@1-$1wIG?!S*wlhsq za|a2Q)6{E!^Yw2T<;t%?690fu%3PH%tZ^nB?qc}fo^N;m_Q~~c8e87NYID!k$Rb8f z@y6l1LzdsFLWQHYFB^G`!(VJ|_12|L;b3YkJprwe%rHSINXh^9Zm?Qvyn&Dlcgf&Q z}DH@A+eORi~Yuuw8oGJV?yrIcVm1y zX!aWGD}gS*U^;}T4G1z8!(t?o9e+}UV@_|p^rwr*V@?1Co>_G&mm|E`hDzw_-Ws3c zhjQM&w*|scBmd?glYO+fqXB=GqDmGDBW6c_5XYOjxCyW(>Q53y?bq64V$o4sy^s&V zI7Rt-Nh72?woXg53`)K%lL!wRaB$aE`4A#@G=6GN?3O5hoh)qP4GZ4$s2a0d&@}i+ zt*u)>wf z5%qz}Kr5|SCe?cCGB0cuYHQimlb$zmtk-0Iowu5)Fbi`d9+#})yvAloBS(P(esqv+ zQo>??W&{fGT6>Bvo^;k?nzUP#`aV^dy<#T&@>;)k#oyw4e(Sn`VKbeHH}`U%7IPwN z&t+3+*t&#B)($03__JF=KaBV8Yr=7oSgqLv2`R&iIS6(lfmHVpborZtk=k7eJ8 zu@R!x3b;hwq%+bK7#*+QC;y}*h%@w1ggX|SOmHa02UYF#-cV;TrS_n0VYwdH*g+4w zUL=ynLuXG_T#RyV$*8EjL52dU0>wy;3hn8M9@)`(dMkk4@2LeV2fU%_UqFfOapIlN zM4-{-p3xfEtTp(;T#ee{Js~$F@p}>RnQc$7S#}o&m^^ynEfqoO_*6+A07nPbuv?CY z*f=7^bSaMd%U5W37`Eq2o&h(m&1yimAZt%|LP9yZLH-~h%z;}jF9RvtG=E;*zBin9 zMZDT3)71j3F{!X`r|$g;aDfZTUrFVcd0b>RD$>cF^o=NP{^(naV3_O)DHo6n(}6T6 zljnaVo-**D5QZaP-^}}N{exlr4=1eHhLl%CW6sNI;9;BM5hqlGN3SCAP^Cu>;12wz zYS5Yv;1+qSS5lUR{)Uv9XixvqadWuD;C?$qZxM!1J0I~|TzPc%g69|Dk!%@81&c?? z+RWz5<*0(iT;zVob(6=43e;j|K=0+h7%WW@bAp8u(X(k;^-sVhaeIiJgU(yr+8`{V z7GoMv&PNsEK<7GbMIxb^Rf4+Y{@{SIUz)8wbU`yiL5aJ`lV=q(j zi&^}Zcp%YP4oYQSc=mHK&D?Ddw0iEQSzy;Q-Jsg?2xl%$&8{`2Mqg&m2sBRK445SXp(G=F~Z)c%D{1v1I2F`3;42X#aHzOlO??NS~i_!2*hSQ9? z7tz2>VjQWDko9wwb2`D`tzk^r){AkoLd1L2k89{vgkT^h#hz8zz-T>)2I`rXQwlws z9M-`zr`~^CO@JQsg1k%Yk4_0Gpg4!}h7=+sDrJ17s3~+x>At*cJ3tI9L^38uk>& zmdS&Dm-mHQ04u+q?rQf?z`Vu}@p|((tkjD2YG?zPUBfQkt>GvwnegM~XSfzTQN?j) z86vnF>V4Ab*=)Yn7Z?~vL4jDSSvF_O@p~#O8GJkl?#}WODeJ&t@(OzB=^zKx@M&1T z2_`RT_Vv{nxul>xiDn^eFGJTr!HgEaP~1Ot#bYem?RTQ83=p^_{o_~saJytc^)yu3 z#2b`eJ+Tl3Ivbsb`@0rsq%dMj*fDlBPT-YFwgb}>> zwi5DVNr8(owd;7zfOf$DQ?>i zDrJjO1f`O%k(UJ_8WW+jC$xJ#E;y&{MdB@aoY=*KdPq`UE2Q=$?pE7AS!I}E7@KmT z91%U>#eux&Wk>&Dna{bR4t6b)6lNx3&Gk^tZ+zb8a7$LRr_P{0kG=k_EN`@qX;D1k z)<%zEHXd{=MEOuzk;(hVF!g;~>`Ulyq$%N@yv0CCJcy*Y!JaM{Bvw%wQL(|Ga2um2 z5cvURF%_;a4a1M-o9h zyHIgL#~6Elx4i3SWG;AD6DZ2d0pKHO`{Q<*S2?mc^iT|`7#o@?1}C<;9Awdycd3Hq zqvlCsq^=-9RGct7qo!JPF%kWjhMesCxu^VFKR>EmAgWB`B{t{|Q!iT8hYG?zjs5p9 zJsFilUX!V6ejgT%;HjF%eX(t7(Qn%Mx1k&KjGEql={>w7N@=Qtpy6GnbPd!x<6erw z)L!bS4oN=Uz{?B`LR2gm2Wq2P2=1tuXlR$s*M!*KzGBA=7w6oi86}yfqb7GtX2bXZ zY-U}CnHe&7lqQo{;$;6D{VtjYqDpHMN2W=Lb-j+pzmV@s-1!H4*PEW4sYXbEw1o%T3Lf7x#rJj<3X6SnY^XuZuUKsS5CPY3`>fVrA_O6nDzn49(9{;)gm6zXf8k91r5tg* zX1J$bwY|gQXAiejB&qko2m#Upk`1Z^az!Fi;uh)kK8%u7*p+5~S>E4qinN(m8>G%ppxr+x2pzZ+soHQYT%W2NK9;X!Qybv$63b#NFrvrysbG7uN*a{M0RA2&@I&3H@cN+Bp?8ga0Rd zhGW$BajrCH|2A?XB$GF8E%+fft2$uu`JYET4S&B%f2Kj(W5B>noCEtZz1}Wu^VIWU zbE47Hh3E`su=P=1g7J+ooFk$?vKU8v+2@KP+GfM4@%io`e~<#_j}4+HB0A!2bo=tY z#oU1)X(cj@veE`ZPOmRpd=NJW-RCKqjULtLodXVnSpjGVY^{;TNu8NG|F{dtGX zX8u=OQ+bvu1aqAZYW@x5jz^Arbo@(8hhAP+S3jdEy%3tAS$G`x@K}ZU#Bjr>Zx@Zz z@F=Mo0Bj>L&%dDu_iTBR;zF$$oLSSy*!Y_x_zOCYa#owqxc9#@zxU{Fs5~ft#{Fm8 zG9TnVViIg*Rrm>w!wNbEJPSN9VAI_J(^B1-E|@MDm)`0M1NS@F!LRtYFZ(upYnc;K zLErKggO+_1o6=!(A*>}5#lEDUaTPgRA?w4Ac4v7%5KCZ_(Yw(4Je2S|rlH_jW8Lq@ z2?NV{bs_SD^7@74E((g{MBlatN%a~iXmwh17AvZApfX>>OBd-IC$4A=&aQuW)H0eOITaTa};fP6mDe!|N$wz)BV zwK_)MGT$(iBk10LsaKqPzPUVP;AJx@fD8Cz6Z{Stbp~cOYwC!~^C;dRUq-Xd+Qt<& zdEjV`Y-v;!*4u&NRh*>9@%1w1^wc*S-j^Euk+@HDVh6&ATGo%6#s zH%O+mk-z@-aJWO1hs*{6oPp};C?vHr?vI?^C`|4y&{7$)!P9CJR^=j>)1xrvSLKeypuDV{6 zY*hG%$OQR4K+*!gOk#RQX zDD~aC&zG3)A!|LL8Yf4uFP1LS;bCfFKm<%|4qwylAhdhd7QIaT545xBPN-izl&i~7 zVUh)-rjRl2M?CQjDK$_F82K$!$#}pen_VBQf8JtdZ&L9}?S}J8&VxuBh65F|!QBzU zN_yw-swQv@sT@zovscSX$kdYpn@6DpSijHVxfztfkBGv4rE`gT1&sAT1@dFFLVqe1 z%Jx39m9dP3=}C5{lPgZBJ=YA#^cq6&0OG!ulhf)*X(c#fOA~myo%1>ZJA$5KdLJg< z`+v3j{aGgE)t)6-6Flx85PSUkP{H0WH>i_gSk<8Q_{~9nW&c-5ax&9QKJRVoA)69( zH$rh&}yb-kJ%ECS{L`6DD{ zHiYSl(^%<_ph`Ullo!X!MN4Z%MI4OMjn@rk9pN`t#!9l$EN*yq2h}O?ut|(|Qeh=qTWjS71rdPm zA0x}|y$~AhAvs^~0v?C`BJ(#&NjSNG$jFcEx4Fx}AQjbDz4Y^bH6Vpu;Ih>@XXECk zVcT(UTp1ckjw7T#yTarhT9wgq+{MW=-m*>8acc66BxvA-<`NIaB>q#i{=7Nw*7K9i znNjQ|;Msg%W@Sn$=CDBo3zO12ncS#LcP&hiw(1v)sCqpIzp~#}aA5~bUU2R}l@gM* z(|bxcn3z(|`MNYn8ugr$kc$z--Mff{{HmPBmqkO+{ZvZAj@A&*yv@IRMvOKle1*+2 za}Ae?*aI%P{!Dpjv6uk!OrVQWWo}|WTdHOitZyz=P3Xog1EI41*Q0+xIM)VI6dndO zReA<~qvLWR3$I?^wPryW#9- zhT@|TtVd@M6&V|2GFboHE0g;RK`a+DwHwrd zsE)4dNyRg7XQ%^3gjp{5Yr?;Q=mzP(nm3$V;Pd|QQ{nB(&jj^~Z0iF|B?W3$PLVZ0 z6AvEFYh*WpqP@8(WKxUyvJ)9mG|l=Qk`75}HKgP&i_K71E+Q~y{&E?e`v)= zi;$2FKd}lF5!nH|8J2IHV+V;8?`zB+8#}S+AaQ`5e53xPdo>}L1loSVeu%;rKrDS8 zZ)>IXno_GklAUNVB#@NFIa{eUIeqcT@yK5tTU%R!kM4LQ z$is2Q9EhLPRAb&;*MqiEh0!umK~VMOC6-q_W2ggh?GdNO%r2A(jc15%bfltSOaY5z zmqCgJ?p+S!J%N0G2K6VQyX~$njGoi?Nw;h#XX^4&`lQ8k<6)k3;~9)b$C&8?Hbp0= zAOkVHY1E}>MT1PR>%S8ct`4>R6me(pv4{2oH^}1u1#MPro^;CnL(u#BhE+bQ(S9}m zl@7s%7}DOsBIe@v>_9^UID7ssh8D-j;+a$&lUY-?<@3sjZl~14?V#izVDF|(+q6rc z$Vfp(&0${mM&tQX3?bcegt7-zT@O%6J2$ry7!91aB*X#uxhw|DsNo)&ovPLYBr=Ch zmXPs#hn>m(ahu`IklNu_erJ35`>uF>R9fzpp-%*0dA-*S4d@-nNH565e0IQV`v~Dp z9{XZLULnxku@eYX!MyinAtxejSm0Tfo$@F+2gg56^&s1lCf&?VOFb0H6X`6_S~ z|7^E+29*tc9Jp@A!`svZEax^Sh3_q3y1B3{Ol;J2hhOPRRtHB=k*o)U1#d*N8sSW~Yw6Sg(QcODus%S8WzT`5`MP*k)CN zgz~lTewGco_+#$VFa`6j@aL8gqPrij3h!Yx>q)!Oz^_&Ja8>)nEID3ocy)IiVX3c2 z2~r^r{JOe|fOs&5qgwO4#a-A2km}BM+fC762dD0AH)VnHJ|$C$J#v~m0b*aMcInrz zZvE@=7BMl`X0@kStolv_sVNJ!`;06hA*6g>7~;`(C>sb~5a17vrpnR4rr_2R60t({ zt)Rj=*(wKXVFpQKs2gxAiPxURt)ZM;vXp`m|5oD^VrsEMR;X|fWv-QYpC23n7z`dKo=JZe-k;eC zFCXN|UL!7h-BfeU*b?C%maS)82Hb3$G(L&Zb)G7Efst=*Ayg`%A>#1Kwo8K`yj1LIg)-7DYV zYH9Ca3i5kk$;_#}?Qn>Fy&SQnpyG}Q@k)S`j2Djz?`MvXS9pFkUvzUv5GDpxTfcUS zk-mc|AKcZ9!&vj!S|E%x(b>U^eQ7!Zi(2x+xCh_*Q)45iyk-RRMiN%)=r_BepApH} zCSMKsf1itboH^AE$t;g8Q+QE;$q_DTUGeCoKkNFP1xqMPPepco2)3QW&_(BU8b^S5 z*ig>m{8!I>Jg1auA|k3KnNagjr#b4MVwJ`|AQKO5Zpu!Sby{-l1{tl_h3Kcu)OjvrVr2GjY&gL@3{yw5(Ps+op92&4YX79+(C@?| z5=^{G2OmY`kKmtU1yuAazqk!8*Nnh65R_J0*gsF0;F%YGpgti|kPz8VCt8fqJ3f*M zgU^^fuV{}f#t)@X80|LVgdq&?#w0Ev!ZT<=0a z^_H5+n0^%=i1xPD;GI+O+c~Gx%Mr7gE1xl-`Ta%t`i~!X?Agx07p!HP(Y0QL6EO)k zR#p+;=9n+CaEQf(1$i7UKIfr|;qxlFhDNo^Sb=!@1FKfpWE@!@aS-4eQ|epF97t8c zPmt|l%|F@SP?!+HA5ZS#%+c1sI>9C-9fMECMU#|dITK}p?<#*mK6+~ z1@8F5#`%l)h_|_3#vbHpL&54VcUb*$^ZP2>Jm0IO;|V6?Xud}uj98C=U#v!poElLz zRW>7rW@w!P8(NXGf4t2S78e#>PbjX%Ng*8%ezJ^dCK3C>=Se^w2(veq3E^*Ec#ylb z?ovz5FZszj1dVhiGgKPwm4nzN;UGO2ga-i;Q|GQS0+lK&GY*!*?I4vW*sg0F+Jn&L z>z=%s4jeULG}C_MkIye4$wcTQXrh000K^Pz1o}K{$qra`=hUW$CU43&wVcd|yE5UvwluEZpqppOpY6g1P*z_$n zboZ*|YWU7*!?lPGSk72dVUw20vW$id-k{3h^>7KKo~)tc7U)Yq%ck)`R`8bPC6qA# zUArZWW@<GplUNTH>L*drvw673YJ^-rED9)=3rOPll^uH|{e8T2r8Nz=hwBcf6!n8~r>sN0 zrlZ8A#lgf_`BYf+`xe}I6dXQ#DDklNGpN^KkPGVYyZg5 zy$1kMAqGEcpgWR42Q8)y+!6)}4{lVaWyPq4Ad7iEhu0egj438;YH7z})PP1&)79q? z9@A@-?`)FWTh95$dK?QsO5>!rq+L)|1jMEg6=G zfeKA8oIWT)d}nLI`;j=mE?vW2Euga3blbr{Bxf}h$;VUr%7F*k2i6aqHvQylP23 zz|(ns&ZzSHldB!)=gnQX5NomZ;ZbMkw%LBpq`PKVi;zi|-bjX@M5TTqwBUw$%>9Z< z+Y(~f9tbfla0ksG#t|N=D6#~_FXEHyPh{wGF*DziZP<)VBfUe4oqL`Q^4 z8R&$TnLrQRgahG3&dY+LzJ|P?2|Dt0{UQ3@e*uXDO%cK4&#HuM_cF$d3tG1uk^dHL zpr9YPneOW7Oz_K3!^VL0+!0KJeFX_{j*_xmN_a5oZ0CfU@O9=siv{1%hCL z8uag0kDXj$`MIilDjcD)G%kT>s3Bx*WO%V8wx}r3j+{ShPvi6Yu4KkK!iK(ZQ(pF- zxSg%YbBh;j6COm6sWLJF4CBvGeH+o zHEPet?fEeF4nJ&rIQucxI88bC=ZX$mvZWRlmdt=coijn!!x8?;Y1t6 zlz+3RHE%;+syS>IbBda-RLgTyKTFoSW8e6C_dDavH&0kVa77vYO?Y|^pp`a*c%;7& z@cef3xA1F*^tO)YjVGh6<83`O=h2rZ+?YNUCA&eqeF4QqX^NP+%HxTS^SmB zhoVW?9VYaZspJSyOUcj#wLY&J z+l}pH!t?HP_WrKxe1GOoGD#*g&$HILwG3z5)vTtcGuTi9;b#7R99pvf`g(D>>J8>d z%u!czyrP(O9!7uPLMd`VoN^Nx--|rs+YrTR8#Vl8Kz_0CW<>F~ZR(TG!BguuCC+f%ZLN@WCd6h1Crm;&s@Gk)x-M>IVLxN#t+6^|>F1o=V~M7+mL7zU}>4NXrA$ zDcxhcN{ZyX9bKY#1Y99#M`_9an|Q4Xn7CMycrhuLig%%}*9lnc>8;{_bA_Uw#-W41 z$cZrq*pNojJPB2r;m%k&>R=7QB`9e$KX>N+A>6^>1XgA}i>S+jV?wnM@tf0-?!k7o zMEc#h1E~S3xco#XhtAZ93Bkb?BVUbvYM0)`4Z=va-48J7tz->O^Z`Gu>u&{wUJ8a)Zz934 zIinNwQA+Yr{>d?hYC)ibe;SjQHLv{S1nS6?%SvRqYG#Hicyrb+`ec|7lA*bCg@5yR z7t-)*1!9mPxW_^+z`Fy{+Y~f9=4?AOM(|M*bGxXdkm*E8zQ9A1#lPiO#Sq}2QhLy* z>xk?b0z6^vyD=S%D*g}7%I;q*JwH`CBbAVv9sw%%+SjXA?j20piG`fjLn|=q)ZsaA z-^Ta;{_#=>N(<0phmM;U?o#B9J?GEsWwcZ;7{)KdS4yBDQOYc(Qdg{{6b586?<;ecp*n| zRrMuS#)HB)i%f!iHoHdER-=*7r?xA!humIrWAUVj&uQVf!lZdi>l1opAF*h!la#Fl z)suppI=3tJ`*l;|ZG7$iO2}}mI67-p^B+P-$h^x*t3*;!#$=dW2p6d8*9kN>@c;qU zoRY7(WZdj63Idy#DV3f|z9QSS9NJUsb97J*e1GAE^~=?CK49~8KE8V``Q9^=!xDXG z7W;Lsuld0J0FBPhO#J%e-G9|GHzz$VDnaaOh;j)XNyqML|-wl3>NuU_cS1(46>7P$%TkNVsv&+@b~0Y z_p2l1_v-q%kb6SqrPIjPu#PBpVCTE;f$Xy03HJkYV{TLYHOWUO-Ey9Jl5J(k1_%b9 zNeGKz)@1D4(%UB$@GgPGb2pi1Wa)K?4N;N}DmOVOqTy7Fv`3ln7fkn(;EOn>bh_%~ zogZ|f8n6$dqtcW}emH8?)dg|NR+-}Ze_r2aracu-II<1xxh%7~x|J5Udr3%;B8Q4tklCeiTQ6 zKfVUw)4*zxRnt9m{EgivKbuGuU%_$ul%<`O#a$a^{Mgcm`mYJU#|K8M?bQ@>c#L$f zE^H2@JZ)oa%dKMLSUxMHl_Jo(!@<$)#BPlSCCr?P^ho@)4E&zD_LXwI3H?uthp*N$ zH)5oe*Oq^*<2)k9ij23P(F1$fqL6r~C;jIGLTin(?yM%$t@wQQJ3xqj%LN}{1wC3M z0loN;oS1*viDi;!3x82WB*^)eCn7;0ElGQ7VnmVQCT`7>&i^@>IbC`GYSYEsM^nci zpC3{BD{Rs7D6H3czCvy2r-iU4c4(rAB`gv#FMvK=cD|ZSjN1#pe!w$(;A(Qn+4_*AwR5|7_2}7{Hn`7wuRDQ5;L_4Zv#PIO= zx1rA9vL6470jL1QhvDbz6u|NqeLM~@Dt9q}mv`*UALX$80gbu$BXKEPc-y)3@2#r1#hu97dh6w+f$Tm>^)yY74OZ-N5@%tHWV#^(^ac z^G_7Dmzr*hfpXs2s>871dOFE9mPA~Tsq?kY&v7Foe+iTBca6!6f8Wjdh2<&; z@S~Or26Z>vrqhpH$>039dv;Oa4Pd#$KNK$(5YTk7Dq&_d(F$g?-jNZk_E%z-uAg|O~{3oT3>}rU! zrKl$t*yD$_yV(*FtyLo=H(lNRpl@e`3`K6xI)XuH^0fU-FLbPbXF}EYs1Yhj!kxEe#7#OO2DYQo zyZe&w>8+tx8C`4>T-bu%mh=G%V|NX}O$Z$R?PN_qwmPa(gHhG{YO?0MKformtT!7d za8&uKhPs#Fopl`?>d!Rj5d_EI(R5iq`{1en?}xY0+s`hW53Nz7Eq6uk-4Nh!`tL(h zcko+iN6bIR|LZBTpm83Y;hq0|+kc;se4AEJ7uW9i|Nj*<2TWEK99-Q0r^??Wo(q%uagQMWrvIb8)-w&;Jv z5?p^1ICGQt5uHogyM6NiA#v}a(1QXuGYE9S`R`x}D2Zz1mjmYem|(2FRf(Q4e@@BO z9@%Q5wC=33h~dDpUdYG=cW3*Ptx5|<&7|UNL@MZnSZQ_<*TELCIx8X+JY1+b0|jCV z10ez>RLFUV!kAwAk`g0iSBK~|qD<9{ECB}UK|_-G%cpZJK=eekKhbc0fcswim%ijm zjD2u{?p`ADr)g<;u)MzVGODDssy+Y_UydtLc~AJ(6tD$`Hse zlcb?B{s~yh*2l-_qgpTsh_MtDBQQqQKM`Oa-vIYEi$B=M;7^3m; zUNber{`ZXqrOE6PtVU6i5gCYNUOgWU^^L683AGRL*7+R#2=;p)=HVV1pnNOC0>6e# z74rP`>+N2{&*UV{?4w(ACXK5|14Ezc;d0aJbxPp-36D|5e$><3L{`wNOj&xX#Nx#A zrxWZSE}JQRjCm1&;i+>%%;a`U0F))x8eW!y33oV6`7LknjRa`eOPr7j@+3l@AIJ#} zUBu;~>7JoC@v65`<8+xr^aLujUN5AeGSwoKq+CYbx=NjTOB*hGzl_wy9W@78`erD5 z66Tpd|7qgxNa|MnxkO$qeVJ%z`2Y=_oSe;Cj1Hi=kzF&?rOoB*l+;t3QH&K@ZKZlU zZ03IE7EtT5ZYU-TOy@7QQEN~0a6m!W(LeBxL*OB zyqI59kcu_2=YkK&s}T9Anp5O!LXgq7Jjdz`5fl`TOysubVvVuB8X+6(eu)Rb`RWLj zh-$V7Mq=boB>b#i6D?@u7fy(B86(RdDCiABGGA-kfZhbSG;Qs|uh#0Xd>i*LsA~?> zg50~cKvl3xU8(K#sL+x<29F9m*@YxMD`sh7bi-r zzO&BvzF|+6H#UH}1oy0%J|=w_N@{_3&(X;DJys6_KwzH7A3iB>k8U^u{;oO;EG{kr zy@8gl&O7x@BRJ$It`Q_u7MH(BIP$6S1~4l5{lEVb;$r^XvlC!Lbp>#9moc$*DHj1@ z$&2T6SacEw3i~$Jm|3Q;Q=6pa_hs8v5&x`>RD_@&Vwqf}0%C1DERK&){0>mee-B2Zy3-!-T&mnjMy_Fvt=-sZ2u=(Z(9Abs#NN&{D*d6fI9oU?XJu6T7 zg354kaAE-@D5-cEC&Yc1Y^_09P$s&kTi4s7jgDm#f3vcozGCq<4I0D@#1BukZ_`sr zz!+lKk=i*$9-8*~?UOKpGz3burwaL?@OomSFAZ-MsN*`G63XBT5+&O7W>6khX+_GshU2@mvX{S z$-*Sg2vLrZ2ujma^fY}85C_fZZ*gt6z~t0yp;2=e{gYbzOM`f7Y^ksdrrskP%I1L4 ztms=%E&y24fbcJe)g-Ry)R*gaX=&;M?0%~jm1Z-P?`vpoMQg1B&z^;Op+(|_@Ah3@ z^!)*x8~x3aKNg33Q@loQ);z~revWt_QARV4H2GPbNsstqNfm?{L5X{HbO$pFM>Y+@ z>amaAQ}kXb&`6l311hWre3C#gNjhhzLHpzJZIKOE)VP0ftjJ$xIvP|7kHnQV1@{68YpzY)*NGZ*f~3p>gA`gwvv?&-;`xW~Sj)2d8=I75 zkO}2?Ncfo0KR;vzMqY-0c(SaY#SrSKEnxZa;m75btscl9ODrz)9nU`K&22$K!(|${ zf`*l3dzbTAFr(uVxJO@O6_uGVL%nAC;ZCIgc67vf*^GFx^UIBkq@nf9B651sU&3!O z5_1Qr|FEUu_Xs#of;=cRFNF(YWig)-nuK_+VZHrF9j1*2k{i{oKc(ay&W5&~2}8ai z6&1(`R~Z7^rPV&HI}rRC=$hHoQ*X@%DA{#eJZKpiwHqiNET}poezvVS0Pph!u(ut@ zjeL*5O6-4U*c;*YHc1^+O=LQaM^>|1AeTmg!z7!^gg%)$l*Rj1K|X=u5pyz=aSfYP zQI^UUIi55)m!I+G4$Yeh8yYs!$YLY_Niin{+zAZwo&`%>0wW|qJ+ALca=ghNytS&t2QNbSLNTZlCsuSX>qZou`##Z z;kllB!HE$`G5mhe&%7$PYg9@QNk2x#Bn3lihC2PpdBYC)))BU45%p4`9^m zvyNjWJ<(!JhB^%%-$zcADIuZByU^Wimd;znCMQIUsoND+30nkMd6D5RUM5Rha}d3( zZJMoD>*8~^f(GUK0CGD_olkM}cGs+=L#q=^yaHdq2sT2HR(sj>F(Q6-?LJ38lbdQEUQ z(-PY(+ijtBcwZ-cMY?Tt$GS4ZAfC+NL&1N(877I1i9MRQRz=i;DVHKI=X}sP?(tGJ zIrytKtC7oF1e8cugQ!aKld4K{+#5;e%}`94NDnOi1pQmc*K0!>-BU{4_O`=0iP3tT zTP!)5;pIwfAs=}UvNOlq8RgXs4bzP#--_o^HQJ1{Y^GuBJw@w>7bIF$NMdos{G-@2 zaYsiA8_YBfB3}HtHrLF^q|Kep2E6}J(i2(p#R{27nay-Wu*CQ+zE(g}MJ^TF^^@{k zuUPbd7u`BS;z?^gs}+u9Nr|wO6!V4%_lDuhwluSwhk|mz^NdPlV7{=F-p*++sZE+j zV&(f@ifuU`+s^>wW7Pa72sC9V;k82s)mZzG8a$MLLer#I9)Xf^gumqPjbV`YY+U!7 z?T6GpBe&~exBF68yX3MG>7bM8s@^c2G^6@rVG-I~4x4R<#Ne~nZ;@i4s@ZVOKRXJx zCo2AA;)P}L2o0LSaL)?=Ozahd0o)m8Y=ka_-tolAHJd=eOor_ka@Y)uZ_G6VxVL@> zDZs-c@8lZa{#1Hfh$=xTD66yA34w$3`oKkO46$Wm%DXZ)vyM>SUCOe+DH#ivD%V+RoxTH)7-Uv4|!TEHa&!3y{Q2!$Sm zkDHzn%OH)4pw+|%Knh_DfyWDDiyy}RJ#Qzgo;}7i2(jQg{YrEE^(Ja1lM!)p{66P@ zhGWuob#;v;*92Sv6b#bom!7t&J3HR!UeT8CD?Y$VhpWtRF%Mi(PiFzss7NeuaXF%~ zZ;W`5hQT0lvNaFP7(eHwzW5-i-^(9U&PW=Y{VX-XPQ}(-0w%eH06RWnilXA8qoC#E z`#HO<4$l(BY&*MfhxNZnE0QX-yl2PUhDu5(ZqV7kk?O&&9CLXu&Ozg(@epp_Nw6|X z!pAc(Vq%3~#li{%aG}|p5hoc9@b_&T#>?%82ig@LW-eFn!b$uW&MHubkaQ8curse$ z{NIavZNH-O+t1XHG;l4?pV{m8WzNA+tp-7e6>YY;JFM1Gsv}5Zd%-8uC*E?*C7NK@ z64D^X1VcZSCoy6^M>y|A$p0H~ml2*5WX4}+_*aT2ezH*Z}{ofXsy0>NQ3jnp5Oni8+~7$eT^wE`;6w(eQIk-||#`$T}de0;XF{&hN?IN6&kA zR+;u)^MlTy>+|=3C!Lu&-OTxj!+gwgH698Iax;eg8jb99;(W~oAWFvi;5a15V^9#O zu4JW_!NVIOfYpnhmCuW4y`zmzI&5H@#cm+%nh; zbSiYS(EZQ#WF$OCiWgzo4(D@%Ivbiv(AjWrmlof4bjFFd@$l({p_X`b;tn%3G$|q4 zkhDRx;?r&@lSj(stQb>P`+%v5xcB~wx)zu8%L-|mpMuvz`NBZ5xF5~w2PDtt70#^3 zrR^*!Mt)hO@vOc|pTKG+`mLn>KJM4c5Y3Arwiy#6UvN=@`xq6s-2MTou`La0fI|<^5!cy*##WvO)~-(KR-R!=9e@1z0hDuJkc-9tu0!{cbybj;|KGsB z0gOVQT{;}9t(qtw>Q5PVdKBYY(HZrGV?#2(bH3KR3HS7OhO_o}nV0FJ7<5gmqW#vA zkC||eD;1*_%xP@Iz)blCN}^VjWtf0twgwp)S~2)7Z@oQUjLI3Pn^+7I3X(B?>U`|{ z+OR;M59=(Q4c_h#*a(yQn6GS$=JY>6xG5a&*0F(1MwS$ zc|R_Ie}U=LJ!oI*orRBuVguwwbsx6Ebfu<^+ii;3?7Xg*{7%V4_&cq}Uq=c7y>FA- zG=SiAPBHPiK8h+48Mxq?PdZG70fh*n`DvD#BvN^Kvqe1Fd1prD?V}e&+dGt1 z{=?M*V{SnZOb?GIa~jdrSr89=zL#XYaC?vqD2BnO08qUL^QQNA4hISx0X$Opf|NY7 z8D>*XzF0gOCAl-tfE}gxq#>f7qa=5&ATh)Z9qXw>Zr)P;;X(O4s~L*XfXT`@CgnnYcK zy|t=t>JK@lCWoQ3;;C?^=IrRd<0c^SK_l&;PS|*loTNmPYCeii8#tNb|voZehsePd{0~ z3ycUq^}TWk2*dm3)JsCLL&gcV}({1WBbDDzVc-oQoryPa-ASfCXWC#qo!4Y-b2 z?6_7$53Edo*OBYOj{5?Iew~ipYkR|C&9=UpCM|4##&Ms^8%looDgGbH`yjXa_`f?n zhO8+1*Puna^zO|;_S>e3!F)-BY$coT%W?NO8uQDV$F|MHZv@Sh78>WiW5Qf1*Yv*Ny9<7bsINOvVYvwld*99c*#={k z*}t>9z!&6>f@=)y7hgUQtUx>cynP$_FK+G+3pg*mTbMW7XwdD`IDO>QcI%+`fF?5^ z68(vmL#Qs@J%->eP|9!@g4Q59!Oc{t=mZIskWZG1%dm|C&uknl|HS2=_oQh6A)`Su zkCLjbh^75F)D>!YsGOBz#q0%R-gn=rJ$!z+wh}8Eu!pm`nC7Q|=My5D&9k`?PZ{0izgI<#-6E2Vsc2Jec*52k8rkV{DeIH_@-K0=7L+Nk11>?{*-- z?f{RkQWkHtsBWYE1-l=RO``|kFgs8HQ8xqWk?N+DZ87c()#y_NEHm9vPOILeF+(Yp z*hP-}r`PzS(QbGu4UY!^#OyECgjr%@VhT+!!HKZaK7FqIShZ1FOy)uOyg_}NC0^D6 zVn5sjh`j#p81Q6d8>wEh_=drZ*H(vw4i8ZSY%)P7*i(KI?%7XNN~1zOPe6?ICaDJkGQ5eY9=4Jm2AD>opKRhG;bEJg~)3uMQb?#R>w8KF#*_x45-`y(Pi6Gokay;I1-Te zgsDr-dYM~tgGxR*<)jqcMdKNd|3*n490st4frh~qOWPn4LOi;MdtEpnDcn<{NTVYI zR;Dbu=3#aoGP7Se?*OoLG(p)9OC*TIC<0#eExXkwB25!p{(wui)qxA~ay(Df#0iUx zz8cpycq(q@^b6n)Z1g z6;hTLo9{94QGa?%c>`9e1lJeX{VQQP!2`TyWmTOChUvSsZ7wqS&PsxQ-{w|6T9A(25lj^e8IFqt6yx?&F`8VW+6{cy zS~ci_=eApPOXm|(|2Q~6_Wx{DRk5(QFjK;E(!Lxsa`PK9>gZb!R&&W^eG9G$k8t+UUScd{>^}* z%}0WDK6v(`%matZ>@OT|WNZo&LD7y)bm!ndgWpZtXrd)mqq#h>qazSFR8QY-F@sn3 zn*6YR@ImxKeo>uF^PCiuGfV%j)+oW_y`QB|>*Y66-o+#0zOZ328j;-^Q8uyfHd~!g zAf$7sVG>Y_F^6!toi2<5rT{>7b=KVxbOv>`Va7QDp<)4$-+ymVx~^;g&lKtom!5yG zYiUYm4fM_hcuG>y-L}v=eQuwD-{|%Hp7RFQ62V&l3;9)}_TO0Coym{F#7F$|1u17g z`7i0{^`Cj#TG1WHoJ0dCE2MN)FYNBWN;5fIr7Fm`&2%SQo$K^==MLlss30+~M>mr^ zZ}mC*Q%<(B^RiPX%c&L3-Js~a;pmy+hUar&G*xiMF8my_&^Y*w(jbskV`|? z-02mHj=CzcDReQ|3~`5d?(GE&-0V$~6`%_!Xapw1Bkbe_CcF1yuv&uJfEhWhl-xT* zi-SP&Z$Ko(OI7Kn_ah1kOS$JAwp=R1^oVAbObFxfrZ>CCNCKlldr+Q3Na73rHFff&kT^kQE-5p z0Wi`o)~ZI9=bQexTqqm_VZ}>FHq-NU*Q6_#!TSpZi3sehyn>D?H9{?sU0uCH0X;9T zVxsVrSR@nQzHxB0e<5bYd^*C!oIh2L>+Do}eI#0{T!#tE8;xmx&iNCU*R!Z>&T`k4vEb{c{_9xmZ9@AVNAO3C zM*kwspI;KxTFF9YdSXV;Bm@e@mV+4sT4!NK!`70a0|Pyb+Z-qtKm;KFrrawhc= zlY$hUK@qTD)b(9lEC2yl$5=v*4g-vhvX2qDGc*8j4f?J)Xh(1wB8pon$%y1}R-&Ce zXl*okwsSKY`rSmSXCpD$>0R40q&If$^@mfuKFM-kU^=YO3VJE(s!JZ~GTo?UkuDV> zZm;I7Hj4R}cbiWej=mV*3>oZIG*b>*oXb}CCxYn3=Z_+nKso?kF;;3GX4^nDJiC*^|wntt~5i%jea5K2Q5B)}^+2ok5 zE|sgkS&boNjk9YL8DB)dv@~Hzb9;l4%T0$Qz@XP5yiijk>d-#~x1Ickj!8;vDk=E* zz4Qi$@heF;Dt}G5jAkX~YHUT|`C9z#0d<^AOgODaLtMUaJ)fLVBUE%+YILVKo=36!#a|7=rD_2;!YJ;>O3Q0-XtYN^YFbdlk2niJ)FO5zj zOTwQ>7IT(~Kx33CSOxPP!qN4z0~CSF$=PpYaj?X*L#zmnBbLX;e9X1AO1YuleQ`?7Z))jlBVv!14QG{UgXZ(0XR@)nyklA~IF; zN%9$gWgaxX+#?QW)Q+L|kt5{aTi|xV8&IQ=b&f3DZn5qL2llBRe*)}5hHBZY^|bLV zT0FAZ;TEj$0gn&#s|g9EzcSb2FUru0$mzsARzdrU>X$9+Bg^hnH1_aocOe+M0uY2#q9Tqf262yt7Y1$)BmOENps55(WVLcd?T@z z$jD!cJGvm}byjV%Oe%#YIN<$$9UfnqenKfKpUJ7Upp|yr=*IAjJ=7Pnox`^pVH!Pt zU=uXZ@DFnGIUG6SB!`$(hjcJZ>_>Oa1+|`kfE5wXH=P3}!+kNjhu;jWMB-Fml`Z13 zDJHz{#>KTHgALHFdBiZanu~5jyzA7c|CryEhKJ|}OFdmuD=R+O4k;pW%;JRQ zB+b1W&b*6B4Z?K7Kg=&9iLGdpvb#ebslMT0vhm-GcF+4fwQ?TY_|MTfZiAdTmR&&rfSo2c)&Kp_R}l>}Xj}xTCyPeSL$0`#=W{+Y1~l z<+ibou4^4L{`2ifXxsOR2v_0E>$7KM$$mrM==%d`4Uj11AY%U=5A8rF5mMQL_ex1u zv$o-bNbv&r`K_57Z6H-dS9enxQ#$EX@}RURHXa4(m!AyP??QhU}UAcfaN|_1Q1{XKc8Dp-Nh`%Z{+4d0CclCnr;?4HPE-X67AyDTTnhn_U*aKlLMIPqbiZ~i%|>Ohoj zC>Hhw+Fk8^<|ot5&BUs+i8LZMgN&@NN_VN`bH?Y(Lm871?G>PK1ZX-r4A!Ofvuh6C zJ+8j1mDsOxD>K8qS)!hT5=68$iA;}}4@;EWzhO=gg+rmv!zAQzB43UZ9qzFqK~{<~ zC+oylg9SO~T<%GJeVgqRR{azVdUQU7Q(GPRwY5hP6n76Le@f?WNWn9d6$z}7$Qe<>MeKfli zU}tNd0a%Vooy2AS&1b8I4A;amP+qNBzvq!7kGfnL3L+3V!d9)L$_AfeUOe|FD5 z!)E~L-1W6DJvj4MHX$_=}1LkOkys(tkhcje?D>dzu#(35YWi=JTJ3 zsQ`U=>CM22@UGAPD&XQt9sxWU}pmY z{CW}q3}+F}NUz@HZoWbOAUpPsL)di1uCFk;{)ow83tv54&BvZ^9x!yVkcSfK zC1f*F@v*76!_m@|CGc@0@c9heEXN%Qrbk97XB}}^7NBC59X#<{Q6H*D+*_A69Qa4N zKh02L{7LhOJ`E2Yrmefp6#~CAiYLu9ZfRwslI&}m#A4Y6co*`ag)AYd#~cYzjp6vT zVZ!rsR2E@+S0}X4`T!T*CRZ){xw&$V8Xp4rHO>fU=k;L8udfrGMAN_k95T0I^TSEbWGssQQ+%OxI z0K`8@d|}69hdUgr_~qmi`#~8rlO5HzW1oZc1vT?|^!BL+fejcIK=>d3J$uq)|92rsDie{m z=}+2k=j|@L^cvkyQOr4UpEdd_xW zkN4Pv4Om+?uT6u^GBQ6Upp_F37U1B!a+B`>KmcH%hy1>*rR&=jW~KF718qsnGRJto zVR4WRwBbMiA`2(+%*ab42od|_eoi93z!YQbM?PQe3t&r_T?4e6c?6O}kUgzHr7!pc zX)U%_XpUJ?R(5i{U#Z^>(-k%Z9J&J2t6im;$YM(zWh_b>K+^9>ci*SX=1ghypV&k= zDw+uZmKZw~WirHLx3105)ng9b=yO-5@*pE!B2;4XTB>q-$5-F&_WK85t{+@olF(xF zt@W1eZWpr@Ul@rpV$R=ILZomr0ME0s2T>OcYRlX*Ng>!H)NNw&OX8;T!F#LRGV>T< zHvm}M8EZ+!z^*QEcAlxN8z8~53h|bd=K%my&$ytCt%dD+ngAr#&e9}uE#*SID8~@d z)y0b=yC!fC+I~9{AL+|$paxc13v@WAlGN>$^1Mra z@_MQy(Kx@mu;3A$8r4@V`;?oY+_f~VUQ4Zw?wUCeqQ_Ol*A&H7`8C`#n}^o>R^5+Y z78{kquvw?WUnpOi&pqPk8y21(Z5J#OKHWxZc2=g_Wu3Wmo<~3S&1~U5u-rX!@G|Gi zCITeu5;&%08;@}1Y%GfEd_}YIyd)aL6tHfuC>rZE)#a?e8-qcvh1#f51noec0k<|L z3xYNJw#OtgvP`)O2?#rF&e^dq_>w$7lrhnx{uwFc$$Gbw|2As|gh=csK!GC}^wgi| zv zZ%@5}PZ}4SV!+Krz?GAaF_lft7SXKL|EKMn(A;tFHt{#l$3#N>xSyS0rO$V1Gn(aH z-m%k*{Z5L->&erPSIX#le0nEiSqSrf6P&PwN1AZCkBxoo>%8txJCZq*$6Rw969&(f zQG!%gmz8Um(#|hm??X4{^&Cq;G+%!c@%*UL_d6&b7!_HO39gKpzoLeVPYf6qP#D)g z?JV#{xtKM(FllprBxudOhcayaZiCvlV3dRXzt-G=5(w9#=KaO+#G!jf)ee`kEOaf+ zn8Pi1^Rhgr2xkgCgN{qVNmACr?c<_gO*48Gjw~IflMszx1>$>*xQjBk68+<=gFDlK z=kV_4Xdd(JqwCx_!u-X>GMVGw>41LgH=bH8Q!9gDsV^?jhK2=c-|N!w>ddGqkmJ5E z8;)OjYW@qUVLd1x9z$I)I9M}l286x6TxSzwJ zOG@3_UMsi~aJ2hxHEd#H6{KQ`y-z2KPDL>86#JJa zCMT_=CPEd=yT**V9pwroV=Jqwju^Cq`ms9x8Pl*h!kd^;|4vW$_VW67gpYG)v*h67 z=xDdruv*S>hH+I~Apdw4RJHE@`~u=~u#ecT-mJwVR_XS8Pnh|2j5tpD9A}m;|9CD2 ztK#{b<=L?}-vu)-vTS>CKBFi_eFPhyo8N6sfn45RGpB!L^HZMMN~U6|s((mHJjD4n znpnWI>*uJFHA)7!T7aprmDj^%G;7>cVp0iH51g@NDVvA2v<*3VWaj#+oR$MsEywRb zk-M+`qC3!gRI@3shS4=9)`W!FUGI;2UljT_)g7%96G?2>I*`QJ%(ahq|CN+K>)QIv z0YQK)8IUkAz_J=}6)%lz#*?jnAcU?r<=eM!fH8~AP*=2q^aS;D-ij$-TP1R5c5!~D zHZ`9304u3)tpD^pB3>bhA+P}artD*+F2}5jK!6jhAd6IV|)W6BCu+>n*wWGJk-+ zdKxU@JYt$;a>CJ`V@b8Acs#|wtU08&{;F8|ovtIFixp=gYI}D3hCgnZTWW8k;pq5- z`i`n{x@LPpo3|dt+eXbk(;nk=!)J0b^HkA5dz31SusE(o`(epImgTd`J(+=9oZCwt{$E72mckb+RWN~@Yjn;kEyM2W zlP$S0Rt9{hdNRN%T&g;^z{0iQ*T()pgUv4eTR=guGmEYO&+%(bXs`IT3&9{ewvt4EX&i zqgagtb-7=xszMGK%5@6#1G*-I7AB^RoRH5}Q)5tfr<{QYtp(YPE#d zS)|dlac&}R6Vb%B_hN-S9Qo5s38bM&&9wW>vUotBkr!o~i;lB;nu4JC@gb67sXmyE zg{}my>O(HlXjwQ{A_Xd9*J3hRRy@c=M_P|Jwg#;;oIj`6V_7lLKM|?K5o?9bisY@~ zIg^LO|6ZBhe&(a?4Gzc8{Edu2towfMW$=9Yn4SC@pJS<(ffhsx7xbK9pPfBNxe4Mypht95nP?>^ zX$VJ0>;l$yrv6lT{FhV)0Wsx^-oV#xs(nWj_VH=U`)+*Am`nh`FC z_)k}}OxRt6?9I^F%#|TAjU1zXGLVx?rQ&2pYfHPC4gp5y&+~mA5+k90Y=--;)JF=) z@deE)T|B&ZZsVOi0~OdMhm|kxuOHq`8mU{$*IT~|hm5OiEbIhKZWn@w6(ui(zChR3 zHuULo0h=YgQF7E#@V}9>HG>tv`rn|O`yHI>8vqD6B9*+V!Dbt1>FXNXq&j#bERq_f7O1a%%WON$X(HVwi ziDShlxiFHN?YB=zRtin}!vNxh*ELSY!ocT3NAt2nLT-ZLTWn0sPJP6B(eX-3#WF!= zgTu^@cV|sDuW!CXHz_0}B*8ken$-mF&wKHK4ruhq{Y-~0(74eDnc-^S!#C}^iK#8( zl=w_$o*$oREer#_b7S}^(>ZKcQ}67*cN*~Ok&uw`N82BXLu_z-f1BrF8}-lZq`p|;=gJ!?4=-2s+u2mD)>SV}1aPN?tD$jO*JP>5T zAKxO5SjphwPq0d^t$fq#I<-GFV>jDPv?wicOrm-ZhOu91I2ak7r`M`+c5?eZTYwey zw}fb0_Um}p=G%^}ay?RJ(;hpY-zk6F7n_fj4;wP=(1I2B?ZvCD!lP6>A)x^4gTtqb z^=_G@Vo6E6G|B2VF9GC2NQo3_eY7Z%w)YL24$3cIfw(*tvY3QE633jveUb-`=My2n zk46JN41#v#ujG7w-GMjenbT@svB28CFW|r$SF!$Z7lbUQ3}9PJV5O6( znf1HC{M~Ypi7#2;eS9G1o?-o`Nxp@Ek433ehh3eCKv{Ii_>>h+e$%C@kCr2oMgP?w zm?|FbVs1q6`Ny|`*(j-#jNiBqza5=sAMpLD8(EHsEPg^Hscg-@qF> z!argMz4w&DExRv|{FU+QlHOtK`W1!Y{JA;x>X=32bMsOuiYXF#TB>Ttt+ups{64D) zA{qh?GC{IvncHPmMUb^|T_~%@3g5NQCRT2mjq@NHDu#)j&Qb4Q+zH0UdNW%@f(3Ju zzV6N%v}v!7N(vqvP)EuTQQF!0-gg8EkGSDon276ZVJ1 zh;pzDUbKulQnCQST0K1x%VohKLbD2xYM)%s|kKl=fJ^y~-{ z4{I|EkW|jQE;9o99jG=%l6!N#-INuGxq@I*AJ`brT{*5Qtk6K8Jgc4`Uu0;lH-}(y z&LEMAB^{G)XOF}zHH&`CoZq#81}UU!$M&DDey;$F;tTs794^)})5X|kWjA{q`fuEf zeQ%klnf)(9CQsn+=QsNL77LM34^A&loww^%3#Ioaqg|#?(thJNQYx%x_I^a?<@!yj zFsh3wWMSjs@Nod104b7-ojaKE;dJxqdNxs6bOWk2qxLP}i9Y0LBz(S36*(GWO6cS9 za9LU5mLb-!`R>5)g;?dW>U=2p%mriq>AUp(3^&*4v?x0C#of5eV<2=9p-7B*zQi3KtM5HmqM^p5&nKzA(WUM# zd?V}pyZb)$j`qebD7%~HED&#UAYQkg#UGhA*pTmsfY+ zKth*|!RMX1pedJa!8d+M+mbhBO%c%3(h$fSV*^8n_%U9v0qHj31LU1v-168c!0JW9VM`AX+ z!Dh!%?rPda>+_&MxW{D2^}=60g+&@QBEB~aM~D+Vl}lBX0cQJHjy5(Ym%DAQ^GmGn zsqqlGL-y`T$L!lfEw@;Y1VMeE7cxIb;X!Op3&2~1DDR`}gIklP^3!iG-QBrej>1pXiP0eb6YrEbHd4XJ~ zK_Y0Xw(=W61)-`PD^b0^eJBFYej%sJ$5hqM(lNUD^*2Idoysr+o@ibOuUZNrDbkLi z@6*%yBAmU6JCghlZpSN;w?|Tu$9itg+VP(~;Op6$_`>>%Q0lh^Usm~@IPD-ye%xI? zqEoSc6U{eRnBF714SIdFlo{36SQBbU71YS50%Ng2*jn8lgmGu~pQ3gm?(erd`TZ(T zORzI~D|AadFN{ARUZmholS9C(QpCGBNtN|{%0(UK!Z+T-_!F7Xm|OzRZ=E_gRCp{c z-!_Nx`$L{Cc%ixiQj(F5W!u3f9xHs>ylB`GP>@I=6ndRHoAlP$D`m#_n2&rgYv10a zLBQ}tRRuqS%E(mOf$Qs8tm2Qpd^J1OT#w((X7WtnWN3r@pSlB+ITNqo`*{%lRY6F5jn%BfL5rT`Fuo8lHeD2>im+PUC)|Mx_(_4hiu#o0E41 zx=cw<=qEkW?JItLHc$8*#%<3Fg!7QuSRvC{&r>)UTkQRuxl5_y9-WReJIsk!bALt( zGu~g`?DR$xgqnh)e06$(!izV&Ff_zsW5SkH_Yz&`gRT~}e~m$jp+@Ah9%Fc1D_Of) z7cNZJ#>rrahZ~=^0&~wo<#BN74|f|8Vfsx%LOg$n)$KO_PIuM2blR8%SKwm+iZU-J zC%CAgSBA$~!{;G>w_n622>A@)CuE99xWxDdJ3?h-aPpa)Qoow;)5Dr(#2>Q9y+6I; zV-n3ZhXe|!jeUogIUlW{{SKiXH^0wB>OwDC7Ya!w`aT=Y_l28i?g{KQ7V8i%? zhEt*xr;MD~;fXa9{FBmx)u{fJAK+Ue22B&4?E5;J)fK$+vq~rT{V=tu9d=A9*J6$w zrzvipyE17L4xSG;Cd^K--BtK?{PA2XKS9|@7uxmayT@1KZM+nlQYNN;rqh#2#VjgP z4sjFpVl3y2KJNz;eWl@n@<_QRK02arcUG3$BEPDGCi_{8#9iX*T#Q!Z;t%hx*8p^L zoH{iLC-!!9nbC})E$L@{_Q$=GS(M9=LZWeHdQA$K2mKw-*YXtOS1r*oS~8L&hHu^) z+;j@RNeV}qXN-QAkqGKt&IA)<_}|~+lqe_1;v3VDxc(Iwto-;`bQcuvX2U@=Sy{z6Aj5fza@(L$`Yk?P+m;nz$q+qG6>m1yl5rR=sJwnARlb;7Tx{;Q&q zFkBR=_U#I@~S zs{WKpcPHUIV8zM73YDt$BcRq?S5QYezHV)$P*)9{ReXH*)6OU-(`UQ#>bx{S+B;}1 zdVSe!e~`BNG$9Xpkj(50xC~?OuDuTUURbJKGrXzP{v;%5Y|WAzlWe2bV`;VRn-mj( zqfK>C>&C}4Qn-%^N$fM9V_`B0Ue#T=Hj*_n=*#XXj~$G(m8r<2&@@Z-%a)H~+P*n>kUL8$crXLb zHiP!>iL4{-x*!QwGtFZNtULY3+nRg-hwCNJA{fUdB%V7_Kt6N)TkL)RPNU+IT+@fZ z)yX(OC2cmBqHDIHlqJ5B4yAkLQc7ADLCtzgz}7EnZYPPa=#VKU86AbddNwDoC3yLh z<126PsJ6=u)`sthkcj4c;L~GV8|(;?P}`ItzYJ?H^OvL9#t^dvCn3a@4%h5w;b4Qsl=&_IA5Y*BNcH%OY+hx<*8q`G)V}S zLJ}GhB34devP$+{dZW#<}W3n-MlO+z#67OGCcC0lL^sjNv zBOqmirT|*94-Zf<46mN1OO<{ea42O`yppHyH?8NFD5Tn62BKbX!>iwz+U7BbHk8@S-6 zzLlak$c}<3<8aaMh8Mio{VY#O`8TLW4keyQRpd@yv!j{rj~FxYYo!KU2=$h`54dc; z;C%cJxx|5VQm|I~GluXisj%<(!1`utjah3Tji?43%y^c+SCbgiYIUr`{YpcV#{(ph zuFuoovz-IKospZ^i%Xe*O%u-&R+ck%jYrmTApG+M%s1LOJTz=E(DC)x2Pk7dHz4h* zs|vXjCa+USrzK&D)%J3tp8oC6E*NJ~-OLuEcYC|uXhPN=FV#088DW;aLUl{SzE3Ek zo=0j|TW_8Ie%du#J}i1mfQeMJK2fZ$)LJgcZvHIKa1{cOVmq^3a$>Ebe+6p#tymsx z5PV|kO)DlMtz!BSlWV%Lb%5LHK5IY-);|JM41Hi($&l+nxl{R8-t{DpgHMu;&8!?7 zU__c$5`*m zoN2;e9?BB*)_kicWZjk>-@7V8{`~p;a`wS#Y`=ZuM*g4i{uz?CyfDFU@iHZ`wk@$h zz)u?D-ZRq*G8;J4f92KCMRF6)-pKSuLE?z-09Sh+Fn zQs?4dJhifk2_@kj)e(`J+wzMR7QG8i0H5ta2cBfCDZegkd0p6w&{%Hxm3pMuy1%!?Z+jh(+{&(Ib101v+>?N8DeC=EwfmJ;8{92=A2TCh?ZDYP;V4=R5S= z17*D2+DKLsz<;ws7S?_}co9zYKa}A268&5&DP$=B#VCY)8Kv>aC`R^g^5!14&Q1{eWUQKMUlITLAfvPK@NjV#U}g2N zbg;B`Gj(KfcC%)s7l9oA%O}sj`INSG@PM$vD(ztEVJT^8?rdR+$f{uJWbI)?#?H^h zBO*ff-#6)%bz!jXw84Y!zpQ=T_5~mH3MS%XefB|H_0PvH#gEvEk?ml#Bt6@%0`1|9 z)#BxP3_@9C465Uybk6>G+4PrJ;YEO2{pk~He@~#2>5~T-;4fnz>)cL%# za10J{6;ju*5ZCxl8mio{jHV^46_2)dltmwFKgn6^6v}%gK|JpY`g-~}{{_yjNts&R zO=>d$f5=*CJt^zE?&f=b0NaoexXcMm)X5Vrhgd$94*T%}wxQ&Ug<3Z$8|tL2$sgmN z#eON5yZcULw$_}hE?$?tavv1Yor#(D3eI7-HkHP%zu*trspqaXRbxLnm5^Iw`SUqQ zg(*4{5X6ba(YF_g^EhFdZb6HEL0HZ7)P zZ#@2CTC1pTHqYt&mTs_<<961XjDQjvX2~bQX)x;XK6(<@rMShu@QkY@b_s`wldD|z zo9dhB%;XohLtg_**jbX1qKw-df+KJZBqJu~T1(Z8Yy>?@=WZsbLBr6Kvj$E-C086&Z8A%S%9wW6J~lea zdYa@H|0#?;TRRG?%}q*sTsZ#_{f(SXJtZY%M5-X!`6m-Pf#^!xO*4@tZ>VLth9pMH z**qal11A-75s6aW4g$hzrH)q@ZpJjlA5DJSeFnMRJqFaHpS#2z>yX;v0+*4NY#+-= zYkuO0712(8IAF*4fHd))H+`B-FM&x4#y^*#g%=t=JN%9=>KmWyj=@SaDi+Ldl^~T9 zm+~JJG(m`Jxv}{lX`jyyeDphjD#Y=a zborBC{KMuiY?Y*zz>j$lUdpe2c$QizaUW}XEeS3`^>SFAH`R;Nn|8;sMOdW5DVf-` z_GZ=N2rjwhF|#id->R6ztEk}cSGWdJHtH4Vj1i@IlD0?V+dd18aia0R3?Dp>C+2Xr z{ggLk@3T;6!PO2P47NTw@j9BIe{iWvS4D}(*e3l#v?RPJw`d`6$krIc_O7*F~3}w8d4utZy5!(a0DaVYX=QaoQC3cKu)+v`KPbxlD;MjDx%+1 zDFB+WtKNL^+IvLJXE;)IRX18ctAR`Hulv^OSZ&{j_k<_dBF`Jo4#DG3bt!G`A3qmf zMtk`-(H(WoE}k-4qd~!(?jJzGuk_%@5AQ!X>&;R7YSVAmq<58BDcC6Nxy5$!Eqe9P zz(mB$$XIw{{J4?(Vk4?UTbmORS+s{p>UOxoz2CuaYH@~3VXa+%xNYDf035MZzS30- z5eV`fVcbdOo7$AyZ$u7!T*A|{_@g~9r==}X#59^_&rJM`XReEy}?_|}GD3eYpP zfsJJ7cO|%v{l{@pQ%AkR{Y)G9vlnHt$Ax0b*3KsAhu-ypqVe`A1*B!J{WuTbyeeGP zr0f0_XQ4gT$eoJ6ZkGk{lG_J{=y5p#>%JV~V<^8!ulB+lPXuFp{L)I13me2@!oQlc5lybud=+w<61L!B&GJsb3aPHGKR^WI+YNPm z89Vo9+>l!cTRKaSXuvBU?KM*ZXAt?Uz6as4vHWZ_g8R~2hes2`CX;ykRK*>Nb!k#u zo0+3Raj~pOug#PaCREH<88Wjl=hHgoptY(HeX%7NGTgU{$}x|Zg1@)r{ahW|iDQ&i z-jfjFKfQOs+xXGyQ(ZEn03U-eVTn09>_!0d zV&J~KP`pdc=>W3|Yq@XO-R193aJdgPM?<~^jIGUmXxt+maXH=NM4fB&0qf8PKRxaL zhF;l(2_6kpzte4b`shCfO@IF*E#S%tRe5C>gcW~&2^|hmF2+6TfG00P-WaGMYbmi( zSsI$!Zsh&f1gr#Ip?7;=F(yYsLKbR8T+6JwhKSXnc=GfwrXJt;4zp}q6W*T=3qObO z;STPPcsWjwa=i^3irg)W_NXt!r=;4_hM$X>mU40xug7Gv)li4Z-wt$I$y5DoTJ!sP z1ntb=1&R#t_U1?aS z{0A2K>S$^W(e>K477$g>#|MEVvX-{iHjt=gPJTpI31Zt@uLMOPO=E*%ka{KkfS4R!{ZxhHpL*O<$7cltE*r5v64yrk_Pt-uqhTUrN^v^_;)d z-8P_R-A^hxSLOd61mGSpd%r^1xe{5Z+9_n2=cDf*rNjL(S(Jlf9(&pY27@th9;iLX7s73P_umc7vx9eZ zTrvCYh0x9>WQQzyHwtrj(oT{_mLIyL!KjxaU#?u0QX97_p)3P1eEa4f;sP^g>`X~h z&Rg^`Ehe)tUO7dWY*ngHd*%%T?4xh_**!>K_&?}>+r>LPuAd0oW1lg}7tnDlL&&wG z;#x@B=LnIcU&Udd4rNreLOzrsMJ!gn-q*z553ClTXKjDqj^Ly<%Q0N2+${c5}*CeHG?V_;pI_f zE0JZn-TN8#6De0^vdKg+)x(6NN#g#4ERP=n78?7K6HKL;a&jMHLU}d1`5ZA?b%m*V zqYr}Wekl!c-I``?u1iNZK)y&SB%PtuI0CE=(%<5E+Ym}=LmOLyZ_Su9AMjC9ef^sauV!*>h_hpwRCCs`6}Ek-bL>0 z+2{EjFV=r$yy9Uq{35X~2vbKZ3EB5Oci|ndtcr<(NAbdt9&<3lm2#H_$#ER?fd%HA`;Z_S^VPNw%>sWQPK@7 zCHUys>ebP&yEW~)>fZ}+`4}>ZD~t`a;YhV((q(76sj@R;-W4N(T4b-nWX`i-TWnK36pHzB*es^?g&vyfZ5Js$0y6h{Yc{u8=dpDzYIFzq6m8QZ#?y9d^H1>BHrs|7f$ zjAR|S^7hIgecs_cpaF6El}$5800OYE%viJH5{L*r-9hI?^|s~(^z9+f~)#kByq%!UzU0W^RCl%3w6}l-v{Xo~Qd`;Epq)+x`vb#}C)T zpujaRA0IWFojUys@Oq>%pYU{=%&;z#d&?NhL*SU!DCM5Bi;9`U!1Ty z;L{M-fe)4+d+jtjr||P&BIj|^VQg$P$o<)U%*sHhfs~-3_U(z)A*7;B8~>>FU? zUH>AtC&4)}f3WMbwlkdw2X-Had6k?z!6tQ#rc#c+Fz23`=thqqhYjEK>b0vP&XG&A zQEaU9Ziky*7+(%P@9F(}sL#z||DNT=c1r5BDe4dU@rk7%ni7@8hg1#l6mCCIYOOy!a*(15~wd6t+&!z{No46baZro zXvaM^llcqvxF6uz!e=HSvj@o@1TGBOI-_Tt^VNLN`%3y6~9hoS_8gqwm;n8!FOtl~-(>TvA+_C*C$m|Kq&|Uo9 zb3N2KCLX3hBpFuYSYhhf`<|P{)zVdNbrht*P@LZoARV*%4iQrJnf9<@(-q}d>%pdT zoiuPj^S)mg*B6aMQ=LqQ;JV!pb;mgkACGu(kM>M^gIinqQuxNDU(n1&YLfUb8tq&< zonDe=z5qM{H-GgQWIL_$Re+FB>IP5C{f zl)a#`yxlrcM)oNpQTH(9AS)1)Vy!ZYq%NnhRx+PGJu{4sk@Yn1+}h8my`r>i0q;5*@+)`% z4YvR>tJ{b*L`l{?tcijukHg%@qYOefAFF@J0H(^b! z@vTt&m&;lZklg{iXU7+cjCze<01E7AY$+%36AI@@QMiE?NfqSewDdNV>hKcMUeMG! zP*8c4S%JQrPY6ZDuL5D=V~15hT?PXLGVHBV6?$yJc`ah$g%W|s+Bnr%kM|L|{D+(_ zsVSztx)pq$b;C57c>vBdxsM?Rb%NZ12<#Zf-Pb1xYYp9x z`-SFc&Rs4+L6*z2(13`430M4WnhsH|MeBUttsHa8ex<8zDJ-&Tjsri7R#}Cuo#Ecd zC7_>|$*65_hU}|hk_QC5^QZqm$?>KLZ9DD-XeNByNL{; zL`Y3z^)s% z7eAWV7}y>wy%cjj9wYf|OFBGZ!4rDbV^v`>tR4X<1i$S}kN9NjxP(UF zwn1gUE*-Nq!NI=lj}-UBgrS!9($=2AypH2j>R;}Yue+h6Ui>=|e^)WY`b({;_EFvq zSK&Whnt=0sgT>E~N@nP!Nnd9l%F;lAPTs@=@YJn&TQ}G#M<0@x7CH>fq752YFLvu zjYTCexeafPi0&A^6s9b1q#P7q$`oa02Q)YVn&vnbYO4oP`03@91Ygln3k5IJ`FVKQ z1&Fp4qa%O5?aN5rM=0Bj7kgUz=dy0luY?$B8odB@IbC0~qB-52LC=H!w$$9RpAL(L zYOz$clLaw^%MYjA(n5DkUw5TDU6dyuBp}<%;fTMp0epPi(uAQvQrv@;x?u#5!%{(H zO>Sy?t0V);^0Q4w@3mqh%>u6CV<&VTlXfMFM?DZg;Tk<71f=6-#(4k9R69CZktX0O z#r%n9%LTO4JJ5q+R!<8G?B<{N;mtfaf5(}4ML!8gDqNU(r)+MDdcZQJtD`QdsrVPU z@s0BBZA7YC$-@(%{a@>qbhEhG0|EL5i9>ydy@Jsx3ZgWZJHG^CsY`3gS+qxS51K_} zPiRGxN=fWObfc!;#3ux9D#fxJ{hvL#&IF^xVa7uI`y}yQAa!8a1X|AOYVDh^_H>Vz zg($)}C0uvFZoKIDzw~9u6{W=5$(4>~?eLvMd}~q{gY!I>iFV0mhS=!PCQDc=#++MB z{qX~^h6kw^J3sO@+YL6lVtAe<_`sSRi{`O^S`}fGq@DfX2KE*B!UE)NRZpddjfvWKUbAg(e{M=H>mo;X;Xp*hzeH1<(-Z2VV(fPgOKtBNKV!fZl>6h1 zj!7X(srzi*r&FeW+=*BLE({#0WX~6~q02;amkEvv!mS=jhuOK0x*-z%oy_K}DS@L9 zfs7c1P+!O|p+EZgx*qa}76J|YY?gn0aghejq7&|g`k7f^YJi{*(?swS2*uQrl3A!~ zN@as5f2b6FkTDfCgF?AXgZKDi(+7p@L_Z~gamRqjZ^j?6#J!jo=zJt0(<^!ofSEoh za!thC%Rsyhwt5}EUvFVQ)(7nS8VPw#efm*{=87*$9fRv@VQ9kPfHqqaB zn_R0RKKfVm^lAL;pJ0U4Rs1X7>Bri?wsUBT{t1AYSV(f6$dwfFP$<$MA&E$$_t@ZcR6uT*+8;ED z*fwDu5jvqJv>#vN&}dYYYCE}7!IR$DUM+sE;$QV-JY&@2N#Z1ZA>u|pg&An8F!d4c zfp65R&kVgXVI1yJ&4QPyemdmy;p0Q(vG$^+^fderL#+H z{P*v^wkl~G?7K1vadI+x=u4Jpfw;Axm-*ozmR)5y9>BFxc z(zj!sdlEFi70gTSQ;&6Ut*u8$tz8k&lBp9LBx7>ll>(Y3Dps9?j6ZtovcL|5*}%Y@ zYI(cyceB?kC=um3HUU;?k8tb9_(h}{YOceHLu1m*uyBy+FWp}W4nW%iV7$JZun@b?ym>q$&P6o!FaWW9)Tv@^k+6TaJ&JAof*0+*0MMJa=Ow z%+q%%e`-BMqI5(wb&d*Hr9X?k`(7-izRY4`c&O=H1kzlgg)WRq-Re-<0 zm+AT24AeytyyV92|)eNc&J%R4}hzFw-658wGz302zb;eu&SVg5@d zFP+Sh{#?fE$BYUa4yfwJTK08TTiwW|>%}xc6C&x> zV~uiT&lamnWD;(D_u@T-d$@{=%3*zUcy8)i=%y!RI3q~p@~+UQ%3G50=(854kIHGcf(Smda7#UmWY2 zTCh`7J}U~39lDA9kQiXoBo=dX>!^GWQg(S4w&YBkUWB)S*j>xv2HP{_TV1EtS=)LF zc&Mf!oTXIJoXfd&%;pAF;5c$3C>0=^33dfvZ|R1Juw1f6TR2cm0b-S0=TDFvGaKGW zc+1bF+{}2IVgDeBJM=uXdZl-!rx+s=O)i4Xrtqmo-!kK)+#<>qZx+alM5HaLIrJ&a zuh6}poq3XUG2j4O947vgOY(ksxA|c55Y$a83D$|Fh>O^&5}rtT?&y zs2`?YO6zn;lE--nJM69%cU{%?1opVM=xw~!e#5OP2_jS@RRsp1Omt!rVj&`Dxdu)L zicefUZbt(^cAkt~9t2N~6?i)tzb+{$DywGIsr(uTgyQ9@6NbIn5>1k=9Ij$VT)mY1 z9S9KXFT5BT$0gRUBnrTJER>TuXl(Xc881;fIRubkv5rpxZ?3z+>;BGpXqL1CX}}K} za(s6XY2^D9ei5)x6}LAyO3`EeX0jc)-2<{%klkWh@Oc~@&PRauBl{_YL|e3TmU*=B z;bA`ht@di;&%4;e*-p7n$*VrHqql|V+Q6)7uU8|WU#-RQtP}QR!qyg{z%D@`&Y`SU zhv`1*noaT49Gn=MS*|(Qqp{q~m(S44n#u8@R5f5_JfcIir^2NO%yvC*dq0Cuiqogt z+;+(6JBYTt5+D(hC)J-BlFlDCJv)Oy1|ih03_=+{ z9SgE5B+9P6CU?SBzQwM96^^e6!B;0lbo;}a%kgtl9P2bAi=ypd6osNDreQUh>qJO| zCP7(W#ZWS2a>O$Bc|GJBp7J~6!rdoB#ftTNKh0y+!0~q(c|?3%@=J5uZvxcf{o)#+ zyG~q_Q{vRhV%ZA3ZODEaX;LRK~wVdMA6rU+h_4i?ox-4=Vyj7xib%22RZM2 z(jfbv>*H;c+~>p0ffO9;%I14}@l+r7m17UGZa?1L=~Lgzn+KDS5Mos1YzLg>ev22j z5;>Sz)73QN32WxCHj|08*_ho?6a83Gm_Yk`s+P$h+9*L4oTnHnc|K??ZobDQ^Klv8 z{B~|Q^NcsW75lw+b9Yv)h14G_iJRMd!-c&yp9fIU79b(&B;|-NH{hS16F;&oj;RXo<7^2-295^n*I$)3 z^!evp(Z?+U6jAuGd?KmREHBQ+*XOm46^Pf(^x&|+H*XL)i|#-u)7tMYriqZFGB@p} z7UU^+%jc)ZM~?#8i0VH;WGf{3o^;!cxGgXw6(R+fKYYqGDhEfJyxtih9?yI%ms82A zY}3b~8l7ZOn!hcuAU##fn&+CnE8*YvmZ5KC(gg2a#$Mq@I~R2_G{zmR`Jv#w7UR3S zfuv3CBZeVcyi1(vIl8$87S^6i`W<8Bis&`@Des{~OT^o@^XpU(Ez7*R+fA*41-&Q6 zp^-lO##ovv(8kXph+X;W>82P4votz3 zx|2lo6L@Iw5AtVDdiu*Fpb*Q%+TXqSx4~8Xp_#fFL;v$>d3n%nu#9ue^l1OjXTZQa z7-!onPWTYELRw}hbnfq8=gUniPM?gUdgjGR{`&9wF?yGdn&qAtt!_DAokeQ*RF!2| zyVE?|#uuaA98cCVA@g(SfXnCfjM1A3V(Qzm&(PO{SUGj$6y)NtfT6Ez*G&b5r_O{5 zqtjM!44PapZ)?hK1&h5BI3fjOo(hzkbVI_#1-JPbJ>_iLt34(8c0c2q0|H&U3;6`I zFG?*8kx*p%Ncf31=D~zE3ZO4|U5|x0J4ob?-uGW#t19Al``ZUVyP>JA!kq;dBY|fa z;L6kdswz^UuDfJMVh6zQO;TfHd0mlF@cn8i+N_!186leU2XM8_r9?1gYVTub&tO(- zR5Zlz14|`niu@`HaXv>#C&C5j8E~-(i6K8#l~oq`CFO5528Fr`&BO{Bh;S!17261t zZ%Tpvxeh(g81s3hXE%_&0cUsadD|=RF}UnJo16is19UhUdMq|gX|D{o{NmOTiN~6V ztCV}zn&yk0W9bvI2ngcp-QRGF_f_t`p!LJTV2VsC5i#n;kxixTT8Yu_1n=yY8}P() zh>cV6u?->Z3n+sl%f_^O|B*gEZIJI@>8AKhI!5{(%O7_` zOETE241+uwNh&mQXh1(}Bb)s)<8z#6N_Em;JV2K2NKxxi!tje^xNBU-uPE#m;{`VF ziuZvBmOK{e*yC2inCG$3VEfO6(Vx^ETx2NSi6+1IF%PNtb7qQP2>l1X=#Q>?5 zPzX#=%TATTiqb!!pHfsDkecP7*v*Z9mw*&LwoDk2<=eT-=w!;8rcP0uI$0EHNuDHg zw6!Bu<%<5xwHWpJv_I8=EXV#{bMbD``Lz;cOm&+w6jo~6B^_ov?9jHGuV6p7}uG}Ks!YOFn(wcXroqLCUb={Kd<+bfNp_|@p7BLVlrkpAIx16b?zxOTUa z&HcfWZ_b8Pz6WCPNQjP?4&NhJB2Mj{H$mP*vhwiMXY8pzC<{-TRsl<&M3XRh$5t?V z=T}tZZ@qWhlw)mLAID4AY6tUyW-eM&5v84$it&5$<+hfNUw;L0(l)@_mw4au@w3x7 zh*S$#{-Je;U;0Y2^lf9xwMp&Ziy{(A5_hl7!eW`&l9Q{9Mxg zYi^QIue7w>@k0q2*(w;3*~JorOdUAQmh#!fpiLYupyn210GU!=3JS(q7!f|5{vRuu z?07j$^TJM>&4?D0ZUqeAJ^a58o)B+ZIZ$#EEv&~8o;qDWt1ycFhMyyJhEl}Tu0P5E z2Pcwfu*%{Zu@%jkE)CI=qm)UMorXx9f|fr=RNOd_8}nUB?sH)dE8U7W4(Ehl&c@*O zulICg!?L}e{>2in0@8)8^Mgb2BVbk*S54s1jx3u5^Zlz|{_3x_pZ&A&h_<`vkoA0A z8SF-b`o0Wo0>AuhE>2fI8_3KaW7yazrW!xIJDbRqtc;e7nUbDI{cFn3tonD-8eu_8 zbwvA($}*JpmbdL`ZB}Q3mI37jn1r)f$vxF2@vKca(5`-xp3VG#+o==nmQ`jK~V_lqN|IX+ZSzke6afExDfo zx}|GFMZ^H*XBuL zJys1Dxj+)w~7TRp&cH2cRgx9_t^NI^gTRGlxNR*7Y%ggm3X1*$qcDBg_dq81?omD;Gh^!KU zvI+q70xI|N!zOK>oLf_C$t{su#AXzU4qv`L$+wOfar>NYZ*L&UMy))T;9%B;aMzeH zMBr}gv(i&lGhxH13wv$wod8QFH2YXze0PQ~tj_p+y1!C9Fk9ueEZs(&O-9hP1C=)mbd5unac>` z10xC=&pr%JRD&Rn4~pK6oT(v%K)JicI~+WckM;GPMlqZ7rNy6?D@k!Ra2^{V*r!VM zJzplF9U;feu@=SR#MJ!_iWt6{A|OfZ_D03MVetR3_T5oUH(R?ZDkumdO}dDHbScsy z(nXr|P86i~-ib)B5s)Te=)FkqM7s3eq=()KH6bLqdC$G)J>Pr2fA3nXMOGl0`OWN^ z{p{zNJ)2cmyWfDP;QIC@Td&+NOm%-+NuV`k^Ra-6#KM5p*of#56%(J)9C$VDm8akW zv^hIL7Z!1>d7tQXd6k47rW&eC{u4cxZ>ExQFe<+jbu0L@VwPIIt=y;4vYCTC7wc=L zKWXX$Rz=1GDHVCGEU}S=y&6wdlo(px9!wGoxs=%tCb_|k3F;lPVUD5vp&vRiO1^T|BJdfn@H(@)^H)h4x1|d1-8$YvGQN&eI zM*^xS_TiDo%DerTnS>k9Wjq5!p(l+6yJGZ?#oH`!ES2wqHAg6;e|u4LUaTi(t%>@F z0KcZQ43Pu3^5u$FG8mkoD9?d?mIt@Dj4iB6BBoh^I9`rQvfP_J8x_-7_=$x#!poB0 zSsz=nT~B?uCcb<}FHjP!g`WeM<4WiqVm#Uo-j4457EAwCj%qr{P=4C!MxQ!KLUlDS z@N0yyAikM`+*^^u*e!dWfz53~R*wjV5OC^x>=T_ElB>Fo(Y8N|14cCSdUQmzq;F7w z_f|7}J~twPFw0N4D;J|5xHzoN;84wmIZ?M9YUuuNKT}X)~I|) znsO_AMNyYmq|xQx;q@TtOH<}BBy82xu*dvhYM_ll)Tc|U?fTSWd19*jDdYI;_&)aJ zm!sAVFol=ZOOzaPmTV8`yhSpb7sA)oE!5h0;ayt;TMt7L^((2qc^&%B+|Uq~7t%N# zt0Us}>DO4~y7leTvYghps1utU`r;hLg&O;JtR==(yNr(_XVeBQ2eXTlXIy=U#n@d` z@DIN#B(~k|D`n*+Y%>vjY)#<3%?FInXX**{)Qy44md8FIQFt`JY|P#LL{-{&`aS8L zU6xvw7j*5ZkLf*+R@6b42g~tYH#goY#zSI$)d6dv%=ka_Tbx}y;2=+@ur0a6+jwdK zG#KPySaE~(Mm=|S<|p4RW@FqDyCKqkNmI;70yu+rEEPF@e1YIyZlDaCrclY2C>&e+ z)*x}mf%;H*j@Fk#^Kx1A5$#bidaH-6-8YbTboI&Wvrm_RZSH_F{!D_(t^CArz450m zkLp@=?M$z|MZ(XLYhmp@57N8B@F)D``4p1LmBk+x#3T@IYdlo{P&$&9`hx#OZP2G^ zvM1xLg~Ac^-f~6nm#aT;^cBW8Y}|cj!6XuB*3BSi?fZEQpj#MjtiD7YfHvZ{_JEqrgM0$l{$DhvKJPG%y6cJlSplHw-qx{+CXwlN2w}1 zz=XNfcdSqU^myh5;))N%Dh^J*tL8WBQpi!4&b@rhVHU0+*sV-w(Nz3Ez?wJZPVIXU zenUanb0>DeOOL&9q)upQk0HY*Bj3G0+1ILrZ;g_x&~?Z}B@)Gu)O~z4eI{3D-d_2T z8LEw6fV0v(5K-t#Zs00PIT%$dD1Mt{3CCD4{OL`j5G4z-&uXIz5h0x_TY7 zZ)))ulM2tIo_Wz)ZM~_?2`A8qHTtR=Ko{S@Me!%W%dw2T;Hu!-DsWn*>Q9dt|7T0C zU;U4n9%y_#>(1GFAZTR7OiAoy<6Dzh=HjSfR~t~b4+^(`>l z3z@@Ra`({Vt9H=`teaSa7%!*J)T{lXut>rN5`4xz>zkLx-a-0Mf#h5--H!~I&>wQb z_$Jzm7WxYuRPJNkj^qML-U56GMtYX?v1EGJm|oir?s9YM(U)w0(HIe6f^u^4zS9Bv zxno7y-Vw9C`e<%aLpm+3-fXRRQx|rhcs+oBeBp~d=fJ!C(6k!cw}S?f3mlfPjS2R&4aO>Jo2^C-^ff+- zN#R(LJwQzATSKiOUO;%n^qbl-qWTUS+mep-YYma`DtfaVneN|f zlX4W{gKHi4N;bM=#s+2YMzPDzynZxoXQh*EnwcOGN44+53h~smb*adCbeqEmE;Zah zF8k`a`1g2n`f+3aM<FT^y#u zi_B7U)G#G7i6}f2JFEl`Rq5l5=LgX0Q@+fhE8y^htnzOr?WDVI4=A$X581l=NTJZt$awd`QVndbVq^#rtP zT=d&PPF?L`PLu*K|KQVtZfR{&v)aMPAMMaN3{{ddn`-0(B|3^AVRrMJIm;dVKSKts zqfv~^xUB=2fme6ifmmg7neO%E1_9Nhr*&co#kl}$RMwOypTdliT|cL{;3rSGAYWu$ zvVECD+0E{W)Yh!p;Fk^5>=wmW9{|I0pRB}K+WVN5)^oYpc&m~2^KLV9nOzX$3S4Dd zvjz*%Z@I;GdVu|fa}%k-|^o*m1gk6!}Wf^Vu7auiA?XZ z?Oh}m8Jssd)P9dchyiW~Yux=+8qcDUuDDL1p*h(ZGpF8uYO1O`9!mOaWO z+XY|muOpMCF|s|nY-$X)?h&^Gv=iuCOMiR>ba!!#!zP_S;pnjn`?8JHY;yNft%HT* z{ypWGNG*w>^3oJw(U6TR^z@eD(xXN`2)F*?$9u|hIip6 z_FVqEo#KM7)tIq3AHl+lR*s`Pf_S!DE~Fm^u)W0c=vk6HZh2uvq+(3u>`SKR*7}&j z5@L!>_CMzJ>gZQ)GVf4j93CLt;v_nw?o??ed@=4fMPh&7@j5E(p=olDOf=y|!y^Mj zqme5r8Pcl0Gw#B?7=b=;rtiRyjHw=-6V}7lN8%2I=5yfV3JSme`(tJHiiC$1yVVdj zjT7yz2M^4NVGU?DmlzOHXgU?X-;H$hPQlCFBDYhZ!>OIixXR^{wl75& zMa(%?fZsnXY7bwfY#R+U6aUe4uU!M}2%bB{`cB|ZL}w%pA*S@W^fs8Xi?T?~TJFQ$ zg{NOk+;?$b&p;-M7nKkl8DVo3$D{^3E(IWlbn6@^DjgV$I{sV+M*27&z*#7Wqv?Kb zTa*1VVX5*=YGw!y$G9Q>9<>|08fL<()`;hzD^=P$YksMKl5oRaK(ZtP77dt62N zx`J%E>mfo`uYT~#eS^-8dTw=-j~|J2yVg96_o`DzUu(7s>9Zk+K#Y zRcVK6uhferM~NEF+JSV?vVM=N)ChDZ_lCL(F0IpctJ8Hue_Ql$iQ>)~6~s`puwC@W zB;ULoXjO#`pNiU8ZWZ?Se0uoWj}uY!02&A%C%Kf282RAhsnEYcr0sZojOv@^l@Kem z?}eCQ%P&W9;em^!Q&J6=oYdm$!4y0a8dp?K^19z~SC_ZC5+>cR{!o9414J-UVrlJ7 zBk5~EJ2$l8oQA-W;bDC*BzagJR8)Kyi`=g{O<|9ud_7S2$u_*s^3k=l^!*tsOf~+9r}h|Y|ifk=Hh^gY>++x z&1*?Nw(%0Mwia~ADD;Vd*W{DbpLvU3T|Y~d3r)^Fub(eC>Aj?h8Lf{vs|-Jil{9#Bi*YQki85% zyK-!@)dq_ou8$)op=RA<+{Aj6nY5L+QWwkvcH}19J(3J7ylF8!OBHg3h?}YuL4*C0o$oB&>(l z1jf9)a$10#t${EW6`N&>I5D5KAihc}R3_K+S{h8Jfa9EttF~aeb50fbm7_o>|$FkINNu;tnw_f3Zl&@eXrOix%-O1EqkA%NVM zdvrF7U=tOpmL=*q`7#Whz>dZ8b$9|VXayTqG4;Ztv=0j~sxT`C)h`}pl!?NtClnIf zNDvj)tUaGbg5r6%{v;_&pUN=`cclIW)^O}_3mb$Cl>Ovzc2xxsW~plOHdKb!eieH)=b;W&@QlTYuQ(>9`p9I44J1+gQWgDcCgzq}7gJ~;TjQ%3{e+T3GI11jJTkXKY+ zy%6~yX*Z~o=q&Eo>{08aa?L?8<8(S2{9u!b=L2s;mC9iWJQ-8fSK6%KK~|@+zc+p* zf@0%h9-6FYO;a=r)iuVL<9_QhGP|qB|Bs}@hTD+9GmY4gu;y=J{$zU-6k&HB@T2z= z=qj$Vd!LnE=WMNv`!m;;^{Nn+a8j7x zKj62Plm{z?79mou)c8Cpk~KIALC)R(GlQ&ym)so2%0&8U066bsP-Ua%z?_>u^XyFh zc2sDu##WhL5slxYi5u~BMoSWMfGUgm&=d&1VPQen+*?MZo*pB+o+UiWc`4W|p&Mt) zoQLbk-x-@wZUin}b2>yUKAm4^hS=j#*d-mwBmU8Ofl*kZ0dF#A#c;zRF5~S?_VD)Y zb|JXAI)5mS@Svt7GqF6gnU3DuHa)8W=emIp_5GD@Rs&l9F$0`YHhK9*(1<>Qt!bE_ z$uf7a6mB(sm#_wy-O$DSXBcs5gDY@<^J90PFW&uvDH#@4bX52H zjgzY+x-GyrKGF|_F-d~|={)W!pqz+MWUJcZY6#8H>a*7}G!)N4Y4YQUPi6zLWT8qO zp2&qSuH)e%&si$|*$mR(kd0wT{xL)|%XL(?r7DOig-4`V9ioL|trN%X``MZQbkG8U< zCjQRk!@am^34x@3H6xdMBP^_xh`)q*mcG`p{S>s6#;d$dwiqL9oP%io=OeP*goJ#` zS97WUT6TZt`A?WpFjrWaN7DY0*yO9}{P0Iv=}PGTm>Dh$5|cSx$mfC)Q`XHTn91SN z!f)CrYT*wCX0UpYg*LlnS4>Le>HKF=;uaIg>xAryCRdrf37a?3^EM8}X_lGTDw#&Z zZ(<&sZ&~IoV*Hz`IA;F&AfF+>&0#Xm#I6+C@4WO3wWDel`24ux_Nvbq9{XpHLP#8nrC#4(*&J}k)h7P^*bC{J$f5W2*Gdxp zt`Q|kzn6gO>C`_z@>%_iyT?U?l2eD}-KI^+Grp=sWvjTC+CPf9v{|X|+5DYU`q#KF zb!@L}u1!u6w7`os?rtlG@+mygvCuMM;b>HeZEny1Pm(0=VZ81EG!CR+RA;((3x*x> zXl31(D>CphCtrSH=GXQyPCl9Czb)g7(?MoM)QNLjJY7>v#IpVdEg>)a-fgcG8_nWC zNfrJ7w&BP~c9r_4?{p|j-gyZi6somv<*OtKx^%0Sal4uy+VZie{U`Srm*k8+T4iHp zb?Z#TACP}HX>#QIsZ7>O;9W}o?-a2ep8T@wDYGXH{9Yyhd=kP!SoH59yG9FV`^HzFpGh51DP#uJV2XRtHB#)DfiZ?UT)ow=;3@&kTP)bHNO<>*k7($f7a#fo*zZ(xSqC z>o@%dqBT~dEgm=d%DUY>u}}~H8c;&QMEzm|y1iUn$gy#DC_KgnShGAhx$Om~-7~82 z#D4#t0av^^-lkn;d_0wM9KDW_77hf-eqp|@gTxsH_`+RYh=}A=f)v1!VCvVGy@yv9 zk5tstKQx42!tlW{DoXut*oDnNzkf%3`!@9XR!bUar5>NhxRC&ZmB9QxrdX*PcyDTB zLK!7x(U-;frrn9rrN?YbdX)j^L* z3PUo2&e>xQgenBtgdxb!5Y!qQ9n`(pFJRlU2l6e+?Z}S~t3$VvcK~el7QI8#hbw<; z*E^(H?{9AmD})60-;4rKw%RIm2jL;U{8)e4|3)Q}2 zl#=k+!;=a`YI+^)c%KN{&wWA3WIN7buR+Tnu&w8voKaAVLC;O>cy8YsCud3}dKdvE z#jd#f|GnK|%MqtuKHbtR@3>_ODomGxde4#DKpxKG3`xIbxUkwO()!cjK$35>agny^UIbs4MaNIxfv-d(^^{w z0z-mSDQkxx!FJs`3yLAIPfn$W;ch0t z0OTP|eo)EZwC#RZh@1WPh(`c=x*?i!!o}HgwJ}}M(o*PQz+s)a-E3Kl^BTXS*JmjG z_OajfuTcQdpxuACI=^%z^H|JdFQ6Wp9~ot5qY&u;z|38ojV|FT`iOvzm-{|!(Dp6c zJ2vA3`_qMj(ZSUf#_hfzurQ+ zezNN3)aLQf6}H$!$fn-zcUrEM+t*$5DlR4>V87f;t@Q#3%BIVEQQvr0N$?0}lC)#C z)YX;E4KjfSk^wtgjx*c+cd1HK9^Jq?Ple+$z1L&Oc%iQP^HBHQk_NROdwb1`0h=_- zzdrx@qp*dKuP6aW2w08yW7d%s!g0{dc%cXQZLRjWB1)k=Vt$t>*>F?k2=(fdV`>8l zQy=83v*;)ea_q${c&#}Oy^_8S#qLJ3U517$kk|u=`);`#@xzTQNqHY0;IZU0<%lAdrh$+ z6S=PTfFs`UL>M?Kvb3bAhjg(xK%G(hvWv}oEn^~qW2BMwMILNLebnD)Ym#@B@m#!F z-q48d3UNL}g-O}_pek* zKZY*&&y%8vpHHpjPqs&aM67b_gd);&V7JxSD)T2e6*QuG0zH@umJ0oH=O&oP1S7xk z!4DD6n^)Bydh9eh@?B!Ps_#cH#aeymZ+dah&RZ|lGq&7?U?O571AzDCub8<5%%B)3 z1GEwg5(pIhw>NR3Y9C8J1qw%BPf1EiQOlThUHe&#Q!Z1G84BuHM*@ZI8@*QAgT1xB z0z=l9bs@Ro*p(Zf=u(bMFaSeT+tGDewdSJuD3PGIQs^lUub>PO)9uRe(XLp;w#XrekHNpwkZ33_zDZxphxdC3-|EMri( z?89hC%95O{tDw;P<#^Kug;*bLZmy8HIWd3z8h1{pZe`8>7HB>}XBB`x@8C8%0(fEA ztTonN!l)>cc@2M(d)5ydWFbtb0(+5u41xCRVcb8l%YMgi=zpMSj0 zQUyN_K!5lZw^tNrS3EeSkdI-6RNO!#Pm`e~sL^7kH#MW}2Ui%HY}oidrke2^`sGf4;U#V-!JKq~%^o8S4QyBtKQD{ft`>r2 zKnRQ?!+tmf&P|}f#}RON*sx+!?@lplXB& zS~u=9`DXN5qe%i-_z2%Wn*_ccwX<*e6EDl(ksZ(}lg@iRzMg^IJv5dY4X%jTE7V z#tTY5LzxXv6|>+UOl4)2dD}k?fLO2xvny>Fi15&rm*+mNf^vhy@(a`S;})u8VW;Sr z2%X1Io4~!@k_e29pj0brTn{LD-OmO|Nt#_!`}mT#_U80Bk)_RRL_D>(uC=LJbZbSbD#+ z1*f-~?Wm(&FyNZJz1h7gz1v9m{7~R0qb+4nt)(hkq-H#qhX~C#P?kB99GDT5&I{aN zv%ze9pWfHy0^*!N&$e8(d*7vr^Rpq-S0Fgvg4deN)~JzL9M)rBXwCE)28p@Gp93>s zNUjRsKmS($c4`ns``q#l&hyp*v89Lulz$}t*pfd8KaTO=!1-n&l*D1z()km=mOl-E z2WfltI=XfISm*DdpmW(AwfwK1}c#P|QVj)=n zwRJFnb}lgbDOtE#kg2O%qOiNd#|Mkk(;mBZvtW8a;1h_@Ov6i5Hh1M|YU4-jVpDW; z<-lwHg?h=cXs5OQCzN%?Qcd?bj?PA*{3|PmR{(FsiCx7k(@lURi>TH-iIk0US70N3 zk4d}#YsmmjB^Q<{nwwyCo8duTXeWkE4#ZE=kIpum(l7u?CVcTg@8p@ zuC81yOQJC-#8JIx-?3SxsW*0&rfPhwyp?&x}`98NK|}4qXZG zI_fq$PF-hIbe7fem-=ZgO!Shcr9A9oIk($45Wj%6t+m@(Mj*NpR&#uI(E`Kz zUg`ZiX2&}HR#$oJDZroO7#2q_7d2Q|x<9Zx$yg&+_j^8_;kgr%vwV{j7+xPT(22Zq zTn<}LOPl|a_T@@l5=lgR3)2&wBL8r(r*CkU&G}+4PN!7Nd*d6@RU@I<-=&}QBj4jE z`?F4zii=d-#>9cLCW)})<+iIEWQD2!+r?1;cETP&e#c$jYJ1D{#!Ed@>SDyt_-JqX z@Fk(<`-dLFUMK={otlH$$#{pOP72^r1pY-BR!JiQ2VhJEh9 zqHZnZ-dW18pIci(7T9Lbgg1fhw+ApyXV%>6wtwUdQT`X-Cq)N`8XAjvg7+L70VltB zb~sB5%a74XliV9aMziQcRtKN=^Vl9LD`|b)t)y(Ll(~y}d4jFj)4`e(O+|6~mDWhd zfCFr#Qu&L*OUJqkFGi1 z#al&P-xn0B|K+L~48sJT4PW8V+dE`oRW=1HcWQ$i5;W>CmxGmb&F5}jmI{|4 zFsDzit3!IX+Leo@}H_D&JtcFdj;!H>GqS#^kR#9Pn`2+PZ&yhEJnRgG z0KBoxTV9^_UpmCSq!uR@XFS%nuK-!dMEH6F#M>We5n9u$L6Ss(Vw^{XgesIeGy+!w zQIb(2Kd}ZB0MjW@Q^>C(7r}`2+6D@dL^kzY?$4$myrQcW?8(3;@Zj<>9YoM(FXx^z zX{^!l0x<%&5DE`?$(pnb4=qlyk-}I%oJ$BLOu;#{rCSB^^XjMa*-~OV7_N$^yB-?(Qo5NtA6;@M9HkaUocgN zZ$aFX=A8*x@xTF>$->bMWhuW)KfVeMp|9jl6E?fT*$0Xk{pu%$ax&{~!?Iiso_!dQY zVsJ3Cv&=zJBOw5-!rAz!y=O<{r4(vA6Wb2j%e<=e0^t`sH8pv8n5-$qwAyV}nE1_O zK$57OxnuYrHmmlhl47QC2zr*#|CCzlXe<7Q5b1TIa3Xo)iz`3BKdF!uy^}5ylU6Vb zdFH9Q=~0Z^c1w4Aik`FaJk;{AdGMJ@+kI7i19mTk(4zfz8J6cmn2Sm(>lTl$z@m2L zlt5{(t^;h*Z~cf9M?N|dApD(YtK|rns28TN)C{vRo{LqS4B)=udaw3_XK{lO`#B32 zqo6P?XD_dC*jEN$4o(J3barOi)UMnI&1&5kVHidJXILSH-O8=1j29=Ik}i>h3rld( zaF@|?YEHV$_WO6kj<(63)j!wHA9TCFb(T)MM&c?k^AgS14sm+M{b9HN>g*8#H8n1& zz-bZl;aZ7ip?sZ+GFh5Z<^oOHj$6zQcX0VS;7G{G?iyq@p0tY3ysg#$`jojd*9RlZ zD-|N_WHc46F1~Sf4oyjM(00!d&h*c{#7E$FFaCrVn$3zAd;xe z{U}T;qIDYnw-5r_N3?p06~5u-lEVG41Sw7v9-JZ%c|waDvqJm>cyeZcX9dn8Bm`8MbJ9^5nrn7 zUHsL&QAEhY54kItSJtD7qan?;hFO|vDgWkm{92*EAC${2_=?PdRys(gUc#>u<(9V@ClW=b>Gw3XD9$Ob&Wl2;Tk+h>0)mrr{^ z{LcoKe&Nso-^0_#)mjr9(!wOg^4whRk}Cfq;~QR*+PyVf-~V5<^pk`n9C|Rw{J&hh zM402QMn%iMN|$yDgV1M3){D}Ac1j3xrADPWxs*g+_m-POnAf#m!^`46R77=PQYtpv z)8l)1?Yn=&m48jeF>&A>oH5>rL7r_p6Kndj19xA)-P1(s{r@K7|J?1@4&jf{d+?y_ zeYwnVv*0Urvi!uq>CL}hV0qTqSo40nc*1Em#OAx^NG83h#Xmj7dzrpx$)#px-YuaH zmR67sCQ|-8LjQjslQk+)kL~bk;?Gp3V&U&LX?D{UoEXp z`YXE_f9rXt6RGL*o#U;_!Nx=y^TQ-74#FfQ1?hjzgVzbt%LgI&y3^6$mb?S0`7tJ5 zPG??QFY+OeR&IsUKWTfM9g+JzjdO=>%{^fXjBa?aE#)jZxJ68z8Z zSFFGPeWbKLIa{&Y>fyhhfW7k9UfmZHQjqU91w%43 z#ald%RL^ii)WU4pRrMc7E$odcW@jA!0It-AX!MtxDoSk(L^D3dar%spKlJUB{9&Y{ zdw|8dU=hf>I7)!1I(#_`M1zw6OxuzZGCpqgHA_qelZaH*rl3ttrTW(=6?$S0dm0vG zCnnhD4nKlUFmViIkXJmr_m3+n8hA+?oDLXcASXYq5#6K0SyT`S0UqT2!>iNkSalWJ z*R}^MFED6-JT&?+02#4&i|)9KLo0ctyK*#*&JZ?7191JG>lIWbk>;B!w(MMm{Jm`h}ykE3L4&Fm(hw=P`NX{Sxb>Z3XdD_3)e)9a<5nH*v+_A8-&N5~X2 zrEQ{aCp#l&j4>6#Y6h-^O>;>yQe6Tww5hC@h8GzJ+!2RGDBSonE|$+YrKaw?dcCgS3)uOpS^#kNP-PNJl<>8 zHZ)YiFRwr1Z2SdmdVc~B9QgF^l_?I3s9U0L=Y5O6S2DN#D`=Y>nq9T206RO!XM~8r zfoEqP7=Nm>QM7kJDx*G2znM5ByLsj}SFFYO6J+X({Q4G12H>>YYhuLtfz$k>k&E=X zyw+Cg=j8nY2aNvlg%WF8i;XyTxy9pRySxJOuMPJSM(DtfV@8tRY?P~GWCsF}lx>R~e^xf%CHXPM=5F(vb%l`}3gnn+^DG zQIxVWhtqekEuEgBsi~VJicKwbVr@?`tc49#E zl?JYXePRpHSi~#+JCbMfR={dByAm}ww?p}`+Xt*USR&}G!G4}NPYLg5FkEQSay7#eP^8hzDI0UcdlJh)qu@1v$HAaX8-os`cw-X^<+S(XInHk$vX zd9+(06OuO4R-#7J1eD=PG>UDfBtBb^QK6{@F2h@+{;0Ffqm!R6{hMv&#cR8Hc7yEx zl538S7ueJ#e`ZS52jWRw4pI}?L@S>B{tcGG*bnb{s97dTpYz9dkJ`st3;_dW^-z@jN{Vx$$Pjs1yM!DJv{Q3hmPHzI@DP>H*Cw%%OC4 z3NJ9!>VuF(E}|!N(;iT_5OTqwRu_>(O}YYc|_ho!teo88V-~_S?>@% z-?MvZwjV(LYiBkCyH;4)e(gBkx%ro zo^GtTOOxNs@;|M55|gayS&h-QO%B=D0|uaQA7y2EZ8)1x0RGr@p{XKRZb?aVgIeoZ=UL^6&6eG+9X3x%Yy2S& ze52=`pa9n$kG)eP2^j2&G%kn}--#k~!Zdv6=Vl0$3SwLK#ka`LygrStVO#ONLeM(# ztqe}q+g&aHCA&~6F!;uXFZ?25poZg^)&T!40q1Al&y;^Dy?q!tUjUh`d zJ3<{cmDTt}DEt#_(=q7FrmNY{9{L=$jf(!C-!@cgf1obu=|0`v4lruy!hRL&#1E-{Z$J}kJ!X#tQ$C6b-Vdab|^C> z@IJ}c2_DY!Cra9iAg(4KwKQa;uI$F8J zeYXUjd6cLn7ehR0u6pam3K<)QQz01z2lQxORUV{;_3AD*S}5yvJo)i9D{8sfLwpZ{ z<5`nH?*X;-Bl3_tdsHOaE7xS$z|-Art51%t4d?+tglTht_oZ@4g=gulxL@d`+c&>> z7Paoax|f|xdc1F&-T^{6_*z2zF7r+OC4fI6`}mlbLafA61{|D0D-{5z7gG3*(7#YN zDCI1hdx8*R%mE|-M9T$7h&2eh> z-f~nc$7`L0Ya8u5<8KAOC>xu-V6|QJV&R~9pPMya#A_R9_Pp_n`YY@1?I%6=9zQR7 z>Z1JozJ{ETfd%l0V(;ouO46;5FrhUiVDRpwO=X8sOWpoQ)onK_WvL z?{Rl+BO)iCYYht>Wj@#*H8G~7`*O+2xld_2-W49(TQ~ONaV>(ZTr>tEYAyvYjuiFb zh`-|qSnOw&`u23A8>eDy4H$%k9XuwBb$xz{Anszh+xETe>ENI0@6_-lnAdIPEj-RK!D^(OEtv@k4;{{g zMGJI|Cf~o;rz0ix5M?I2uae16coTW7E)5TY#QzZW8o47P9rMhtKDHCDe23;>nchT) zC91y`N`}onkh7A@tU6wz#S`%D7d1!Jgei59^Ha#bf{&BEVXz62wZKyf5al-$GLB0WoJ~7k)4j+e};TDi>fjT#wEu1G(ocNU8Fy9tkt8#!$&k&Qu~&#tp%RU+y3EkW)o zTu-9Un$b%xWM9Pvojp8ER6Wq~%zZb{mL6euD)K!$0b9l?$53ccVEA_u*~E`rH!*{0 z#B0>R6PLk0FleFB3tKW^OA{W7U*WiwYR(o=a#xK3cOOqCXdWX*p}WZIuavZVM5w`KU2Dz5d>qpHlsaizK9J9X7)OAOkkRX zfC4{k@&eoMgfupK3*%1Ih@Pb0eBW*eKzcfY!Y>k$Lso%$Tlfg@SWHBb<&HiHa-R2_ z66XupP}&*XlJJ2^`5*<0cgIL(Lj+HFeN42tN*Zi7?-L)Z<8PDr9z(vBYL6qjTK7vE zfvwd)N{IzblI~l<_{ioABy|<@L!0Z%i)o#yofoD*a8xFrQyRj1UIry^j~y6D!R-FR z>=j;I9dE0qzG_PUZlPGCez??pk$SQmzP7fnP6vo>A-uMxhKG~T-dlLa?~!8Mfcx`g z7d|+GgfDD15ULl@p~yM8xMTbZq=bVcN^Q)1KCG;)YAG=Ma$329X$%ekGjXd(4aQzcvC(VR`JkOF-8(AcB=Q}%vKLZU6I4$?N33aArPk~o(LenRA zs;+CRg|JoDEZN+Xnv>%ZT~#mdynJ-hfpk74TI|7{68P}Mczo(00<8WDjVo&|bGff@ z@r>jvTKv6=8q1m370AQF;X1$6H6ZOJ&{{c_X+1f||9E-0xZLj5A;|;e1|whim+riG zV(X_M?F}j8Mi1o>TI}BD@!B$cosFr=xvu7LUse&?;(qVXgEj^Po1puJz2LsuBFakr z9p{r#V}z?>UX0wM!1dS;vmNXkI>cD=y?Z^5mx^+7Ic+~AY-r|5$PsWLTbWUV#@z;b z2ROV>1?%m(uVJ*{yuSq=u_YLrRg@lz+PxSZGrK3a14|-FWmp-D; zL~gzCANDOpzq;Q;C4#}TL#LfAe?qYFyMmLzoljf_xfd2tR)1>e_H zs=i@}Hf$jlUAUcs{Eh^j1R2T!rc&$>w2zlVD|{#j^(f%?n9@N)t8nb zZ*b~PZg!RY)`B!r6I}?42AmJG7zAw(8{I`Qv2PCeB!tAnCoZmZYDZ0u&RpTmgBdo5(*gRBO0{Lk%xQoI+I_tN6qq*Z zzvX3s`T03M?6J`K?Rs&g`QmfN52*l8x0;&v_T9Z{u3D6LK5zKj z#GAD)1;SyjT*>Y$|6+VY74!3%f*9kMF?6D?LrX1JpT1RJ^j?Su20HmfnCygFQF80c zG@Hn|lh9ZF0Rwu9k~_i=ZZqzY-(<^%=h7S0z9|cvYZIs0s6HK-s*O?f3H^QU0g-;o zyJa*$2XAv)xjhLGc3O1#&2p>1-)1$1JjIUR(MO2yK{JhTsHg4Tx3pF04Cr%)$xIY$ zI?-TL3hHHLgxE8)b_?^tpdFEE+@-#{zQ5u70-pe41RFuXb7+K70dU5~EG)uEVO^$9 z->4>uJSDPmlQ-#jB-8Ih$xf3#;>S{RVIk1LMS?J4oC8M7DV|}j0F9 zD&LcDy(k}jU>_XuuFYFXaQ-9hmz1zA0M8eGoF9KDZ8*@@+RAaPahsY|w*We2zEB^b z=yPvaHLkk)-Npq=`H!#nE3xj(7w;DjfKW#=*9Q+DUcS$5U|b#5Vk7Ivvl_{8vJKlf zIeo={F&4u|Fl>1Z;N188_|e4=`%9p4Wp1vk0Bh6n)@`zeFSmF22McU;O8GfzaipiKJX@dGgVl80{Qk$5P@B8 z!@qK4NcAro`19SD+!3`+NUu~91l>a0Bs;NPoHevU{#q+oud_`VnNSwud-8p40=J!7 z89~3*BvSk@ji2NxE4$fMng;j>;IB2Nr9tU*5al@n=CT7JEReI0=3h+sJN zIYw-adQCGgzNE!rypx6Z%Ksks@n(#j`&y_Q`*VGGm_G6e>r7-rEY0hq^IgK9{&2HY z+w|)-t`~F7EMIPbIy!jh;4|u!$_(-J7vH%RX^&j?z8S2dyh*Zd{oxYbAqjK~UdN%) zl9lZF{e7c2I;AnLkB0{>P0n}bNwx=n_pbua0mBVbn@4wl+8(z*{l>e*eh_|pB{1DO z`FPPs+DK}J_(GYU@l@UY9I$%0gT^oScYlmSobz)V`XZnQnJ=WKm=R{dcZPY)tsR)d zz`nzNpXrqB35hc9t{*RAit8&h{ts{O7$jNKbq!Bz+SasfThq4fY1_uM?P=S#ZF|~w zPun)@t?Rn|{Q3TU5fxDt6?yXH$&fhPUdMx;#i3iP|A#HfyeRl^fZV}U;i^=OAM}R8oJiswo zC!@p+k%oZJAO1RK5g;mhEucO4n8it@cEGbXqb{`D)3v~RwbkgeA(;ugN`G(#iV zvpc`W%iW>(!p25?+E3v}s2}eiZ$(U{EYs_V`~|1GFG+YZL*hNqL5E`B8Vb7r9CpmR z$r#jfKe{5)c4<~*~WG0gjqsah9cda(Ny(ywaAzYh< zQg$thUZLZ{@7!#+t17I(3A~9{)O0@^Q`E0gJl)yYc@mW8!h8wI5mNp@tZxBxQeKiX z*lkY=z1Dm9d1`WO58fglLjOW*%RBP`FV;skC1gcJ%jL`}kWV}1ZX}&&r(j%+n$pq` zS~wV(?olF4%A9TA}(f=%{EOW4Nn>Q2bcrv~4ED*O%iQWfZuVS@9%39jU4%{Bl zB-6p_;NzassR^$SO>s>vMPf40A?nt7t-@g0p|x9$JZAkF86Gb1$^V!f`zg?*Q>p9F z*gvgjz3vZQIycC1(c|;+wF(vZ{p3UsWw={WZ5gayv!&;a1>t}ISYB92N=!T(j`i2z z-Z%en6i?Iyg!7w4BVFtHV3|BjS84O-1yli?joeo}Hr8HXF=eAqd=WQI4;4q@sgkPv&l-cmC9MaC0wJZw730-fQsI-ikdF^y`ueY+TCsziyQJYflQ_lek=rC z1lZ@vTRGw?z^yYatBNG#*XjF<%boAh!+ez&PZ|G&8Q)z8cFv>RlY-WQDMAXr`*oNK z?yvHKCL0Tjp$fRM{v|IhO;r*O&oKKXCwIGkwUidGtNGSX&CXG) zm#uufZ=u9>alyuYv%DLA&~7Bq5jA-z3|E%?w#V~1qd5AFdkMa;5(nq|;SuJkm}@#w z=jM56K!9oNZ*CDt0tOo?Mq~TlES}XymaSiv>!a9{{z-tsMo>Hb6?reH9$E`h`m)MW zv32qH#6*>Jt?ika%=mY_cz^!q$uEVh%OF7RKEPt^tEovAOlaIdtd%@lupQhkOhYw* z`N;9{o@IGigtyjFS_)2;fvr`4br4Z!ZC6)v5HZ8nT3eHO&1L@wNg{XT#n9otdeqx| zdx+6PQ}uI?7|KNlZq6i=I|&N#M|Wmi#>*Gx+1$KWuZg*`t}ghT-|6ss62r?;S8q5M z7vj*=uc_u1@u((`FYgf%*o}Ioyyr6jg+GO%;W>$@2=^r%J zyl(8PR1~bI%ut9>TCQujN;XSJ*4pGt20Zz9 zldQ;d^EE;$)ut6WOx^Y^B2 zFL#(3+Sw1Di_4XOLCm8J;L_%Y=`%hbAkB^Yh=GlG4~-`6UIgF|3){RNU2f(y_>MEZ zVAB6^PS1|pHdJle&k2OY&5u4f!hGohZV4j(QMidb<`d6qNTT*rMp?i@Fm3Vk@qngD z4d=#zh#MiDmK-eqxzxh;Q9Eb*^%bMxGvUJ#Ofv2(Z#1M~deGU2@MD2j-*%%zq7Kk{qw_a2{3h5()6F1p*Kk9(jmzr zQaL%QKBnTLYeM%rO^s^r#GEYk!j^H8X5%Df<`n?B< zpHQG0b(ykm@_BSHKKF!Ftq7}~$!I>QZ1;G&@5IsM>tDruGq#m&yFQnja$bDDcE9HE z`D(uX4T_tdle^}1tR~;nKbv0)u^V5J%2a)pBDhG z4(GQ{lq}bN2rBAWC^r3!la5}KVL28yP)dKafNRPaJ0GY1pZ36a^M6c>yKs>yIC1jI zbjR21?&Ud`y|Nn>Mw~N?d9x}F{dfIWpzmL>QBwlu2a#5PMI zKvXyEs3R!8VR9W!{2FFn4orQaFxvkv-w_%Y7is|gzZVg#&Al&v^HQgor*cap5wt!n zph}{F&$U{VbV#yQ_nKrL`%9SncZcfu{Y9nkm>HDHiz!vdCZhHS<;Jr(nU#~~8fRF? zM#KK6aG*ROB{V*b7|#&a?{Dq0 z!2js9Af6rRVpj=}fn}B@aCOQ9p5r96gx}Ku=tU~^z^s4G=H%@J{sZ_|9(=(RQ9djqnb)Y~y3-9^; zhkeIc;cEg)>#gN<%GWTxUpnzWVz*;@tTibw`+=M7M%dk8@mV`lykFNoNC30|{=O)G zTd05D39#>FEre77AC!cTtH+pHg6Y@CSg?6hrZSR3qqo%(3 zOsYf5hHJ3OuiL@5I@n!-{NLNX ze*qw;BO@=u;YCWP<76S}%T7k?>UP0KW(#OUKxIFDG3IsLUy)9sPf6jYqo(F^XY9^k zGJd~&enLfMNK95uOj6aIYCT-7;=w|~uIDECuyk?pR&>xj?{nXs&cJa#Tas5*Wdq8r z^g8XkR}7@|QRj;l)2mKnoH?HS47?wfK+q_=C6u%E5lxm!OG#N>S}G+cl|-$+`R8(T z*6ng*vz@KqvL{_G*EBi8cyMG)UM-j>v&v`$Je{8G4Svich4krrF znO-6_A1TMvE#BGU54_hN)Hjy~d*3mi|4gfQ{#1Ti{X!xUbg6h7Sy{Rfc`t4C^;i$4 z%@cFpcb9;9s@>#gR#w&{e(JSG2Wc7S%z}f}Ls@OI4P7m@@H+ws2uKJz9*1}5Y5baA zYCs-IHrINt=+T63t)-~Od0$O9;G_h{Xm1yDN)H#mIj^Qe8) znzAwmTFR|Dl3T}Dw!$24lVrfmPHXVY3>*1&g}U8)qmgH!g>UHR)u7KJ10(Fs(Ephv zZEo%TD4_xQvcIAOA$vj!ojKQSH$P7jl7wOeHGJx9AQ9pd7=%!(;q~-%byXEKgeJ;M zT%Mfn$U8YS%LUPS@c67*q0FYqcY4Q1fPt$kt_F-sowwCVZGNHdNAE>U3TdhFIhN}9 zpUXAdBD&exyr3iUA_2R*x7XJX&&DR30gZPz_=I+=_$c+*5v=ArN*vwvhlrG1viJ!U zHWg|iJd>?O?QRA=QWl)JrM1@&jJf6YUtyenUc)5l=`G*iO(TW@<~K7lIDC5#5-27G zb|GLfNcy(FcW|(AA&gM?0R<$__Z2Gso)*h9Z2q_NyEK-gf#=>{MB2Iog!k?6k2NQQ zi>dSf_?!tq;LANf!Qwb!e1TFhI~!LX-AI&AOKGj~>RhaPAg}D2^E$l-n6==8Z?s$qcnhPVnabLHM2BS!Zg){& z_tw{!H!j?Z$G{M7d3k?*I6DgjE2OZZVz3t&ehEdqiz}PpprfLi1XLjx_g!45-1tB_DYCMx1f;CE2pb@Oy&g79eqZ>QvZW-Zvy{Mw0 z^ccYT9=&J29V-$=qsr@1(o=6XI>7pLIlWzW^D~`@W#P;-6Re^Yna1@>H zd!3dr>C06&%g*619t3gip6+gjr+Z5aA6K#u?3?Kvc@WfcxXk$7TOhr2d@cQWed35K zJCf!lmraNH15`^{_rz3OZ#}mr!>!HD zvRf{29t-2r>UL&6KRn1XG1U#qf6vHFQTN*eDl|g%Q<+S9*rs;2&ba(O*wAVr)qO8O zO>=*rRl)?<*!V}&+IAj*r!ME2;nvp^!1!N2!@vu$z{m9i<4ra0Iui z=7E3_D82xX5ysnGIB9q2U?|Zq-SJ)=spO(_V-f&=MGSq=`s>8OjW09JkZyfYO%I;9rn$-p4{=B z1I@SHZ1;3M`{e8?t*?K*>+xlB*jn<+zf)o4${9cFYY(u3|rM<#-syQ0@kYGD|ZtbovNOzCN)|@va56_^LhEX;3ZTCL{ zxHr?;vL1=*P<&A$pzfv*r%k}vZzNATj~ntF94_ZKr2S)l=jQ_P;MRg^4m;&EsW+Z` z-_S=KZ*UhSmRDGY`v3GA3jpyD5`5HU7n`gZi@eB8cveR@j zRUMe(*dfBs-h3XlL6W2z6A)m?6u!O0GFwus!B86a=<$QTpGl71GKA3 zDk`8LOEW8u96ZZJm@tBu9zP%Cc@+#sguPXSir*XhSfkCM6 z^pv2dC-bi#o`^^Qps5AY?C>5(6Afh}mK)UROctp@wb#P${5?>R9mG%lpG*bY4~&sw zE+88p+j$?@Nlm77&e|0J$EyC`I;mzm{JKOYu49k&0$%HO_1U;tR6XW$%7y8u3(ds;sJ3s(WyxAiJfTQs3;3C7nh4c;xHMsX;|)SJh^5K)T)Djt2qd-Okd z=jI}epedYykvMMcfqss6vzPy^MJMh5lN*icO+Ve?c-$Y~RHXFCOUeObiUYox0MGUR zhJ;BkAfF_^qRy3Esnfa3R+BImC6CwWw%K6 zcX8y05fV}k1bbd}xuJ`1o-MXNEUsy-TjEtMt`WUlCgc)FTP~*fTx_1XJxFC|9&H?D zes|B(n_@PAl0gC&{Qv(G>kFcijWsf%cDi4Jjk|}NR3%G)H(7zBw1%s~#MfGm=ZATX zLGMwRXqE3|?Of;hE4re#`zy zGSt6%VV`6GO%k_@t*%WN$JBIcUA6n7|N4^Q48dF5_uXgjBy`d&r!f=K;$&7<)7`g@^=zBD7x@G(?M!!Y9^@eqiLA0`GUvEq7 z@;(;^%5?znSWK(q3@AbZx$P{4B4FFi)87WsGVCX0Rvd-< zbO9=ehEg(|FfiNwL3G~2J3C^?W#s#h?J|G3$AUKA4^{8~yq&{gTrkUrV}VYAfg?I;km*u!P^X?$v#Ss_1r30eo0O zTyQqd+mZ6HFyi`x)sWhcP$#3}>-pq6mgO7eWXFOMM&7$JjPAe{N7Uht33RlyTRKWd z^;+nNiN#!ef{QYo!T1^LKvA-{JZst>$B301wy{>25M^S9pW&^S(#3XEvpJuqqyac5 zat@itW7YudbYV2K=b;koTk*kLdc#oGS-b*0f?f1f-Qf3$rvCg7XW83c{@9uU6?18( zCvrZ@c{q22f4t|Eew4bQWEdQd?O1~?B4`v?Hsx!294XjUA=t8{hAj48Z;3{A`_4$c z)~1Gi&h4>C;HY&Ij)^y>*G64v3lX3Og3n47q6S!rS+LG>`YSdIABwi@X zqQ{VU303T`)8}n{{@`P(^v$-yw76X&QlTxBM5P3cepzow96E*a_W8qhrQ>7b`levy zCNf{1gs@p~IB+ntehtg(o4&1i^%4^yk=kEFxn4too;UfkSAR-*BIfmHThe|}rfqR; zazgZDwZCcFbc_$LK(Gxh|3J(J;npi#2pM##q*`~a`n<3Cb@XY@y?qyM{{0C}NPrLu zQjq9=qhKGelq**sx! zkm<6daKlU9X5>ij~`_))jc0#Fw&Ju zZz3j%O>`@)CaY6rH0=}&n~GbUY>f2cx$a$Romqmk(4yy~3x)A<0fi8me#mHP!z$+D z4c7-EuDA2*4o2j_1bcXCe%(ZP;~=^^xUjKu>+G#MeJ5+RqCq9uy@&RUE^&Rs&#)yd zE9p~;H*vGtp_&X_6LauV7cE7df&C(#->!1nZDzaqHf(eaU4gr#(-RPv5KJ<3Seu+C ztH0;Oz9)3R>1_R=NS(|Qj z+q|5#!ME)Y44=p+vdSp~7yh%FIgcRv(&k>lIucUud!6xB06drTom3~@oWziZpfw{z zB3$s`8RPBSnELzh3jNS%i0!zjmyne12rR~c6Xkwr9EOQi(y}h<(M?b_Ipm7%JlTEL zGeWrqaEsr(wjw-O)vsZ{eZ#m#CB=NHsCg$4EZr}@zyz_NuPRps9;X{eY%B)N14`iX z<Y*GW~UDvh=-xpE^e99(pzH`y+EgBZYgmvMvD&W z_n4ofAPTGrlc9kiD>F||PE|)uQcKt2#dt5Wo=|~|(N7-T{eT%rPK!AIW{b5^D*1js znVI`FU6@q0JZ~NT0G#bsDcNz)l=+8p9?r||lW%btU30C|Q_Syb&=VXEtB*<-$oNRH zG2kTKmNCp*f|s47w5!Z${03K4?xJQdgfA{M5j-BZ*8b7~7hS93Sx2UJt!8+FhL)ks z?;xo=+4`J$I%DwilWosx{V4FN6(QPBz;vnFCr{G8&Sx(E@g-w;QkS3e`#}@B;z~ON z#eVaI2G}kbK4e=F#xnYnt6IwxJwC4_4iX)^TdvaqbQ>F?hZ6^$Ke)o5?mcG({B9Wt zS#Iw|T?r)a%0J3{U_!-%TE$q*&gc2#-rF&JA04w+d{ht9e)dRcLc$=q-v~IVqGis} zv;vvph)PabWTw9li0~kbUJl<=BOUsZPizlCf0I--hd( zM=<;?vtpV{2lwP`yT<$?!u#FR8HpY#^N1#d6Gl0Yw=mSRObXGRoXQXqHTxykj0G{= z?1olm5CM&aqkJx5pTUU@eeDr@hQ$RX8SfydW!73)0wFdgEhBso`FuLpBBV%$*wc|@ z`&QNAtU^vfLh=sr{rnf44MGs1FJX-`MZS?2Y{Vcm_MnDIeA{TB0yT5tLj-r6CUBv9 zp~*QUmTLuLV@3qAqH^A5?t~N_+Li(vi;`(GE*}{kl}kuu2stx&JZGQFE%Jhdfw_HK zM)=BX(6U>vA{1M2WFZ^cOs&=c0|h&&eAw^gfi4-P{=oRdj?Te0((2KvmBJ7kj@&lf zTrpB#79}<*yT#9}GmO8{$;+q$+}(ZU!WJ?WnLft6+C^5khwnvDus;)4bao$%wp(~n zI)$9xR0lC_*ENCgioj*iMYg}(ZhcVVUt?t?aD&(W1JSigP{V2*J zkIo$mwlbLfPP`np?7|7)cogMD(M34)qpN-LS`)Vwg;I;;8<-7Mz30Z%N4YEKOKE4P z+?eb#y4+TqM}MeHm*{2u=lV$Ojn_BgvS6`0l4UhI(ckGw`L=WAgvj-vRi~=4&j_;U zNwSOl2FHS%=;oK7#m!PzTWduz`1+uSToQ&Se-LE<0H@!>Ld#H{{qD0Aa#%)_-kuzj z(S*=>-n8iN3M)5($K!3%H|k26-9NmzHA(Qj!cb=Uc@;+~;tc49Sfg<(8%$ouxo{9M zqtn0eEiSX}NY}Z|``b*edpTde2F`TmTr=rQPw);Ht*K+$bpP-?U7j_|UV2i@kcSTn z%tgY6`7*@#(d$o94JslQ+oGxjNFwy))xoo31+DLvJny}y*#Tc<(P1e?p{V_`dqQuq z@w^()dC|Z7@rA(zOIjVQ%e#CIwlh4XPVD!R>F2k^UJluT4T<9^vJO(i<00l&^DuZ>@g|riFmAQwVOfx zBIX13)4L+_82fSUun~`rEX#}^+f5-*<=nZCdbsx!HMIa~Xoo5ButluM_nx zfhI9lPx1~=a|9LWu{S1~XaSbxWNDF55s(iip^f(QYJ!}tSvl=dsB56I3wE*Ce}nw} znqD*}cYWwUBW4?93(gs~F&<8)5TGXj;O8#znv2K#1A!5peFennv`qJ2QCZyAwFxPe2|Sr z?JgLpVTxIlGRUclN`iEwDk7G3b8@icMUQX@;nUI+1Rz7?12(iw`*1E684XPICFxWu zLVPz|i%7)GMWh9tbrz?$EoI6=wgdZQRH803Pq}r>1gx;acnMh zU@n%YTF5ypomb;jwNqjHyR)d6)4IM$*vgnmH)Yu%$r|T>&a^q3oky10#C`F-#elKl z?fcEJ@@w z<_#A2a3`QU1rIJPp`%@+DCdNh$DXeUJIoYVE(D_INO2t^Fz%+5msOlq;AxrVUr?h# zS;6t8kKgYipRhbmHuL8Ou9I;%vM%F|``I{ls0Dp{@dR4`kO*F?Nsv(TPE4=%-`6l5 zXlLBgMxBykIZ12y{77vPP6edp?go`U*4LgxK|w5Xe*XmAF6apg&4J79Y+pJ_ z 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