$func, 'input' => $input, 'meta' => $meta, ); $data = array( 'data' => json_encode($info), ); $url = 'https://api.jutge.org/api'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $lines = explode("\n", $response); $intersting = $lines[3]; $answer = json_decode($intersting, true); curl_close($ch); if (array_key_exists('output', $answer)) { return $answer["output"]; } else { throw new \Exception($answer["error"]["name"]); } } function login() { $path = getenv('HOME') . '/.jutge-client.yml'; if (!file_exists($path)) { echo 'The file ~/.jutge-client.yml does not exist'; exit(); } $file = file_get_contents($path); list($line1, $line2) = explode("\n", $file, 2); list($email_text, $email) = explode(': ', trim($line1), 2); list($password_text, $password) = explode(': ', trim($line2), 2); $credentials = execute('auth.login', array('email' => $email, 'password' => $password)); global $meta; $meta = array( 'token' => $credentials['token'], 'exam' => null, ); } function logout() { global $meta; $meta = array('token' => null, 'exam' => null); } namespace client\auth; /* Login: Get an access token */ function login($data) { return \client\execute('auth.login', $data); } /* Logout: Discard access token 🔐 Authenticated */ function logout() { return \client\execute('auth.logout', null); } namespace client\misc; /* Get a fortune message */ function get_fortune() { return \client\execute('misc.getFortune', null); } /* Get server time */ function get_time() { return \client\execute('misc.getTime', null); } /* Get homepage stats */ function get_homepage_stats() { return \client\execute('misc.getHomepageStats', null); } /* Get Jutge.org logo as a PNG file */ function get_logo() { return \client\execute('misc.getLogo', null); } namespace client\tables; /* Returns all languages Returns all languages as a dictionary of objects, indexed by id. */ function get_languages() { return \client\execute('tables.getLanguages', null); } /* Returns all countries Returns all countries as a dictionary of objects, indexed by id. */ function get_countries() { return \client\execute('tables.getCountries', null); } /* Returns all compilers Returns all compilers as a dictionary of objects, indexed by id. */ function get_compilers() { return \client\execute('tables.getCompilers', null); } /* Returns all drivers Returns all drivers as a dictionary of objects, indexed by id. */ function get_drivers() { return \client\execute('tables.getDrivers', null); } /* Returns all verdicts Returns all verdicts as a dictionary of objects, indexed by id. */ function get_verdicts() { return \client\execute('tables.getVerdicts', null); } /* Returns all proglangs Returns all proglangs as a dictionary of objects, indexed by id. */ function get_proglangs() { return \client\execute('tables.getProglangs', null); } /* Returns all tables Returns all compilers, countries, drivers, languages, proglangs, and verdicts in a single request. This data does not change often, so you should only request it once per session. */ function get_all() { return \client\execute('tables.getAll', null); } namespace client\problems; /* Get all available abstract problems 🔐 Authenticated Includes problems. */ function get_all_abstract_problems() { return \client\execute('problems.getAllAbstractProblems', null); } /* Get available abstract problems whose keys are in `problem_nms` (comma separated list) 🔐 Authenticated Includes problems. */ function get_abstract_problems($problem_nms) { return \client\execute('problems.getAbstractProblems', $problem_nms); } /* Get available abstract problems that belong to a list 🔐 Authenticated Includes problems. */ function get_abstract_problems_in_list($list_key) { return \client\execute('problems.getAbstractProblemsInList', $list_key); } /* Get an abstract problem 🔐 Authenticated Includes owner and problems */ function get_abstract_problem($problem_nm) { return \client\execute('problems.getAbstractProblem', $problem_nm); } /* Get extras of an abstract problem 🔐 Authenticated Includes accepted compilers and accepted proglangs */ function get_abstract_problem_extras($problem_nm) { return \client\execute('problems.getAbstractProblemExtras', $problem_nm); } /* Get a problem 🔐 Authenticated Includes abstract problem, which includes owner */ function get_problem($problem_id) { return \client\execute('problems.getProblem', $problem_id); } /* Get extras of a problem. 🔐 Authenticated Includes accepted compilers, accepted proglangs, official solutions checks and handler specifications */ function get_problem_extras($problem_id) { return \client\execute('problems.getProblemExtras', $problem_id); } /* Get sample testcases of a problem. 🔐 Authenticated */ function get_sample_testcases($problem_id) { return \client\execute('problems.getSampleTestcases', $problem_id); } /* Get public testcases of a problem. 🔐 Authenticated Public testcases are like sample testcases, but are not meant to be show in the problem statatement, because of their long length. */ function get_public_testcases($problem_id) { return \client\execute('problems.getPublicTestcases', $problem_id); } /* Get Html statement of a problem. 🔐 Authenticated Currently, this is suboptimal, but I already know how to improve it. */ function get_html_statement($problem_id) { return \client\execute('problems.getHtmlStatement', $problem_id); } /* Get Text statement of a problem. 🔐 Authenticated */ function get_text_statement($problem_id) { return \client\execute('problems.getTextStatement', $problem_id); } /* Get Markdown statement of a problem. 🔐 Authenticated */ function get_markdown_statement($problem_id) { return \client\execute('problems.getMarkdownStatement', $problem_id); } /* Get PDF statement of a problem. 🔐 Authenticated */ function get_pdf_statement($problem_id) { return \client\execute('problems.getPdfStatement', $problem_id); } /* Get ZIP archive of a problem. 🔐 Authenticated */ function get_zip_statement($problem_id) { return \client\execute('problems.getZipStatement', $problem_id); } namespace client\student; namespace client\student\keys; /* Get problem, courses (enrolled and available) and list keys. 🔐 Authenticated */ function get_all() { return \client\execute('student.keys.getAll', null); } /* Get problem keys. 🔐 Authenticated */ function get_problems() { return \client\execute('student.keys.getProblems', null); } /* Get enrolled course keys. 🔐 Authenticated */ function get_enrolled_courses() { return \client\execute('student.keys.getEnrolledCourses', null); } /* Get available course keys. 🔐 Authenticated */ function get_available_courses() { return \client\execute('student.keys.getAvailableCourses', null); } /* Get list keys. 🔐 Authenticated */ function get_lists() { return \client\execute('student.keys.getLists', null); } namespace client\student\profile; /* Get the profile. 🔐 Authenticated */ function get() { return \client\execute('student.profile.get', null); } /* Update the profile 🔐 Authenticated */ function update($data) { return \client\execute('student.profile.update', $data); } /* Returns the avatar as a PNG file. 🔐 Authenticated */ function get_avatar() { return \client\execute('student.profile.getAvatar', null); } /* Set a PNG file as avatar 🔐 Authenticated */ function set_avatar() { return \client\execute('student.profile.setAvatar', null); } /* Change password 🔐 Authenticated Receives the old password and the new one, and changes the password if the old one is correct */ function change_password($data) { return \client\execute('student.profile.changePassword', $data); } namespace client\student\dashboard; /* Get all distributions 🔐 Authenticated */ function get_all_distributions() { return \client\execute('student.dashboard.getAllDistributions', null); } /* Get compilers distribution 🔐 Authenticated */ function get_compilers_distribution() { return \client\execute('student.dashboard.getCompilersDistribution', null); } /* Get dashboard 🔐 Authenticated */ function get_dashboard() { return \client\execute('student.dashboard.getDashboard', null); } /* Get heatmap calendar of submissions 🔐 Authenticated */ function get_heatmap_calendar() { return \client\execute('student.dashboard.getHeatmapCalendar', null); } /* Get programming languages distribution 🔐 Authenticated */ function get_proglangs_distribution() { return \client\execute('student.dashboard.getProglangsDistribution', null); } /* Get dashboard stats 🔐 Authenticated */ function get_stats() { return \client\execute('student.dashboard.getStats', null); } /* Get submissions by hour distribution 🔐 Authenticated */ function get_submissions_by_hour() { return \client\execute('student.dashboard.getSubmissionsByHour', null); } /* Get submissions by weekday distribution 🔐 Authenticated */ function get_submissions_by_week_day() { return \client\execute('student.dashboard.getSubmissionsByWeekDay', null); } /* Get verdicts distribution 🔐 Authenticated */ function get_verdicts_distribution() { return \client\execute('student.dashboard.getVerdictsDistribution', null); } namespace client\student\submissions; /* Get all submissions. 🔐 Authenticated Flat array of submissions in chronological order. */ function get_all() { return \client\execute('student.submissions.getAll', null); } /* Get all submissions for an abstract problem. 🔐 Authenticated Grouped by problem. */ function get_for_abstract_problem($problem_nm) { return \client\execute('student.submissions.getForAbstractProblem', $problem_nm); } /* Get all submissions for a problem. 🔐 Authenticated */ function get_for_problem($problem_id) { return \client\execute('student.submissions.getForProblem', $problem_id); } /* Get a submission. 🔐 Authenticated */ function get($data) { return \client\execute('student.submissions.get', $data); } /* Perform a submission. 🔐 Authenticated */ function submit($data) { return \client\execute('student.submissions.submit', $data); } namespace client\student\courses; /* Get all available courses. 🔐 Authenticated */ function get_all_available() { return \client\execute('student.courses.getAllAvailable', null); } /* Get all enrolled courses. 🔐 Authenticated */ function get_all_enrolled() { return \client\execute('student.courses.getAllEnrolled', null); } /* Get an available course. 🔐 Authenticated Includes owner and lists. */ function get_available($course_key) { return \client\execute('student.courses.getAvailable', $course_key); } /* Get an enrolled course. 🔐 Authenticated Includes owner and lists. */ function get_enrolled($course_key) { return \client\execute('student.courses.getEnrolled', $course_key); } /* Enroll in an available course. 🔐 Authenticated */ function enroll($course_key) { return \client\execute('student.courses.enroll', $course_key); } /* Unenroll from an enrolled course. 🔐 Authenticated */ function unenroll($course_key) { return \client\execute('student.courses.unenroll', $course_key); } namespace client\student\lists; /* Get all lists. 🔐 Authenticated */ function get_all() { return \client\execute('student.lists.getAll', null); } /* Get a list. 🔐 Authenticated Includes items, owner. */ function get($list_key) { return \client\execute('student.lists.get', $list_key); } namespace client\student\statuses; /* Get statuses for all problems. 🔐 Authenticated */ function get_all() { return \client\execute('student.statuses.getAll', null); } /* Get status for an abstract problem. 🔐 Authenticated */ function get_for_abstract_problem($problem_nm) { return \client\execute('student.statuses.getForAbstractProblem', $problem_nm); } /* Get status for a problem. 🔐 Authenticated */ function get_for_problem($problem_id) { return \client\execute('student.statuses.getForProblem', $problem_id); } namespace client\student\awards; /* Get all awards. 🔐 Authenticated */ function get_all() { return \client\execute('student.awards.getAll', null); } /* Get an award. 🔐 Authenticated */ function get($award_id) { return \client\execute('student.awards.get', $award_id); } namespace client\instructor; namespace client\instructor\tags; /* Get all tags 🔐 Authenticated */ function get_all() { return \client\execute('instructor.tags.getAll', null); } /* Get all tags with their problems 🔐 Authenticated */ function get_dict() { return \client\execute('instructor.tags.getDict', null); } /* Get all problems with a given tag 🔐 Authenticated */ function get($tag) { return \client\execute('instructor.tags.get', $tag); } namespace client\instructor\documents; /* Get index of all documents 🔐 Authenticated */ function index() { return \client\execute('instructor.documents.index', null); } /* Get a document (without PDF) 🔐 Authenticated */ function get($document_nm) { return \client\execute('instructor.documents.get', $document_nm); } /* Get PDF of a document 🔐 Authenticated */ function get_pdf($document_nm) { return \client\execute('instructor.documents.getPdf', $document_nm); } /* Create a new document 🔐 Authenticated */ function create($data) { return \client\execute('instructor.documents.create', $data); } /* Update a document (without PDF) 🔐 Authenticated */ function update($data) { return \client\execute('instructor.documents.update', $data); } /* Update PDF of a document 🔐 Authenticated */ function update_pdf($document_nm) { return \client\execute('instructor.documents.updatePdf', $document_nm); } /* Remove a document (including PDF) 🔐 Authenticated */ function remove($document_nm) { return \client\execute('instructor.documents.remove', $document_nm); } namespace client\instructor\lists; /* Get index of all lists 🔐 Authenticated */ function index() { return \client\execute('instructor.lists.index', null); } /* Get a list with its items 🔐 Authenticated */ function get($list_nm) { return \client\execute('instructor.lists.get', $list_nm); } /* Get the items of a list 🔐 Authenticated */ function get_items($list_nm) { return \client\execute('instructor.lists.getItems', $list_nm); } /* Create a new list 🔐 Authenticated */ function create($data) { return \client\execute('instructor.lists.create', $data); } /* Update an existing list 🔐 Authenticated */ function update($data) { return \client\execute('instructor.lists.update', $data); } /* Delete an existing list 🔐 Authenticated */ function remove($list_nm) { return \client\execute('instructor.lists.remove', $list_nm); } /* Set the items of a list 🔐 Authenticated */ function set_items($data) { return \client\execute('instructor.lists.setItems', $data); } namespace client\instructor\courses; /* Get index of all courses 🔐 Authenticated */ function index() { return \client\execute('instructor.courses.index', null); } /* Get a course with its items (lists, courses and tutors) 🔐 Authenticated */ function get($course_nm) { return \client\execute('instructor.courses.get', $course_nm); } /* Get lists of a course 🔐 Authenticated */ function get_lists($course_nm) { return \client\execute('instructor.courses.getLists', $course_nm); } /* Get students of a course 🔐 Authenticated */ function get_students($course_nm) { return \client\execute('instructor.courses.getStudents', $course_nm); } /* Get tutors of a course 🔐 Authenticated */ function get_tutors($course_nm) { return \client\execute('instructor.courses.getTutors', $course_nm); } /* Create a new course 🔐 Authenticated */ function create($data) { return \client\execute('instructor.courses.create', $data); } /* Update an existing course 🔐 Authenticated */ function update($data) { return \client\execute('instructor.courses.update', $data); } /* Delete an existing course 🔐 Authenticated Note: A course should not be deleted. Ask a system administrator to remove it. */ function remove($course_nm) { return \client\execute('instructor.courses.remove', $course_nm); } /* Set lists of a course 🔐 Authenticated */ function set_lists($data) { return \client\execute('instructor.courses.set_lists', $data); } /* Invite students to a course 🔐 Authenticated */ function invite_students($data) { return \client\execute('instructor.courses.invite_students', $data); } /* Invite tutors to a course 🔐 Authenticated */ function invite_tutors($data) { return \client\execute('instructor.courses.invite_tutors', $data); } /* Remove students from a course 🔐 Authenticated */ function remove_students($data) { return \client\execute('instructor.courses.remove_students', $data); } /* Remove tutors from a course 🔐 Authenticated */ function remove_tutors($data) { return \client\execute('instructor.courses.remove_tutors', $data); } namespace client\instructor\exams; /* Get index of all exams 🔐 Authenticated */ function index() { return \client\execute('instructor.exams.index', null); } /* Get an exam with its items (course, problems, documents, students) 🔐 Authenticated */ function get($exam_nm) { return \client\execute('instructor.exams.get', $exam_nm); } /* Create a new exam 🔐 Authenticated */ function create($data) { return \client\execute('instructor.exams.create', $data); } /* Update an existing exam 🔐 Authenticated */ function update($data) { return \client\execute('instructor.exams.update', $data); } /* Delete an existing exam 🔐 Authenticated Note: An exam can only be deleted if it has not started. */ function remove($exam_nm) { return \client\execute('instructor.exams.remove', $exam_nm); } /* Get documents of an exam 🔐 Authenticated */ function get_documents($exam_nm) { return \client\execute('instructor.exams.getDocuments', $exam_nm); } /* Get course of an exam 🔐 Authenticated */ function get_course($exam_nm) { return \client\execute('instructor.exams.getCourse', $exam_nm); } /* Get problems of an exam 🔐 Authenticated */ function get_problems($exam_nm) { return \client\execute('instructor.exams.getProblems', $exam_nm); } /* Get students of an exam 🔐 Authenticated */ function get_students($exam_nm) { return \client\execute('instructor.exams.getStudents', $exam_nm); } /* Get an student of an exam 🔐 Authenticated */ function get_student($data) { return \client\execute('instructor.exams.getStudent', $data); } /* Get submissions of an exam 🔐 Authenticated This endpoint prepares a ZIP file to download the submissions of an exam. Preparing the ZIP file takes some time, an href link to the ZIP will be returned. This ZIP file will be available for download for a limited time. */ function get_submissions($data) { return \client\execute('instructor.exams.getSubmissions', $data); } /* Set documents of an exam 🔐 Authenticated */ function set_documents($data) { return \client\execute('instructor.exams.setDocuments', $data); } /* Set problems of an exam 🔐 Authenticated */ function set_problems($data) { return \client\execute('instructor.exams.setProblems', $data); } /* Set students of an exam 🔐 Authenticated */ function set_students($data) { return \client\execute('instructor.exams.setStudents', $data); } /* Add students to an exam 🔐 Authenticated */ function add_students($data) { return \client\execute('instructor.exams.addStudents', $data); } /* Remove students from an exam 🔐 Authenticated */ function remove_students($data) { return \client\execute('instructor.exams.removeStudents', $data); } namespace client\instructor\queries; /* The old and venerable ricard01 query. 😀 🔐 Authenticated Returns a list of submissions for a given problem for all students of a given course. Each submission includes the email, time, problem name, problem id, verdict, and IP address. The list is ordered by email and time. */ function ricard01($data) { return \client\execute('instructor.queries.ricard01', $data); } /* The old and venerable ricard02 query. 😀 🔐 Authenticated Returns a list of submissions for all problems in a given list for all students of a given course. Each submission includes the email, time, problem name, problem id, verdict, and IP address. The list is ordered by email, problem id and time. */ function ricard02($data) { return \client\execute('instructor.queries.ricard02', $data); } namespace client\instructor\problems; /* Get the passcode of a problem. 🔐 Authenticated Returns an empty string if the problem has no passcode. */ function get_passcode($problem_nm) { return \client\execute('instructor.problems.getPasscode', $problem_nm); } /* Set or update the passcode of a problem. 🔐 Authenticated The passcode must be at least 8 characters long and contain only alphanumeric characters. The passcode will be stored in the database in plain text. */ function set_passcode($data) { return \client\execute('instructor.problems.setPasscode', $data); } /* Remove passcode of a problem. 🔐 Authenticated */ function remove_passcode($problem_nm) { return \client\execute('instructor.problems.removePasscode', $problem_nm); } /* Deprecate a problem. 🔐 Authenticated */ function deprecate($data) { return \client\execute('instructor.problems.deprecate', $data); } /* Undeprecate a problem. 🔐 Authenticated */ function undeprecate($problem_nm) { return \client\execute('instructor.problems.undeprecate', $problem_nm); } /* Download a problem. 🔐 Authenticated Quick and dirty implementation, should be improved. Returns a zip file with the abstract problem and all its problems. */ function download($problem_nm) { return \client\execute('instructor.problems.download', $problem_nm); } namespace client\admin; namespace client\admin\users; /* Count users 🔐 Authenticated */ function count() { return \client\execute('admin.users.count', null); } /* Create a user 🔐 Authenticated */ function create($data) { return \client\execute('admin.users.create', $data); } /* Remove a user 🔐 Authenticated */ function remove($email) { return \client\execute('admin.users.remove', $email); } /* Set a password for a user 🔐 Authenticated */ function set_password($data) { return \client\execute('admin.users.setPassword', $data); } namespace client\admin\tasks; /* Purge expired access tokens 🔐 Authenticated Purge expired access tokens (call it from time to time, it does not hurt) */ function purge_auth_tokens() { return \client\execute('admin.tasks.purge-auth-tokens', null); } /* Clear all memoization caches 🔐 Authenticated */ function clear_caches() { return \client\execute('admin.tasks.clear-caches', null); } namespace client\admin\stats; /* Get counters 🔐 Authenticated */ function get_counters() { return \client\execute('admin.stats.getCounters', null); } /* Get distribution of verdicts 🔐 Authenticated */ function get_distribution_of_verdicts() { return \client\execute('admin.stats.getDistributionOfVerdicts', null); } /* Get distribution of verdicts by year 🔐 Authenticated */ function get_distribution_of_verdicts_by_year() { return \client\execute('admin.stats.getDistributionOfVerdictsByYear', null); } /* Get distribution of compilers 🔐 Authenticated */ function get_distribution_of_compilers() { return \client\execute('admin.stats.getDistributionOfCompilers', null); } /* Get distribution of proglangs 🔐 Authenticated */ function get_distribution_of_proglangs() { return \client\execute('admin.stats.getDistributionOfProglangs', null); } /* Get distribution of registered users by year 🔐 Authenticated */ function get_distribution_of_users_by_year() { return \client\execute('admin.stats.getDistributionOfUsersByYear', null); } /* Get distribution of registered users by country 🔐 Authenticated */ function get_distribution_of_users_by_country() { return \client\execute('admin.stats.getDistributionOfUsersByCountry', null); } /* Get distribution of registered users by submissions using a custom bucket size 🔐 Authenticated */ function get_distribution_of_users_by_submissions($data) { return \client\execute('admin.stats.getDistributionOfUsersBySubmissions', $data); } /* Get ranking of users 🔐 Authenticated ❌ Warning: Input type is not correct */ function get_ranking_of_users($data) { return \client\execute('admin.stats.getRankingOfUsers', $data); } /* Get distribution of submissions by hour 🔐 Authenticated */ function get_distribution_of_submissions_by_hour() { return \client\execute('admin.stats.getDistributionOfSubmissionsByHour', null); } /* Get distribution of submissions by proglang 🔐 Authenticated */ function get_distribution_of_submissions_by_proglang() { return \client\execute('admin.stats.getDistributionOfSubmissionsByProglang', null); } /* Get distribution of submissions by compiler 🔐 Authenticated */ function get_distribution_of_submissions_by_compiler() { return \client\execute('admin.stats.getDistributionOfSubmissionsByCompiler', null); } /* Get distribution of submissions by weekday 🔐 Authenticated */ function get_distribution_of_submissions_by_weekday() { return \client\execute('admin.stats.getDistributionOfSubmissionsByWeekday', null); } /* Get distribution of submissions by year 🔐 Authenticated */ function get_distribution_of_submissions_by_year() { return \client\execute('admin.stats.getDistributionOfSubmissionsByYear', null); } /* Get distribution of submissions by year for a proglang 🔐 Authenticated */ function get_distribution_of_submissions_by_year_for_proglang($proglang) { return \client\execute('admin.stats.getDistributionOfSubmissionsByYearForProglang', $proglang); } /* Get distribution of submissions by day 🔐 Authenticated */ function get_distribution_of_submissions_by_day() { return \client\execute('admin.stats.getDistributionOfSubmissionsByDay', null); } /* Get heatmap calendar of submissions 🔐 Authenticated Data is provided as required by https://cal-heatmap.com */ function get_heatmap_calendar_of_submissions() { return \client\execute('admin.stats.getHeatmapCalendarOfSubmissions', null); } /* Get upcoming exams 🔐 Authenticated */ function get_upcoming_exams() { return \client\execute('admin.stats.getUpcomingExams', null); } namespace client\admin\problems; /* Get official solution for a problem for a proglang 🔐 Authenticated ❌ Warning: TODO */ function get_problem_solution($data) { return \client\execute('admin.problems.getProblemSolution', $data); } namespace client\check; /* Checks that query actor is a user 🔐 Authenticated */ function check_user() { return \client\execute('check.checkUser', null); } /* Checks that query actor is an instructor 🔐 Authenticated */ function check_instructor() { return \client\execute('check.checkInstructor', null); } /* Checks that query actor is an admin 🔐 Authenticated */ function check_admin() { return \client\execute('check.checkAdmin', null); } /* Throw an exception of the given type */ function throw_error($exception) { return \client\execute('check.throwError', $exception); } namespace client\playground; /* Upload a file */ function upload($data) { return \client\execute('playground.upload', $data); } /* Get negative of an image */ function negate() { return \client\execute('playground.negate', null); } /* Download a file */ function download($data) { return \client\execute('playground.download', $data); } /* Download a file with a string */ function download2($data) { return \client\execute('playground.download2', $data); } /* Ping the server to get a pong string */ function ping() { return \client\execute('playground.ping', null); } /* Returns the given string in uppercase */ function to_upper_case($s) { return \client\execute('playground.toUpperCase', $s); } /* Returns the sum of two integers */ function add2i($data) { return \client\execute('playground.add2i', $data); } /* Returns the sum of two floats */ function add2f($data) { return \client\execute('playground.add2f', $data); } /* increment two numbers */ function inc($data) { return \client\execute('playground.inc', $data); } /* Returns the sum of three integers */ function add3i($data) { return \client\execute('playground.add3i', $data); }