{"version":3,"sources":["aws-exports.js","CacheDraw.js","LocalDB.js","graphql/queries.js","graphql/mutations.js","graphql/subscriptions.js","graphql/customops.js","ibdata.js","ImageUtils.js","UsersUtils.js","Amp.js"],"names":["awsmobile","CacheDraw","cache","subs","cb","timer","timerDone","items","Object","keys","map","key","sort","a","b","createTime","i","length","o","ended","created","ib","then","r","obj","data","updateObject","id","createObject","timerInit","clearTimeout","setTimeout","initCache","args","newObj","cb1","JSON","parse","stringify","Date","getTime","console","error","updateObj","endPath","cacheSubs","d","c","delObject","stillDrawing","gSession","listCommunityBoards","getClassroom","listFrequentEngagementMins","getTenant","queryByParent","queryByClassroom","queryByCreatorLocalId","queryByGroupsClassroom","queryByEventsClassroom","querybyEngagementClass","queryLocalUserByClass","queryByParentID","sessionSorted","byTeamTenant","UPByTenant","queryClassByTutorGroup","eventByTutorClass","byUsersSessionSorted","videoRoomBySession","videoRoomBySID","createSession","updateSession","updateGamePlay","updateClassGroup","updateClassroomEvent","updateLocalUsers","createMultiBoard","createUserProfile","updateUserProfile","createUser","updateUser","subscribeToSessionObjects","queryBySavedOwner","mutations","autoMutation","callDispatch","firsttime","functions","LocalDB","db","undoops","redostack","undostack","failedOperation","resetUndoStack","localgqlOperationWithRetry","query","delay","retryCount","Promise","resolve","reject","undefined","input","API","graphql","graphqlOperation","catch","ms","qStr","doRetry","Array","isArray","errors","idx","errorType","message","stack","log","bind","e","includes","msg","sev","button","timeout","delObj","callDispatch1","ctx","sessionID","init","setInterval","cleanOldTimer","doPendingTimer","mylocalStorage","clearTable","getAllObjects","dbobj","doPending","isSupported","wnd","indexedDB","window","mozIndexedDB","webkitIndexedDB","msIndexedDB","IDBTransaction","webkitIDBTransaction","msIDBTransaction","READ_WRITE","IDBKeyRange","webkitIDBKeyRange","msIDBKeyRange","addLocalParams","cmd","time","updatedAt","toISOString","localDB_localVersion","localDB_table","localDB_synced","removeLocalKeys","forEach","k","updateLocalStore","tbl","store","transaction","objectStore","put","excludeDeleted","allObj","request","openCursor","onsuccess","cursor","result","value","localDB_key","deleted","push","continue","getOneObject","get","processElem","foundlu","CreatorLocalID","sp","split","lu","dbo","updates","mydb","oncomplete","doUpsertOperation","dbkey","idata","operation","getObject","mutation","kk","copy","res","v","my","localDB_remoteCreated","localDB_failedCount","doOperation","localDB_opertaion","callSubFun","cmd1","pushUndoStack","found","u","val","del","objectStoreRequest","clear","event","onerror","pending","done","p","fc","SessionID","doundo","st","op","pop","ii","getUndoStack","doredo","lasttouch","localDB_localTimestamp","openRequest","open","onupgradeneeded","db1","objectStoreNames","contains","createObjectStore","keyPath","createIndex","unique","createObj","locl","gotObjs","undo","function","redo","registerCB","OBS","process","REACT_APP_OBS","gProfiles","NO_EXPIRY_TTL","MAX_SAVED_BOARDS_BASIC_PAID_PLAN","dispatchCB","setDispatchCB","fn","getDelTTL","Math","round","now","getTTL","paidUserPlan","userPaidPlan","Auth","user","uUtils","getTTL2Week","getTTLForDays","wait","MAX_RETRY_COUNT","RETRY_DELAY","s3HostPattern","s3UrlPattern","checkAndReSubscribe","retried","gaAction","errorObj","unSubObj","subFunc","context","errStr","getErrorString","dt","floor","valueOf","timeSet","indexOf","sendWBCReactGAEvent","windowreload","handleCommonErrors","SUB_MAX_RETRY_COUNT","unsubscribe","doList","category","label","action","slice","WBCReactGA","errArr","tmpIdx","item","replace","Sub","subObj","subArgs","subAction","this","subsciption","sub","subscribe","trySubscribeReal","trySubscribe","n","reallySubscribe","getQueryName","q1","errIdx","gqlOperationWithRetry","replaceChars","origStr","allowedLen","oneChar","retStr","repLen","repeat","removeMSTeamsEmail","em","email","getUserString","userName","userEmail","socialLogin","startsWith","MAX_EMAIL_LEN","days","genJoinCode","m","getMonth","y","getFullYear","array","Uint8Array","crypto","getRandomValues","code","chars","KEEPALIVE_TIMEOUT_SECONDS","isRestricted","location","host","checkRestriction","Classroom","validTeacher","alert","checkDomain","bc","props","match","domain","toLowerCase","getTenantById","boardsInternalTenantId","t","tenantConfig","nc","allLogin","boardAuthUsersOnly","boardsInternalTenant","boardsInternalTenantDomain","domainName","secondaryDomainConfig","x","allowedDomains","history","createSessionCommon","ten","TenantID","autoQuery","old","boardConfig","createWhiteboard","opts","name","TutorGroupID","uuid","luid","pg1","j","multiBoardOption","createClassroom","TeacherID","sess","content","parentId","pageNumber","parentBoardID","classr","isGroup","ttl","TutorClass","joinCode","toString","createSessionPlain","deleteSessionPlain","setupdel","createSessionIfNotThere","getSession","createSessionNotFound","pgSplit","parentSplit","cc","Error","findCreateSession","classroom","nt","limit","nextToken","sortDirection","filter","and","eq","ne","dat","findSessionbyID","deleteUserAndBoard","getboardsbyparent","deletePage","err","getLocalUsers","localId","CurrentUser","deleteUser","deleteLocalUsers","findCreateSessionByName","luname","customops","parentID","Users","uu1","js","localID","listObject","duplicatePage","newNum","oldSessionID","oldPageVal","pluson","createObjPlain","updateClassBoardsOrderAll","bo","getSessionByClassroomSync","pages","getboardsbyparentSync","slowLoad","quickLoad","page","boardOrder","updateClassBoardsConfig","sess2","updateClassBoardsTools","boardTools","getUserProfie","getUserProfile","deletePageNumber","createPaperObj","objIn","sessionid","raster","isJson","copy1","drawPaper","ff","exportJSON","type","pako","deflate","to","delSession","checkObjLocked","objType","rr","newobj","compressed","inflate","lockedClearAllowed","lock","delAllObjSession","group","userId","CreatedBy","jj","getSessionByJoinCode","updatePersonalConfig","pc","personalConfig","updateClassIfNeeded","url","up","JOINURL","localluid","cl","TeacherList","updateClassroom","delUsers","UserProfile","re3","dats","byProfileSorted","Session","getBoards","promises","savedOwner","all","getClassboardsByClass","classRoom","allList","getBoardsByTeacher","dateLast","gt","studentCount","findCreateUserProfile","avatar","signup","emailOptIn","needsUpdate","re","tmpName","processTenant","tvalue","assignLicensesAutomatically","entitlements","en","planType","paidPlan","dom","listTenantByDomain","queryByDomainName","t1","mainDomain","tval","userid","intype","createObjectanimate","animate","reCreateObject","updateAnimateObject","inp","updateObjPlain","listObjectSync","ObjectSubscribe","s2","s1","autoSub","next","delCB","s4","subCB","findUser","userProfileID","findUserLoop","userList","session","concat","userAvatar","cmdCopy","listUser","UserSubscribe","subscribeToSessionUsers","SessionSubscribe","subscribeToSession","delcb","listSession","f","today","setHours","getHours","getDate","createdAt","listSessions","SessionSubscribeAll","onCreateSession","createSessionSave","jc","childId","childBoardID","updateClassGroupTTL","classroomID","inputDict","updateClassroomEventsTTL","updateLocalUsersTTL","ClassroomID","updateMultiBoardTTL","updateUserTTL","getUrlFromMap","urlMap","fullUrl","setUrlInMap","newUrl","getMultiPageId","oldUuid","multiPageMap","setMultiPageId","newUuid","checkCopyUrl","multiPage","inKey","xtn","noExpire","checkUrl","oo","xx","g","copyFile","handleImage","tContent","entries","pageArray","tUrl","uds","uss","prefix","join","handleDrawPaperRaster","tContent2","source","bingo","stringReplaceAll","whatToReplace","whatToReplaceWith","RegExp","handleDrawPaperGroup","refresh","files","files2","Set","copied","updateObjsContentInternal","tContent3","updateObjsContent","updateObjTTL","idx3","updateGamePlayTTL","queryGamePlayBySession","_version","adjustContentForMove","paperInfo","spinner","spinnerId","prepObj","moveObj","newSessionID","arg","validateObjContent","str","printErr","ObjectSubscribeLocal","sessTtl","getAllBoards","refreshBoard","gotPages","updateDict","folderID","oldExpiry","getClassroomSync","saveBoard","ids","ipgSplit","pbid","back","listClassroomEventByClass","events","For","rep","createClassroomEvent","listClassGroupByClass","classes","createGroupForClass","members","updateEvents","importBoard","sessions","objects","filteredObjs","objCount","ob","cdDoneObj","makePageCopy","allItems","lastpage","pggg","parseInt","last","np","setName","row","path","passCurUpdatedAt","newName","tmpItem","listSessionByOwner","ownerid","SessionSubscribeByOwner","subscribeToSessionbyOwner","s3","subscribeToSessionDelbyOwner","sendClassEvent","ClassroomSubscribe","subscribeToClassroomById","createLocalUsers","listLocalUsersByClass","SubscribeLocalUsersByClass","subscribeToLocalUsersByClass","listSessionByClassroom","custom","q","SessionSubscribeByClassroom","subscribeToSessionbyClassroom","addPageOrder","req","max","boardConf","order","clearAllBoards","mode","gotBoards","teacherBoard","updateBoards","us","delOldUser","timeMin","anydels","pushURL","CellPhoneCall","enable","participantId","allVideo","VideoConferenceSet","boardLabelSet","labels","boardNameSet","boardConfigSet","getUserInfo","username","fbUserId","attributes","picture","getCurrentSession","sessID","href","deleteClassGroup","SubscribeClassGroupByClass","subscribeToClassGroup","idPass","NoOfStuds","foundPreCog","hasPreCogs","ppid","res2","count","createClassGroup","gp","grp","createNewGroup","updateGroupForClass","getClassroomEvent","listClassroomEventByClassSync","delChat","evs","SubscribeClassroomEventByClass","subscribeToClassroomEvents","createErrorLog","MonitorCB","dt2","ss","listObjectFilter","uptime","errcb","dt1","lastObjTS","gotObjMonitor","lastObj","AddSubMonitor","sessId","ResetSubsMonitor","clearInterval","runScript","scr","script","document","createElement","src","async","body","appendChild","onload","state","classID","board","update","createcb","State","Content","updateClassPolls","question","close","pollers","teacher","createClassPollEvent","updateClassEvent","GetFoldersByOwner","userProfileId","foldersByOwner","SubscribeFoldersByOwner","subscribeToFoldersbyOwner","subscribeToDelFoldersbyOwner","createFolder","parentFolderPath","updateFolder","deleteFolder","delId","checkStudentMove","parentObj","studentMoveParent","studentMoveParentID","visible","remove","createRaster","img","tobj","listCommunityBoardsSync","updateCommunityBoard","createCommunityBoard","findUserProfile","listUserProfiles","createPersonalPalette","updatePersonalPalette","deletePersonalPalette","SubscribePersonalPalettesByOwner","ListPersonalPalette","owner","byPOwnerSorted","subscribeToPalette","subscribeToDelPalette","createCommunityPalette","createGamePlay","sessionTTL","expectedVersion","version","findGamePlay","SubscribeGamePlay","subscribeToGamePlay","getLanguages","fetch","method","headers","response","json","languages","gTranslate","text","lang","postData","translateURL","target","params","ret","translations","translatedText","lockClass","classLevel","bytimer","creator","dateConvert","date","navigator","userLanguage","language","toLocaleString","weekday","month","day","hour","minute","gamePlayGarbage","classR","rightLoc","gotObjects","gamePlayAvatar","gamePlayAv","create","l","debounceClick","copyObjtoClipBoard","selected","copyObjstoClipBoard","selectedObjs","arr","objs","boardGradeSet","gradType","valtoset","expandObj","manualScore","createTextItem","color","sz","sessid","font","pointObj","lastItem","updateScore","percent","pgScoreCount","checkObjisPointObj","f22","processBoardCorrections","answerKey","compA","createItem","creatCheck","points","foundDZ","textBoxID","ans","up1","trim","toUpperCase","up2","answer","vals","correct","ignoreSpecial","pg","total","dropZone","answers","pts","ansKey","toFixed","lockSingle","single","autoCorrect","pageNum","ff2","linkData","mx","segments","rr2","removeBoardCorrection","autoCorrectRemove","truncateString","num","boardResoltionType","w","h","reload","deepCompare","leftChain","rightChain","compare2Objects","isNaN","String","Number","isPrototypeOf","constructor","prototype","hasOwnProperty","arguments","sendShowCaseEvent","studentID","student","sendFormSubmit","formID","form","clearUndefined","getService","getMSMktpAccToken","updateOembedLink","link","getElementById","encStr","encodeURIComponent","copyBoard","boardData","instanceObj","userEmailId","errCb","dict","post","exportCSV","boardName","filename","element","setAttribute","encodeURI","style","display","click","removeChild","doReport","processPage","savedUser","palette","firstObj","diff","s","report","evt","rh","chat","poll","enScore","ListEngagementEventSync","engagement","ee","engagementScore","calculated","nm","ct","tt","kind","set","from","pgNum","pageCreated","objectCount","stickers","timeSpent","Score","manualGrade","final","getEscapeRoomPage","pgnum","setEscapeRoomPage","oldpg","createEngagementEvent","SubscribeEngagementEventsByOwner","ListEngagementEvent","subscribeToEngagementEvent","getQueryStringParams","test","reduce","param","decodeURIComponent","getStoreApiMode","loc","firstcall","resetStore","byApiKey","listApiKey","docref","referrer","parent","gotTopDomain","c2","findUserProfileByEmail","byEmamilUP","iduse","btoa","findCreateApiKey","getAPIKey","getApiInfo","createAPIKey","r2","d2","createApiInfo","makeOpenAIImg","prompt","size","getImage","value2","findUserToMove","oldEmail","newEmail","newU","r1","new","updateUserSessions","oldUser","newUser","listClassroomByTeacher","queryByTeacher","wobotDisabled","wobotDisable","kommunicate","displayKommunicateWidget","isBotLoaded","rcSession","isChatOpen","rcSub","unsubscribeRC","subscribeRC","setWobotContext","subscribeToRemoteControl","updateChatContext","chatContext","wobotLoaded","resp","subscribeToEvents","wobotEnable","orientation","screen","width","kommunicateSettings","voiceOutput","voiceName","onInit","getElementsByTagName","_globals","getPlanDisplayName","planName","createTeam","getTeam","updateTeam","deleteTeam","listTeamSync","tenantID","listSessionByClassroomForTTL","listSessionByOwnerWithExpireDate","assignLicense","userProfiles","tenant","entitlement","revokeLicense","licensedUsers","listTenant","getAllTenantUsers","updateTenant","createTenant","adminUsers","getFEM","listFEMByAvatar","Avatar","listFEM","Public","createFEM","updateFEM","updateUserProfileForTenant","checkTenantExists","queryByTenantName","getMyName","isSiteAdmin","siteAdmin","authUser","updateBoard","postBoardMessage","postMessage","changedBoardName","createTutorGroup","updateTutorGroup","getTutorGroup","createTutorClass","updateTutorClass","getTutorClass","deleteTutorClass","listClassByTutorGroup","updateSessionBoards","checkTutorClass","userProfile","tc","roster","createTutorClassEvent","updateTutorClassEvent","deleteTutorClassEvent","createVideoRoom","updateVideoRoom","listVideoRoomBySessionSync","listVideoRoomBySID","SID","findCreateRoomBySid","setRecordingOnRoomBySid","rm","recordingTurnedOn","getRecordings","ses","rec","listTutorClassEventSync","TutorClassID","SubscribeToTutorClassEvent","listTutorClassEvent","classId","subscribeToTutorClassEvent","subscribeToTutorClassEventDel","downloadJsonFile","blob","Blob","URL","createObjectURL","download","exportObjectsJson","boardId","finalData","isExternalApi","chatGPTAPI","region","config","aws_user_files_s3_bucket_region","bucket","aws_user_files_s3_bucket","dataURLtoFile","dataurl","mime","bstr","atob","u8arr","charCodeAt","File","dataURItoBlob","dataURI","bytes","unescape","ia","resizeImage","settings","file","maxSize","reader","FileReader","image","Image","canvas","background","resize","height","getContext","ext","fillStyle","fillRect","drawImage","dataUrl","toDataURL","imgR","ok","no","readerEvent","ev","readAsDataURL","createImageRaster","randompages","numPages","ratio","scale","pdfText","splitstring","local","fd","finalPage","finalSession","createImage","newPoints","robj","loadPDF","SCALEPDF","pdfjsLib","p2","pdfjsWorker","GlobalWorkerOptions","workerSrc","getDocument","promise","pdf","maxPages","getPage","viewport","getViewport","hscale","wscale","maxSize2","allText","getTextContent","textContent","render","canvasContext","intent","getImageData","ctx2","putImageData","dataUrl2","f1","kb","wroteFile","rest","generateVideoThumbnail","video","autoplay","muted","crossOrigin","onloadeddata","videoWidth","videoHeight","pause","processPDF","fileReader","readAsArrayBuffer","readPNG","subFolderName","extension","mimeType","Storage","contentType","fetchSignedUrl","GetS3ProfileImage","fUrl","readFile","ts","fileExtArr","status","readBlob","getImageURL","writeBlob","WritePalette","UploadSmartFile","infile","sj","SmartImport","importFile","UploadIwbFile","IwbImport","UploadFile","fileR","loadImage","UploadIWBObjects","UploadImportedFile","writeFileReturn","GetImage","expires","GetS3File","ReadFile","uploadMediaFile","userHasNoBoardExpiry","getChargeBeeId","validateEmail","initDone","AmpInit","awsExports","oauth","redirectSignIn","origin","redirectSignOut","aws_appsync_authenticationType","Amplify","configure"],"mappings":"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","file":"static/js/6.2c20b5f8.chunk.js","sourcesContent":["/* eslint-disable */\n// WARNING: DO NOT EDIT. This file is automatically generated by AWS Amplify. It will be overwritten.\n\nconst awsmobile = {\n    \"aws_project_region\": \"us-east-2\",\n    \"aws_cognito_identity_pool_id\": \"us-east-2:e8634429-d135-43f7-9055-018cad230f45\",\n    \"aws_cognito_region\": \"us-east-2\",\n    \"aws_user_pools_id\": \"us-east-2_61SKKCWde\",\n    \"aws_user_pools_web_client_id\": \"6106f5gs2ggu24mk2adv6e1vo4\",\n    \"oauth\": {\n        \"domain\": \"whiteboard-master.auth.us-east-2.amazoncognito.com\",\n        \"scope\": [\n            \"phone\",\n            \"email\",\n            \"openid\",\n            \"profile\",\n            \"aws.cognito.signin.user.admin\"\n        ],\n        \"redirectSignIn\": \"http://localhost:3000/login/,https://eb.epiphani.ai/login/,https://www.shayr.us/login/,https://www.whiteboard.chat/login/,https://newpmdev.drtb0o61d9u0.amplifyapp.com/login/,https://www.asia.whiteboard.chat/login/,https://wb.whiteboard.chat/login/,https://uswest.whiteboard.chat/login/,https://restricted.whiteboard.chat/login/\",\n        \"redirectSignOut\": \"http://localhost:3000/logout/,https://eb.epiphani.ai/logout/,https://www.shayr.us/logout/,https://www.whiteboard.chat/logout/,https://newpmdev.drtb0o61d9u0.amplifyapp.com/logout/,https://www.asia.whiteboard.chat/logout/,https://wb.whiteboard.chat/logout/,https://uswest.whiteboard.chat/logout/,https://restricted.whiteboard.chat/logout/\",\n        \"responseType\": \"code\"\n    },\n    \"federationTarget\": \"COGNITO_USER_POOLS\",\n    \"aws_cognito_username_attributes\": [\n        \"EMAIL\"\n    ],\n    \"aws_cognito_social_providers\": [\n        \"FACEBOOK\",\n        \"GOOGLE\"\n    ],\n    \"aws_cognito_signup_attributes\": [\n        \"EMAIL\"\n    ],\n    \"aws_cognito_mfa_configuration\": \"OFF\",\n    \"aws_cognito_mfa_types\": [\n        \"SMS\"\n    ],\n    \"aws_cognito_password_protection_settings\": {\n        \"passwordPolicyMinLength\": 8,\n        \"passwordPolicyCharacters\": []\n    },\n    \"aws_cognito_verification_mechanisms\": [\n        \"EMAIL\"\n    ],\n    \"aws_appsync_graphqlEndpoint\": \"https://zfwoao5vafh6noze7valybuld4.appsync-api.us-east-2.amazonaws.com/graphql\",\n    \"aws_appsync_region\": \"us-east-2\",\n    \"aws_appsync_authenticationType\": \"AMAZON_COGNITO_USER_POOLS\",\n    \"aws_cloud_logic_custom\": [\n        {\n            \"name\": \"serviceApi\",\n            \"endpoint\": \"https://b5rbaoc2ak.execute-api.us-east-2.amazonaws.com/master\",\n            \"region\": \"us-east-2\"\n        },\n        {\n            \"name\": \"tenantApi\",\n            \"endpoint\": \"https://fgbpfcmaw3.execute-api.us-east-2.amazonaws.com/master\",\n            \"region\": \"us-east-2\"\n        }\n    ],\n    \"aws_user_files_s3_bucket\": \"collaborate637449bed9df4b3d944f19e6b9b6effe93353-master\",\n    \"aws_user_files_s3_bucket_region\": \"us-east-2\",\n    \"aws_cognito_login_mechanisms\": [\n        \"EMAIL\"\n    ]\n};\n\n\nexport default awsmobile;\n","import * as ib from './ibdata'\n\nexport const CacheDraw = (function () {\n    var cache = {}\n    var subs = {}\n    var cb = null\n    var timer = null\n\n    function cacheSubs(obj, d, i, c, cb) {\n        if (!timer) return false\n        subs[obj.id] = { o: obj, d: d, i: i, c: c, cb: cb }\n        return true\n    }\n    function initCache(args) {\n    }\n\n    function timerDone() {\n        // maybe should sort in the order it was created?\n        // Create items array\n        var items = Object.keys(cache).map(function (key) {\n            return cache[key];\n        });\n\n        items.sort(function (a, b) {\n            return a.createTime - b.createTime\n        })\n        for (let i = 0; i < items.length; i++) {\n            let o = items[i]\n            if (!o.ended) continue\n            if (!o.created) {\n                delete o['intype']\n                delete o['createTime']\n                ib.createObjPlain(o).then(r => {\n                    const obj = r.data.createObject\n                    if (!obj.ended) {\n                        cache[obj.id].created = true\n                    }\n                })\n            } else {\n                delete o['intype']\n                delete o['created']\n                delete o['createTime']\n                ib.updateObject(o).then(r => {\n                    const obj = r.data.updateObject\n                    if (cache[obj.id]) {\n                        cache[obj.id].created = true\n                    }\n                })\n            }\n            if (o.ended) {\n                //leave it in the cache\n                if (cb) cb(cache[o.id])\n                delete cache[o.id]\n            }\n        }\n    }\n    function timerInit() {\n        if (timer != null) {\n            clearTimeout(timer)\n            timer = null\n        }\n        timer = setTimeout(timerDone, 300)\n    }\n\n    function newObj(obj, cb1) {\n        cb = cb1\n        if (!obj.id) {\n            console.error(\"GOT BAD OBJ\", obj)\n            return\n        }\n        timerInit()\n        cache[obj.id] = JSON.parse(JSON.stringify(obj))\n        cache[obj.id].createTime = new Date().getTime();\n    }\n\n    function updateObj(obj) {\n        if (!obj.id) {\n            console.error(\"GOT BAD OBJ\", obj)\n            return\n        }\n        timerInit()\n        if (cache[obj.id] && cache[obj.id].created) obj.created = cache[obj.id].created\n        if (cache[obj.id]) {\n            obj.createTime = cache[obj.id].createTime\n        }\n        cache[obj.id] = obj\n    }\n\n    function endPath(obj) {\n        if (!obj.id) {\n            console.error(\"GOT BAD OBJ\", obj)\n            return\n        }\n        timerInit()\n        if (cache[obj.id] && cache[obj.id].created) obj.created = cache[obj.id].created\n        if (cache[obj.id]) {\n            obj.createTime = cache[obj.id].createTime\n        }\n        cache[obj.id] = obj\n    }\n\n    function delObject(id) {\n        delete cache[id]\n    }\n\n    function stillDrawing() {\n        timerInit()\n    }\n    return {\n        initCache,\n        newObj,\n        updateObj,\n        endPath,\n        cacheSubs,\n        delObject,\n        stillDrawing\n    }\n\n})()","import { API, graphqlOperation } from 'aws-amplify';\nimport * as mylocalStorage from \"./mylocalStorage\"\nimport * as ib from './ibdata';\nimport * as autoMutation from './graphql/mutations'\n\nconst mutations = {\n    'create': autoMutation.createObject,\n    'update': autoMutation.updateObject\n}\nconst wait = ms => new Promise(r => setTimeout(r, ms));\nvar callDispatch = null\nvar timer1 = null\nvar timer2 = null\nvar firsttime = true\nvar gSession\nvar functions = {\n    'newObj': null,\n    'delObj': null,\n    'session': null\n}\nexport const LocalDB = (function () {\n    var db = null\n    var undoops = {\n        redostack: [], undostack: []\n    }\n    // var lastKey = null\n    // var undoPos = null\n    var failedOperation = false\n\n    function resetUndoStack() {\n        undoops = {\n            redostack: [], undostack: []\n        }\n    }\n    // based on: https://stackoverflow.com/questions/38213668/promise-retry-design-patterns\n    // answer by: Yair Kukielka\n    const localgqlOperationWithRetry = (query, args, delay, retryCount) => new Promise((resolve, reject) => {\n        if ((delay === null) || (delay === undefined)) delay = ib.RETRY_DELAY;\n        if ((retryCount === null) || (retryCount === undefined)) retryCount = ib.MAX_RETRY_COUNT;\n        //console.log(\"gqlOperationWithRetry:\", args);\n        ib.validateObjContent(args.input, \"writing to gql\")\n        return API.graphql(graphqlOperation(query, args))\n            .then(resolve)\n            .catch((error) => {\n                // let errStr = ib.getErrorString(error);\n                let qStr = ib.getQueryName(query);\n                console.error(\"gqlOperationWithRetry:\", error, args);\n                try {\n                    let doRetry = true;\n                    if ((\"errors\" in error) && Array.isArray(error.errors)) {\n                        for (let idx in error.errors) {\n                            if (error.errors[idx].errorType === \"DynamoDB:ConditionalCheckFailedException\") {\n                                doRetry = false;\n                                // errStr = `DynamoDB:ConditionalCheckFailedException`\n                                qStr = `${qStr}: ${JSON.stringify(args)}`;\n                                break;\n                            }\n                            if (error.errors[idx].errorType === \"DynamoDB:DynamoDbException\") {\n                                doRetry = false;\n                                // errStr = `DynamoDB:DynamoDbException`\n                                qStr = `${qStr}: ${JSON.stringify(args)}`;\n                                break;\n                            }\n                            // TODO: Add checks for more errors here.\n                        }\n                    } else if (error.message || error.stack) {\n                        // Try to retry\n                    } else {\n                        // Could not figure out the error type.\n                        doRetry = false;\n                    }\n                    if (doRetry) {\n                        // Check & Retry the API call\n                        retryCount = retryCount - 1;\n\n                        if (retryCount > 0) {\n                            if (retryCount >= (ib.MAX_RETRY_COUNT - 1)) {\n                                console.log(\"GIVE UP\")\n                            }\n                            return wait(delay)\n                                .then(localgqlOperationWithRetry.bind(null, query, args, delay, retryCount))\n                                .then(resolve)\n                                .catch(reject);\n                        }\n                    }\n                } catch (e) {\n                    // got an error while processing API call error, just break out\n                    console.log(\"GQL_OPER_HANDLER_ERROR\", qStr,\n                        ib.getErrorString(e), retryCount);\n\n                    console.log(\"gqlOperationWithRetry: Got an error while processing API call error:\", e)\n                }\n\n                if (!retryCount) {\n                    if (qStr && qStr.includes('Object')) {\n                        // reject anything \n                        if (qStr && qStr.includes('Object')) {\n                            callDispatch({ msg: \"NETWORK ERROR: The app will try to resync but you may \", sev: \"error\", button: \"Refresh\", timeout: 20000 })\n                        }\n                    }\n                }\n                return reject(error);\n            })\n    })\n\n\n\n    async function registerCB(newObj, delObj, callDispatch1, ctx) {\n        functions['newObj'] = newObj\n        functions['delObj'] = delObj\n        functions['session'] = ctx.sessionID\n\n        resetUndoStack()\n        callDispatch = callDispatch1\n        if (ctx) {\n            gSession = ctx.sessionID\n            if (firsttime) {\n                await init()\n                setInterval(cleanOldTimer, 600 * 1000);\n                setInterval(doPendingTimer, 3 * 1000);\n            }\n            var lu = mylocalStorage.getItem(\"storedSession\")\n            if (lu !== gSession) {\n                //other session clear it\n                await clearTable()\n                mylocalStorage.setItem(\"storedSession\", gSession)\n            }\n            //optimization to get all values first \n            let dbobj = await getAllObjects(true)\n\n            newObj(dbobj)\n\n            doPending()\n            cleanOld(firsttime)\n\n            firsttime = false\n        }\n    }\n\n    function isSupported() {\n        let wnd = {}\n        // In the following line, you should include the prefixes of implementations you want to test.\n        wnd.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;\n        // DON'T use \"var indexedDB = ...\" if you're not in a function.\n        // Moreover, you may need references to some window.IDB* objects:\n        wnd.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction || { READ_WRITE: \"readwrite\" }; // This line should only be needed if it is needed to support the object's constants for older browsers\n        wnd.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;\n        // (Mozilla has never prefixed these objects, so we don't need window.mozIDB*)\n\n        if (!wnd.indexedDB) {\n            return false\n        }\n\n        return true\n    }\n\n    function addLocalParams(cmd) {\n        var time = new Date()\n\n        if (cmd.updatedAt) {\n            time = new Date(cmd.updatedAt)\n        }\n        cmd['localDB_localTimestamp'] = time.getTime(); // delete old records like this: db.records.where('timestamp').below(Date.now() - 2419200000).delete()\n        cmd.updatedAt = time.toISOString()\n        if (cmd.localDB_localVersion) {\n            cmd.localDB_localVersion = cmd.localDB_localVersion + 1\n        } else {\n            cmd.localDB_localVersion = 1\n        }\n        cmd.localDB_table = 'Object'\n\n        cmd.localDB_synced = false\n        return cmd\n    }\n\n    function removeLocalKeys(cmd) {\n        let keys = Object.keys(cmd)\n        keys.forEach(k => {\n            if (k.includes('localDB_')) {\n                delete cmd[k]\n            }\n        })\n    }\n\n    function updateLocalStore(cmd, key) {\n\n        let tbl = cmd.localDB_table\n        let store = db.transaction(tbl, \"readwrite\").objectStore(tbl);\n        ib.validateObjContent(cmd, \"update local\")\n        store.put(cmd)//, key)\n        // rr.onsuccess = function () {\n        //     console.log(\"FINISHE\", rr.result)\n        // }\n        return store\n    }\n\n    function getAllObjects(excludeDeleted) {\n        return new Promise((resolve, reject) => {\n            let tbl = \"Object\"\n            let allObj = []\n            let del = db.transaction(tbl, \"readwrite\").objectStore(tbl)\n\n            let request = del.openCursor();\n            // called for each book found by the cursor\n            request.onsuccess = function () {\n                let cursor = request.result;\n                if (cursor) {\n                    let key = cursor.key; // book key (id field)\n                    let value = cursor.value; // book object\n                    let r = value\n                    r = addLocalParams(r)\n                    r.localDB_key = key\n                    if (!excludeDeleted || !r.deleted) {\n                        allObj.push(r)\n                    }\n                    cursor.continue();\n                } else {\n                    resolve(allObj)\n                }\n            }\n        })\n    }\n\n    function getOneObject(id) {\n        return new Promise((resolve, reject) => {\n            let tbl = \"Object\"\n            let del = db.transaction(tbl, \"readwrite\").objectStore(tbl)\n\n            let request = del.get(id);\n            // called for each book found by the cursor\n            request.onsuccess = function () {\n                resolve(request.result)\n            }\n        })\n\n    }\n    async function gotObjs(items) {\n        if (!window.mydb) return\n\n        let updates = []\n        let tbl = \"Object\"\n        // let dbobj = await getAllObjects()\n        let lu = mylocalStorage.getItem('mystoreID');\n\n        // console.log(\"DB OBJS\", dbobj)\n\n        async function processElem(o) {\n            let foundlu = null\n            if (o.CreatorLocalID) {\n                let sp = o.CreatorLocalID.split('@@')\n                if (sp.length > 1) {\n                    foundlu = sp[0]\n                }\n                if (foundlu && foundlu !== lu) {\n                    //someone else did this, ignore\n                    return\n                }\n            }\n            let dbo = await getOneObject(o.id)\n            let cmd = addLocalParams(o)\n            if (dbo && dbo.updatedAt === o.updatedAt) {\n                // dbkey = dbobj[mykey].localDB_key\n                // already ahve it\n                return\n            } else {\n                updates.push(cmd)\n            }\n        }\n        for (let i = 0; i < items.length; i++) {\n            let o = items[i]\n            await processElem(o)\n        }\n\n        let transaction = db.transaction(tbl, \"readwrite\")\n        let store = transaction.objectStore(tbl);\n        updates.forEach(cmd => {\n            cmd.localDB_synced = true\n            ib.validateObjContent(cmd, \"got from sub\")\n            store.put(cmd)\n        })\n        transaction.oncomplete = function () {\n            // console.log(\"Transaction is complete\");\n        }\n    }\n\n    function doUpsertOperation(cmd, dbkey) {\n        return new Promise(async (resolve, reject) => {\n            let lu = mylocalStorage.getItem('mystoreID');\n            let idata = null\n            try {\n                idata = await ib.getObject(cmd.id)\n            } catch (e) {\n                cmd.localDB_synced = false\n                reject(e)\n            }\n            let operation = 'update'\n            if (!idata || !idata.data || !idata.data.getObject) operation = 'create'\n            let tbl = cmd.localDB_table\n            // let operation = cmd.localDB_opertaion\n            let mutation = mutations[operation]\n\n            let kk = operation + tbl\n\n            let copy = JSON.parse(JSON.stringify(cmd))\n            removeLocalKeys(copy)\n            if (operation === \"create\")\n                copy.CreatorLocalID = lu + \"@@\" + dbkey\n            if (!copy.deleted) copy.deleted = false //gql doesnt handle undefined properly\n\n            delete copy['Session']\n            \n            localgqlOperationWithRetry(mutation, { input: copy }).then(res => {\n                //update synced flag for obj\n                let v = res.data[kk]\n                if (v) {\n                    Object.keys(v).forEach(my => {\n                        //update all schema keys\n                        cmd[my] = v[my]\n                    })\n                    cmd.localDB_synced = true\n                    cmd.localDB_remoteCreated = true\n                    updateLocalStore(cmd, dbkey)\n                    resolve(cmd)\n                }\n\n            }).catch(e => {\n                if (operation === \"create\") {\n                    //lets try update because object maybe there and deleted state\n                    mutation = mutations[\"update\"]\n                    let kk = \"update\" + tbl\n\n                    localgqlOperationWithRetry(mutation, { input: copy }).then(res => {\n                        let v = res.data[kk]\n                        if (v) {\n                            Object.keys(v).forEach(my => {\n                                //update all schema keys\n                                cmd[my] = v[my]\n                            })\n                            cmd.localDB_synced = true\n                            cmd.localDB_remoteCreated = true\n                            updateLocalStore(cmd, dbkey)\n                            resolve(cmd)\n                        }\n                    })\n                }\n                //failed to update\n                cmd.localDB_synced = false\n                if (cmd.localDB_failedCount) {\n                    cmd.localDB_failedCount++\n                } else {\n                    cmd.localDB_failedCount = 1\n                }\n                cmd.localDB_remoteCreated = false\n                failedOperation = true\n                updateLocalStore(cmd, dbkey)\n                reject(e)\n            })\n        })\n    }\n\n\n    function doOperation(cmd, dbkey) {\n        return new Promise(async (resolve, reject) => {\n            let lu = mylocalStorage.getItem('mystoreID');\n\n            let tbl = cmd.localDB_table\n            let operation = cmd.localDB_opertaion\n            let mutation = mutations[operation]\n\n            let kk = operation + tbl\n\n            let copy = JSON.parse(JSON.stringify(cmd))\n            removeLocalKeys(copy)\n            if (operation === \"create\")\n                copy.CreatorLocalID = lu + \"@@\" + dbkey\n            delete copy['Session']\n            delete copy['created']\n\n            localgqlOperationWithRetry(mutation, { input: copy }).then(res => {\n                //update synced flag for obj\n                let v = res.data[kk]\n                if (v) {\n                    Object.keys(v).forEach(my => {\n                        //update all schema keys\n                        cmd[my] = v[my]\n                    })\n                    cmd.localDB_synced = true\n                    cmd.localDB_remoteCreated = true\n                    updateLocalStore(cmd, dbkey)\n                    resolve(cmd)\n                }\n\n            }).catch(e => {\n                //failed to update\n                cmd.localDB_synced = false\n                if (cmd.localDB_failedCount) {\n                    cmd.localDB_failedCount++\n                } else {\n                    cmd.localDB_failedCount = 1\n                }\n                cmd.localDB_remoteCreated = false\n                failedOperation = true\n                updateLocalStore(cmd, dbkey)\n                reject(e)\n            })\n        })\n    }\n\n\n    function callSubFun(cmd1) {\n        //this function messes with the object so make a copy\n        let cmd = JSON.parse(JSON.stringify(cmd1))\n        if (cmd.deleted) {\n            if (functions['delObj']) {\n                functions['delObj'](cmd)\n            }\n        } else {\n            if (functions['newObj']) {\n                functions['newObj']([cmd])\n            }\n        }\n    }\n\n    async function pushUndoStack(cmd) {\n        //check to see if we have in the stack\n        let id = cmd.value.id\n        let found = null\n        undoops.undostack.forEach(u => {\n            if (u.value.id === id) found = true\n        })\n        if (!found) {\n            //get from db\n            let val = await getOneObject(id)\n            if (val)\n                undoops.undostack.push({ key: id, value: val }) //push db state first\n        }\n        undoops.undostack.push(cmd)\n    }\n\n    function createObj(cmd1) {\n        return new Promise(async (resolve, reject) => {\n            let cmd = JSON.parse(JSON.stringify(cmd1))\n\n            let tbl = cmd.localDB_table\n            let operation = cmd.localDB_opertaion\n            let locl = addLocalParams(cmd)\n            //delete everything after this because we have already undone it\n            undoops.redostack = []\n            await pushUndoStack({ key: cmd.id, value: cmd })\n            // printstacks(\"AFTER PUSH STACK\")\n\n            let store = db.transaction(tbl, \"readwrite\").objectStore(tbl);\n            ib.validateObjContent(cmd, \"created by user\")\n\n            let res = store.put(locl)//add(locl)\n            res.onsuccess = function () {\n                let kk = operation + tbl\n                let result = { data: { [kk]: cmd } }\n                let dbkey = res.result\n                resolve(result); // return first so that the obj can appear\n                callSubFun(cmd)\n                // do the gql opertaion node \n                try {\n                    doOperation(cmd, dbkey)\n                } catch (e) {\n                    console.log(\"ERROR IN SYNC\", e)\n                }\n            }\n            res.onerror = function () {\n                console.log(\"Error\", res.error);\n                reject(res.error)\n            };\n        })\n    }\n\n    function clearTable() {\n        return new Promise(async (resolve, reject) => {\n            let tbl = \"Object\"\n            let del = db.transaction(tbl, \"readwrite\").objectStore(tbl)\n            var objectStoreRequest = del.clear();\n\n            objectStoreRequest.onsuccess = function (event) {\n                // report the success of our request\n                resolve()\n            };\n            objectStoreRequest.onerror = function (event) {\n                reject()\n            }\n        })\n    }\n\n    function cleanOld(firsttime) {\n        return\n        // const time = (Date.now() - 15 * 60 * 1000) //15 minutes\n        // let tbl = \"Object\"\n        // let del = db.transaction(tbl, \"readwrite\").objectStore(tbl)\n\n        // let request = del.openCursor();\n        // if (firsttime)\n        //     lastKey = 0\n        // // called for each book found by the cursor\n        // request.onsuccess = function () {\n        //     let cursor = request.result;\n        //     if (cursor) {\n        //         let key = cursor.key; // book key (id field)\n        //         let value = cursor.value; // book object\n        //         let r = value\n        //         if (firsttime)\n        //             lastKey = key\n        //         if (r.localDB_localTimestamp < time) {\n        //             del.delete(key)\n        //         }\n        //         cursor.continue();\n        //     }\n        // };\n    }\n\n    function doPending() {\n        let tbl = \"Object\"\n        let del = db.transaction(tbl, \"readwrite\").objectStore(tbl)\n\n        let request = del.openCursor();\n\n        let pending = []\n        // called for each book found by the cursor\n        request.onsuccess = async function () {\n            let cursor = request.result;\n            if (cursor) {\n                let key = cursor.key; // book key (id field)\n                let value = cursor.value; // book object\n                let r = value\n                let fc = r.localDB_failedCount ? r.localDB_failedCount : 0\n                if (!r.localDB_synced && fc < 5 && r.SessionID === gSession) { //try 5 times\n                    pending.push({ 'key': key, 'cmd': r })\n                }\n                cursor.continue();\n            } else {\n                if (pending.length === 0) {\n                    failedOperation = false\n                } else {\n                    failedOperation = true\n                    done()\n                }\n            }\n        };\n        async function done() {\n            for (let i = 0; i < pending.length; i++) {\n                let p = pending[i]\n                let r = p.cmd\n                try {\n                    await doUpsertOperation(r, p.key)\n                } catch (e) {\n                    console.log(\"RETRY FAILED\", e)\n                }\n            }\n        }\n    }\n    function cleanOldTimer() {\n        cleanOld(false)\n    }\n    function doPendingTimer() {\n        if (!failedOperation) return\n        doPending()\n    }\n\n    // function getUndoTopStack() {\n    //     return new Promise(async (resolve, reject) => {\n    //         let tbl = \"Object\"\n    //         let objectStore = db.transaction(tbl, \"readwrite\").objectStore(tbl)\n    //         let stack = []\n    //         let top = null\n    //         var index = objectStore.index('localDB_localTimestamp');\n    //         var openCursorRequest = index.openCursor(null, 'prev');\n    //         openCursorRequest.onsuccess = function (event) {\n    //             let cursor = openCursorRequest.result;\n    //             if (cursor) {\n    //                 let v = { key: cursor.primaryKey, value: cursor.value }\n    //                 if (v.value.localDB_localTimestamp > undoops.lasttouch) {\n    //                     cursor.continue()\n    //                     return\n    //                 }\n    //                 if (top === null) {\n    //                     top = v\n    //                     undoops.lasttouch = v.value.localDB_localTimestamp - 1\n    //                 }\n    //                 if (cursor.value.id === top.value.id) {\n    //                     stack.push(v)\n    //                 }\n    //                 if (stack.length > 1) {\n    //                     done()\n    //                 }\n    //                 // if (event.target.result) {\n    //                 //     console.log(\"FOUND\", event.target.result.value, event.target.result.primaryKey)\n    //                 // }\n    //                 cursor.continue()\n    //             } else {\n    //                 console.log(\"FINISHED\")\n    //                 done()\n    //             }\n    //         };\n    //         function done() {\n    //             resolve(stack)\n    //         }\n    //     });\n    // }\n\n    function getUndoStack() {\n        let stack = []\n        if (!undoops.undostack || undoops.undostack.length === 0) return []\n        let op = undoops.undostack.pop()\n        stack.push(op)\n        for (let i = undoops.undostack.length - 1; i >= 0; i--) {\n            let ii = undoops.undostack[i]\n            if (ii.value.id === op.value.id) {\n                stack.push(ii)\n                break;\n            }\n        }\n        return stack\n    }\n\n    // function printstacks(str) {\n    //     console.log(\"=================================\")\n    //     console.log(\"==============\", str, \"=================\")\n\n    //     console.log(\"=================================\")\n\n    //     console.log(\"UNDO\", undoops.undostack)\n    //     for (let i =0; i <  undoops.undostack.length; i++){\n    //         let s =  undoops.undostack[i]\n    //         console.log(\"   STCK\", i, s.key, s.value.type, s.value.objType, s.value.localDB_opertaion)\n    //     }\n    //     console.log(\"REDO\", undoops.redostack)\n    //     for (let i =0; i <  undoops.redostack.length; i++){\n    //         let s =  undoops.redostack[i]\n    //         console.log(\"   STCK\", i, s.key, s.value.type, s.value.objType, s.value.localDB_opertaion)\n    //     }\n    //     console.log(\"=================================\")\n    // }\n    function undo() {\n        ib.debounceClick({ timer: timer1, function: doundo, timeout: 400, args: null })\n    }\n    function doundo() {\n        // printstacks(\"BEFORE UNDO\")\n        // let st = await getUndoTopStack()\n        let st = getUndoStack()\n        if (st.length === 0) {\n            return\n        }\n        // return\n        let op = st[0].value\n        if (op.localDB_opertaion === \"create\") {\n            //just delete it\n            undoops.redostack.push(JSON.parse(JSON.stringify(st[0])))\n            op.localDB_opertaion = \"update\"\n            op.deleted = true\n            delete op['updatedAt']\n            op = addLocalParams(op)\n            updateLocalStore(op, st[0].key)\n\n            callSubFun(op)\n            try {\n                doUpsertOperation(op, st[0].key)\n            } catch { }\n            // printstacks(\"AFTER UNDO\")\n\n            return\n        }\n        if (op.localDB_opertaion === \"update\" && st.length > 1) {\n            //go to previous version\n            undoops.redostack.push(JSON.parse(JSON.stringify(st[0])))\n            op = JSON.parse(JSON.stringify(st[1].value))\n            op.localDB_opertaion = \"update\"\n            delete op['updatedAt']\n            op = addLocalParams(op)\n            updateLocalStore(op, st[0].key)\n\n            callSubFun(op)\n            try {\n                doUpsertOperation(op, st[0].key)\n            } catch { }\n            // printstacks(\"AFTER UNDO\")\n\n            return\n        }\n        if (op.localDB_opertaion === \"update\" && st.length === 1) {\n            undoops.redostack.push(JSON.parse(JSON.stringify(st[0])))\n            op.localDB_opertaion = \"update\"\n            if (op.deleted)\n                op.deleted = false\n            delete op['updatedAt']\n            op = addLocalParams(op)\n            updateLocalStore(op, st[0].key)\n\n            callSubFun(op)\n            try {\n                doUpsertOperation(op, st[0].key)\n            } catch { }\n            // printstacks(\"AFTER UNDO\")\n\n            return\n        }\n        // printstacks(\"AFTER UNDO\")\n\n    }\n\n    function redo() {\n        ib.debounceClick({ timer: timer2, function: doredo, timeout: 400, args: null })\n    }\n    function doredo() {\n        // printstacks(\"BEFORE ReDO\")\n        if (!undoops.redostack || undoops.redostack.length === 0) return\n        let op = undoops.redostack.pop()\n        delete op.value['updatedAt']\n        let cmd = addLocalParams(op.value)\n        undoops.lasttouch = cmd.localDB_localTimestamp\n\n        undoops.undostack.push(JSON.parse(JSON.stringify(op)))\n        updateLocalStore(cmd, op.key)\n        callSubFun(cmd)\n        try {\n            doUpsertOperation(cmd, op.key)\n        } catch { }\n        // printstacks(\"AFTER ReDO\")\n\n    }\n    function init() {\n        return new Promise(async (resolve, reject) => {\n\n            if (!isSupported()) {\n                resolve()\n            }\n\n            // if (initDone) {\n            //     doPending()\n            //     cleanOld(firsttime)\n            //     return\n            // }\n            // initDone = true\n            let openRequest = indexedDB.open(\"wbCache\", 1);\n\n            // create/upgrade the database without version checks\n            openRequest.onupgradeneeded = function () {\n                let db1 = openRequest.result;\n                if (!db1.objectStoreNames.contains('Object')) { // if there's no \"books\" store\n                    let objectStore = db1.createObjectStore('Object', { keyPath: \"id\" })//{ autoIncrement: true }); // create it\n                    // objectStore.createIndex(\"id\", \"id\", { unique: false });\n                    // objectStore.createIndex(\"SessionID\", \"SessionID\", { unique: false });\n                    objectStore.createIndex(\"localDB_localTimestamp\", \"localDB_localTimestamp\", { unique: false });\n                }\n            };\n            openRequest.onsuccess = function () {\n                db = openRequest.result;\n                window.mydb = db\n\n                resolve()\n                // continue working with database using db object\n            };\n            openRequest.onerror = function () {\n                reject()\n            }\n        })\n\n    }\n    return {\n        isSupported,\n        init,\n        createObj,\n        gotObjs,\n        undo,\n        redo,\n        registerCB,\n    }\n})()","/* eslint-disable */\n// this is an auto generated file. This will be overwritten\n\nexport const getSession = /* GraphQL */ `\n  query GetSession($id: ID!) {\n    getSession(id: $id) {\n      id\n      name\n      content\n      createdAt\n      updatedAt\n      Objects {\n        items {\n          id\n          name\n          content\n          type\n          objType\n          ended\n          createdAt\n          updatedAt\n          SessionID\n          ttl\n          animate\n          CreatedBy\n          CreatorLocalID\n          DisableSync\n          deleted\n        }\n        nextToken\n      }\n      ttl\n      savedOwner\n      parentID\n      pageNumber\n      boardConfig\n      Users {\n        items {\n          id\n          name\n          createdAt\n          updatedAt\n          SessionID\n          content\n          UserProfile\n          ttl\n          avatar\n        }\n        nextToken\n      }\n      parentBoardID\n      folderID\n      Classroom\n      CreatorLocalID\n      MultiBoard {\n        items {\n          id\n          parentBoardID\n          childBoardID\n          ttl\n          createdAt\n          updatedAt\n        }\n        nextToken\n      }\n      isGroup\n      joinCode\n      TenantID\n      deleted\n      TutorClass\n    }\n  }\n`;\nexport const listSessions = /* GraphQL */ `\n  query ListSessions(\n    $filter: ModelSessionFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listSessions(filter: $filter, limit: $limit, nextToken: $nextToken) {\n      items {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      nextToken\n    }\n  }\n`;\nexport const getCommunityBoard = /* GraphQL */ `\n  query GetCommunityBoard($id: ID!) {\n    getCommunityBoard(id: $id) {\n      id\n      name\n      description\n      creator\n      creatorEmail\n      CreatorLocalID\n      Country\n      Grade\n      Subject\n      boardLink\n      content\n      createdAt\n      updatedAt\n      title\n      deleted\n    }\n  }\n`;\nexport const listCommunityBoards = /* GraphQL */ `\n  query ListCommunityBoards(\n    $filter: ModelCommunityBoardFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listCommunityBoards(filter: $filter, limit: $limit, nextToken: $nextToken) {\n      items {\n        id\n        name\n        description\n        creator\n        creatorEmail\n        CreatorLocalID\n        Country\n        Grade\n        Subject\n        boardLink\n        content\n        createdAt\n        updatedAt\n        title\n        deleted\n      }\n      nextToken\n    }\n  }\n`;\nexport const getClassroom = /* GraphQL */ `\n  query GetClassroom($id: ID!) {\n    getClassroom(id: $id) {\n      id\n      name\n      TeacherID\n      content\n      Teacher {\n        id\n        name\n        createdAt\n        updatedAt\n        email\n        boardConfig\n        avatar\n        personalConfig\n        emailOptIn\n        paidPlan\n        validTeacher\n        adminOfTenant\n        TenantID\n        FEMStatus\n        lastVisitedSubs\n        MemberOfTeam\n        TutorGroupID\n      }\n      Users {\n        items {\n          id\n          content\n          createdAt\n          updatedAt\n          CurrentSessionId\n          CurrentUserId\n          ClassroomID\n          ttl\n          deleted\n        }\n        nextToken\n      }\n      ttl\n      createdAt\n      updatedAt\n      TeacherList\n    }\n  }\n`;\nexport const listClassrooms = /* GraphQL */ `\n  query ListClassrooms(\n    $filter: ModelClassroomFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listClassrooms(filter: $filter, limit: $limit, nextToken: $nextToken) {\n      items {\n        id\n        name\n        TeacherID\n        content\n        Teacher {\n          id\n          name\n          createdAt\n          updatedAt\n          email\n          boardConfig\n          avatar\n          personalConfig\n          emailOptIn\n          paidPlan\n          validTeacher\n          adminOfTenant\n          TenantID\n          FEMStatus\n          lastVisitedSubs\n          MemberOfTeam\n          TutorGroupID\n        }\n        Users {\n          nextToken\n        }\n        ttl\n        createdAt\n        updatedAt\n        TeacherList\n      }\n      nextToken\n    }\n  }\n`;\nexport const getGamePlay = /* GraphQL */ `\n  query GetGamePlay($id: ID!) {\n    getGamePlay(id: $id) {\n      id\n      Session\n      type\n      content\n      createdAt\n      updatedAt\n      version\n      ttl\n    }\n  }\n`;\nexport const listGamePlays = /* GraphQL */ `\n  query ListGamePlays(\n    $filter: ModelGamePlayFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listGamePlays(filter: $filter, limit: $limit, nextToken: $nextToken) {\n      items {\n        id\n        Session\n        type\n        content\n        createdAt\n        updatedAt\n        version\n        ttl\n      }\n      nextToken\n    }\n  }\n`;\nexport const getClassGroup = /* GraphQL */ `\n  query GetClassGroup($id: ID!) {\n    getClassGroup(id: $id) {\n      id\n      createdAt\n      updatedAt\n      ttl\n      name\n      content\n      Classroom\n      SessionID\n      deleted\n    }\n  }\n`;\nexport const listClassGroups = /* GraphQL */ `\n  query ListClassGroups(\n    $filter: ModelClassGroupFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listClassGroups(filter: $filter, limit: $limit, nextToken: $nextToken) {\n      items {\n        id\n        createdAt\n        updatedAt\n        ttl\n        name\n        content\n        Classroom\n        SessionID\n        deleted\n      }\n      nextToken\n    }\n  }\n`;\nexport const getClassroomEvent = /* GraphQL */ `\n  query GetClassroomEvent($id: ID!) {\n    getClassroomEvent(id: $id) {\n      id\n      createdAt\n      updatedAt\n      ttl\n      type\n      event\n      For\n      State\n      Content\n      Classroom\n      deleted\n    }\n  }\n`;\nexport const listClassroomEvents = /* GraphQL */ `\n  query ListClassroomEvents(\n    $filter: ModelClassroomEventFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listClassroomEvents(filter: $filter, limit: $limit, nextToken: $nextToken) {\n      items {\n        id\n        createdAt\n        updatedAt\n        ttl\n        type\n        event\n        For\n        State\n        Content\n        Classroom\n        deleted\n      }\n      nextToken\n    }\n  }\n`;\nexport const getEngagementEvent = /* GraphQL */ `\n  query GetEngagementEvent($id: ID!) {\n    getEngagementEvent(id: $id) {\n      id\n      createdAt\n      updatedAt\n      luid\n      name\n      time\n      ttl\n      Content\n      Classroom\n    }\n  }\n`;\nexport const listEngagementEvents = /* GraphQL */ `\n  query ListEngagementEvents(\n    $filter: ModelEngagementEventFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listEngagementEvents(\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        createdAt\n        updatedAt\n        luid\n        name\n        time\n        ttl\n        Content\n        Classroom\n      }\n      nextToken\n    }\n  }\n`;\nexport const getLocalUsers = /* GraphQL */ `\n  query GetLocalUsers($id: ID!) {\n    getLocalUsers(id: $id) {\n      id\n      content\n      createdAt\n      updatedAt\n      CurrentSession {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      CurrentSessionId\n      CurrentUserId\n      CurrentUser {\n        id\n        name\n        createdAt\n        updatedAt\n        SessionID\n        Session {\n          id\n          name\n          content\n          createdAt\n          updatedAt\n          ttl\n          savedOwner\n          parentID\n          pageNumber\n          boardConfig\n          parentBoardID\n          folderID\n          Classroom\n          CreatorLocalID\n          isGroup\n          joinCode\n          TenantID\n          deleted\n          TutorClass\n        }\n        content\n        UserProfile\n        ttl\n        avatar\n      }\n      ClassroomID\n      ttl\n      deleted\n    }\n  }\n`;\nexport const listLocalUserss = /* GraphQL */ `\n  query ListLocalUserss(\n    $filter: ModelLocalUsersFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listLocalUserss(filter: $filter, limit: $limit, nextToken: $nextToken) {\n      items {\n        id\n        content\n        createdAt\n        updatedAt\n        CurrentSession {\n          id\n          name\n          content\n          createdAt\n          updatedAt\n          ttl\n          savedOwner\n          parentID\n          pageNumber\n          boardConfig\n          parentBoardID\n          folderID\n          Classroom\n          CreatorLocalID\n          isGroup\n          joinCode\n          TenantID\n          deleted\n          TutorClass\n        }\n        CurrentSessionId\n        CurrentUserId\n        CurrentUser {\n          id\n          name\n          createdAt\n          updatedAt\n          SessionID\n          content\n          UserProfile\n          ttl\n          avatar\n        }\n        ClassroomID\n        ttl\n        deleted\n      }\n      nextToken\n    }\n  }\n`;\nexport const getMultiBoard = /* GraphQL */ `\n  query GetMultiBoard($id: ID!) {\n    getMultiBoard(id: $id) {\n      id\n      parentBoardID\n      parentBoard {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      childBoardID\n      childBoard {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      ttl\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const listMultiBoards = /* GraphQL */ `\n  query ListMultiBoards(\n    $filter: ModelMultiBoardFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listMultiBoards(filter: $filter, limit: $limit, nextToken: $nextToken) {\n      items {\n        id\n        parentBoardID\n        parentBoard {\n          id\n          name\n          content\n          createdAt\n          updatedAt\n          ttl\n          savedOwner\n          parentID\n          pageNumber\n          boardConfig\n          parentBoardID\n          folderID\n          Classroom\n          CreatorLocalID\n          isGroup\n          joinCode\n          TenantID\n          deleted\n          TutorClass\n        }\n        childBoardID\n        childBoard {\n          id\n          name\n          content\n          createdAt\n          updatedAt\n          ttl\n          savedOwner\n          parentID\n          pageNumber\n          boardConfig\n          parentBoardID\n          folderID\n          Classroom\n          CreatorLocalID\n          isGroup\n          joinCode\n          TenantID\n          deleted\n          TutorClass\n        }\n        ttl\n        createdAt\n        updatedAt\n      }\n      nextToken\n    }\n  }\n`;\nexport const getObject = /* GraphQL */ `\n  query GetObject($id: ID!) {\n    getObject(id: $id) {\n      id\n      name\n      content\n      type\n      objType\n      ended\n      createdAt\n      updatedAt\n      SessionID\n      ttl\n      animate\n      CreatedBy\n      CreatorLocalID\n      DisableSync\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      deleted\n    }\n  }\n`;\nexport const listObjects = /* GraphQL */ `\n  query ListObjects(\n    $filter: ModelObjectFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listObjects(filter: $filter, limit: $limit, nextToken: $nextToken) {\n      items {\n        id\n        name\n        content\n        type\n        objType\n        ended\n        createdAt\n        updatedAt\n        SessionID\n        ttl\n        animate\n        CreatedBy\n        CreatorLocalID\n        DisableSync\n        Session {\n          id\n          name\n          content\n          createdAt\n          updatedAt\n          ttl\n          savedOwner\n          parentID\n          pageNumber\n          boardConfig\n          parentBoardID\n          folderID\n          Classroom\n          CreatorLocalID\n          isGroup\n          joinCode\n          TenantID\n          deleted\n          TutorClass\n        }\n        deleted\n      }\n      nextToken\n    }\n  }\n`;\nexport const getTeam = /* GraphQL */ `\n  query GetTeam($id: ID!) {\n    getTeam(id: $id) {\n      id\n      name\n      TenantID\n      Members\n      Config\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const listTeams = /* GraphQL */ `\n  query ListTeams(\n    $filter: ModelTeamFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listTeams(filter: $filter, limit: $limit, nextToken: $nextToken) {\n      items {\n        id\n        name\n        TenantID\n        Members\n        Config\n        createdAt\n        updatedAt\n      }\n      nextToken\n    }\n  }\n`;\nexport const getUserProfile = /* GraphQL */ `\n  query GetUserProfile($id: ID!) {\n    getUserProfile(id: $id) {\n      id\n      name\n      createdAt\n      updatedAt\n      email\n      boardConfig\n      avatar\n      personalConfig\n      emailOptIn\n      paidPlan\n      validTeacher\n      adminOfTenant\n      TenantID\n      FEMStatus\n      lastVisitedSubs\n      MemberOfTeam\n      TutorGroupID\n    }\n  }\n`;\nexport const listUserProfiles = /* GraphQL */ `\n  query ListUserProfiles(\n    $filter: ModelUserProfileFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listUserProfiles(filter: $filter, limit: $limit, nextToken: $nextToken) {\n      items {\n        id\n        name\n        createdAt\n        updatedAt\n        email\n        boardConfig\n        avatar\n        personalConfig\n        emailOptIn\n        paidPlan\n        validTeacher\n        adminOfTenant\n        TenantID\n        FEMStatus\n        lastVisitedSubs\n        MemberOfTeam\n        TutorGroupID\n      }\n      nextToken\n    }\n  }\n`;\nexport const getTutorGroup = /* GraphQL */ `\n  query GetTutorGroup($id: ID!) {\n    getTutorGroup(id: $id) {\n      id\n      name\n      createdAt\n      updatedAt\n      config\n      roster\n      creator\n      TenantID\n      tutorClasses {\n        items {\n          id\n          name\n          description\n          videoMode\n          createdAt\n          updatedAt\n          config\n          roster\n          TutorGroupID\n          Sessions\n        }\n        nextToken\n      }\n    }\n  }\n`;\nexport const listTutorGroups = /* GraphQL */ `\n  query ListTutorGroups(\n    $filter: ModelTutorGroupFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listTutorGroups(filter: $filter, limit: $limit, nextToken: $nextToken) {\n      items {\n        id\n        name\n        createdAt\n        updatedAt\n        config\n        roster\n        creator\n        TenantID\n        tutorClasses {\n          nextToken\n        }\n      }\n      nextToken\n    }\n  }\n`;\nexport const getTutorClass = /* GraphQL */ `\n  query GetTutorClass($id: ID!) {\n    getTutorClass(id: $id) {\n      id\n      name\n      description\n      videoMode\n      createdAt\n      updatedAt\n      config\n      roster\n      TutorGroupID\n      TutorGroup {\n        id\n        name\n        createdAt\n        updatedAt\n        config\n        roster\n        creator\n        TenantID\n        tutorClasses {\n          nextToken\n        }\n      }\n      Sessions\n      TutorClassEvents {\n        items {\n          id\n          createdAt\n          updatedAt\n          config\n          type\n          TutorGroupID\n          TutorClassID\n        }\n        nextToken\n      }\n    }\n  }\n`;\nexport const listTutorClasss = /* GraphQL */ `\n  query ListTutorClasss(\n    $filter: ModelTutorClassFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listTutorClasss(filter: $filter, limit: $limit, nextToken: $nextToken) {\n      items {\n        id\n        name\n        description\n        videoMode\n        createdAt\n        updatedAt\n        config\n        roster\n        TutorGroupID\n        TutorGroup {\n          id\n          name\n          createdAt\n          updatedAt\n          config\n          roster\n          creator\n          TenantID\n        }\n        Sessions\n        TutorClassEvents {\n          nextToken\n        }\n      }\n      nextToken\n    }\n  }\n`;\nexport const getTutorClassEvent = /* GraphQL */ `\n  query GetTutorClassEvent($id: ID!) {\n    getTutorClassEvent(id: $id) {\n      id\n      createdAt\n      updatedAt\n      config\n      type\n      TutorGroupID\n      TutorGroup {\n        id\n        name\n        createdAt\n        updatedAt\n        config\n        roster\n        creator\n        TenantID\n        tutorClasses {\n          nextToken\n        }\n      }\n      TutorClassID\n      TutorClass {\n        id\n        name\n        description\n        videoMode\n        createdAt\n        updatedAt\n        config\n        roster\n        TutorGroupID\n        TutorGroup {\n          id\n          name\n          createdAt\n          updatedAt\n          config\n          roster\n          creator\n          TenantID\n        }\n        Sessions\n        TutorClassEvents {\n          nextToken\n        }\n      }\n    }\n  }\n`;\nexport const listTutorClassEvents = /* GraphQL */ `\n  query ListTutorClassEvents(\n    $filter: ModelTutorClassEventFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listTutorClassEvents(\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        createdAt\n        updatedAt\n        config\n        type\n        TutorGroupID\n        TutorGroup {\n          id\n          name\n          createdAt\n          updatedAt\n          config\n          roster\n          creator\n          TenantID\n        }\n        TutorClassID\n        TutorClass {\n          id\n          name\n          description\n          videoMode\n          createdAt\n          updatedAt\n          config\n          roster\n          TutorGroupID\n          Sessions\n        }\n      }\n      nextToken\n    }\n  }\n`;\nexport const getFrequentEngagementMin = /* GraphQL */ `\n  query GetFrequentEngagementMin($id: ID!) {\n    getFrequentEngagementMin(id: $id) {\n      id\n      name\n      AvatarName\n      Public\n      Minutes\n      Rating\n      Ranking\n      Content\n      TierQualifingPoints\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const listFrequentEngagementMins = /* GraphQL */ `\n  query ListFrequentEngagementMins(\n    $filter: ModelFrequentEngagementMinFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listFrequentEngagementMins(\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        AvatarName\n        Public\n        Minutes\n        Rating\n        Ranking\n        Content\n        TierQualifingPoints\n        createdAt\n        updatedAt\n      }\n      nextToken\n    }\n  }\n`;\nexport const getApiInfo = /* GraphQL */ `\n  query GetApiInfo($id: ID!) {\n    getApiInfo(id: $id) {\n      id\n      key\n      content\n      count\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const listApiInfos = /* GraphQL */ `\n  query ListApiInfos(\n    $filter: ModelApiInfoFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listApiInfos(filter: $filter, limit: $limit, nextToken: $nextToken) {\n      items {\n        id\n        key\n        content\n        count\n        createdAt\n        updatedAt\n      }\n      nextToken\n    }\n  }\n`;\nexport const getPersonalPalette = /* GraphQL */ `\n  query GetPersonalPalette($id: ID!) {\n    getPersonalPalette(id: $id) {\n      id\n      createdAt\n      updatedAt\n      path\n      owner\n      name\n      content\n    }\n  }\n`;\nexport const listPersonalPalettes = /* GraphQL */ `\n  query ListPersonalPalettes(\n    $filter: ModelPersonalPaletteFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listPersonalPalettes(\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        createdAt\n        updatedAt\n        path\n        owner\n        name\n        content\n      }\n      nextToken\n    }\n  }\n`;\nexport const getCommunityPalette = /* GraphQL */ `\n  query GetCommunityPalette($id: ID!) {\n    getCommunityPalette(id: $id) {\n      id\n      createdAt\n      updatedAt\n      path\n      owner\n      name\n      content\n    }\n  }\n`;\nexport const listCommunityPalettes = /* GraphQL */ `\n  query ListCommunityPalettes(\n    $filter: ModelCommunityPaletteFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listCommunityPalettes(\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        createdAt\n        updatedAt\n        path\n        owner\n        name\n        content\n      }\n      nextToken\n    }\n  }\n`;\nexport const getUser = /* GraphQL */ `\n  query GetUser($id: ID!) {\n    getUser(id: $id) {\n      id\n      name\n      createdAt\n      updatedAt\n      SessionID\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      content\n      UserProfile\n      ttl\n      avatar\n    }\n  }\n`;\nexport const listUsers = /* GraphQL */ `\n  query ListUsers(\n    $filter: ModelUserFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listUsers(filter: $filter, limit: $limit, nextToken: $nextToken) {\n      items {\n        id\n        name\n        createdAt\n        updatedAt\n        SessionID\n        Session {\n          id\n          name\n          content\n          createdAt\n          updatedAt\n          ttl\n          savedOwner\n          parentID\n          pageNumber\n          boardConfig\n          parentBoardID\n          folderID\n          Classroom\n          CreatorLocalID\n          isGroup\n          joinCode\n          TenantID\n          deleted\n          TutorClass\n        }\n        content\n        UserProfile\n        ttl\n        avatar\n      }\n      nextToken\n    }\n  }\n`;\nexport const getErrorLog = /* GraphQL */ `\n  query GetErrorLog($id: ID!) {\n    getErrorLog(id: $id) {\n      id\n      name\n      createdAt\n      updatedAt\n      content\n      ttl\n    }\n  }\n`;\nexport const listErrorLogs = /* GraphQL */ `\n  query ListErrorLogs(\n    $filter: ModelErrorLogFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listErrorLogs(filter: $filter, limit: $limit, nextToken: $nextToken) {\n      items {\n        id\n        name\n        createdAt\n        updatedAt\n        content\n        ttl\n      }\n      nextToken\n    }\n  }\n`;\nexport const getFolder = /* GraphQL */ `\n  query GetFolder($id: ID!) {\n    getFolder(id: $id) {\n      id\n      name\n      createdAt\n      updatedAt\n      userProfileId\n      user {\n        id\n        name\n        createdAt\n        updatedAt\n        email\n        boardConfig\n        avatar\n        personalConfig\n        emailOptIn\n        paidPlan\n        validTeacher\n        adminOfTenant\n        TenantID\n        FEMStatus\n        lastVisitedSubs\n        MemberOfTeam\n        TutorGroupID\n      }\n      parentFolderPath\n    }\n  }\n`;\nexport const listFolders = /* GraphQL */ `\n  query ListFolders(\n    $filter: ModelFolderFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listFolders(filter: $filter, limit: $limit, nextToken: $nextToken) {\n      items {\n        id\n        name\n        createdAt\n        updatedAt\n        userProfileId\n        user {\n          id\n          name\n          createdAt\n          updatedAt\n          email\n          boardConfig\n          avatar\n          personalConfig\n          emailOptIn\n          paidPlan\n          validTeacher\n          adminOfTenant\n          TenantID\n          FEMStatus\n          lastVisitedSubs\n          MemberOfTeam\n          TutorGroupID\n        }\n        parentFolderPath\n      }\n      nextToken\n    }\n  }\n`;\nexport const getServiceNotice = /* GraphQL */ `\n  query GetServiceNotice($id: ID!) {\n    getServiceNotice(id: $id) {\n      id\n      createdAt\n      updatedAt\n      noticeConfig\n    }\n  }\n`;\nexport const listServiceNotices = /* GraphQL */ `\n  query ListServiceNotices(\n    $filter: ModelServiceNoticeFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listServiceNotices(filter: $filter, limit: $limit, nextToken: $nextToken) {\n      items {\n        id\n        createdAt\n        updatedAt\n        noticeConfig\n      }\n      nextToken\n    }\n  }\n`;\nexport const getLatencyEndPoints = /* GraphQL */ `\n  query GetLatencyEndPoints($id: ID!) {\n    getLatencyEndPoints(id: $id) {\n      id\n      createdAt\n      updatedAt\n      region\n      content\n    }\n  }\n`;\nexport const listLatencyEndPointss = /* GraphQL */ `\n  query ListLatencyEndPointss(\n    $filter: ModelLatencyEndPointsFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listLatencyEndPointss(\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        createdAt\n        updatedAt\n        region\n        content\n      }\n      nextToken\n    }\n  }\n`;\nexport const getRemoteControl = /* GraphQL */ `\n  query GetRemoteControl($id: ID!) {\n    getRemoteControl(id: $id) {\n      id\n      parentID\n      ttl\n      createdAt\n      updatedAt\n      content\n    }\n  }\n`;\nexport const listRemoteControls = /* GraphQL */ `\n  query ListRemoteControls(\n    $filter: ModelRemoteControlFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listRemoteControls(filter: $filter, limit: $limit, nextToken: $nextToken) {\n      items {\n        id\n        parentID\n        ttl\n        createdAt\n        updatedAt\n        content\n      }\n      nextToken\n    }\n  }\n`;\nexport const getLatencyCalculation = /* GraphQL */ `\n  query GetLatencyCalculation($id: ID!) {\n    getLatencyCalculation(id: $id) {\n      id\n      createdAt\n      updatedAt\n      region\n      clientRegion\n      content\n    }\n  }\n`;\nexport const listLatencyCalculations = /* GraphQL */ `\n  query ListLatencyCalculations(\n    $filter: ModelLatencyCalculationFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listLatencyCalculations(\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        createdAt\n        updatedAt\n        region\n        clientRegion\n        content\n      }\n      nextToken\n    }\n  }\n`;\nexport const getTenant = /* GraphQL */ `\n  query GetTenant($id: ID!) {\n    getTenant(id: $id) {\n      id\n      name\n      domainName\n      createdAt\n      updatedAt\n      entitlements\n      adminUsers\n      tenantConfig\n      secondaryDomainConfig\n      licensedUsers {\n        items {\n          id\n          name\n          createdAt\n          updatedAt\n          email\n          boardConfig\n          avatar\n          personalConfig\n          emailOptIn\n          paidPlan\n          validTeacher\n          adminOfTenant\n          TenantID\n          FEMStatus\n          lastVisitedSubs\n          MemberOfTeam\n          TutorGroupID\n        }\n        nextToken\n      }\n    }\n  }\n`;\nexport const listTenants = /* GraphQL */ `\n  query ListTenants(\n    $filter: ModelTenantFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listTenants(filter: $filter, limit: $limit, nextToken: $nextToken) {\n      items {\n        id\n        name\n        domainName\n        createdAt\n        updatedAt\n        entitlements\n        adminUsers\n        tenantConfig\n        secondaryDomainConfig\n        licensedUsers {\n          nextToken\n        }\n      }\n      nextToken\n    }\n  }\n`;\nexport const getVideoRoom = /* GraphQL */ `\n  query GetVideoRoom($id: ID!) {\n    getVideoRoom(id: $id) {\n      id\n      SID\n      name\n      createdAt\n      updatedAt\n      state\n      url\n      content\n      SessionID\n      recordingTurnedOn\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      ttl\n    }\n  }\n`;\nexport const listVideoRooms = /* GraphQL */ `\n  query ListVideoRooms(\n    $filter: ModelVideoRoomFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    listVideoRooms(filter: $filter, limit: $limit, nextToken: $nextToken) {\n      items {\n        id\n        SID\n        name\n        createdAt\n        updatedAt\n        state\n        url\n        content\n        SessionID\n        recordingTurnedOn\n        Session {\n          id\n          name\n          content\n          createdAt\n          updatedAt\n          ttl\n          savedOwner\n          parentID\n          pageNumber\n          boardConfig\n          parentBoardID\n          folderID\n          Classroom\n          CreatorLocalID\n          isGroup\n          joinCode\n          TenantID\n          deleted\n          TutorClass\n        }\n        ttl\n      }\n      nextToken\n    }\n  }\n`;\nexport const queryBySavedOwner = /* GraphQL */ `\n  query QueryBySavedOwner(\n    $savedOwner: ID\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelSessionFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    queryBySavedOwner(\n      savedOwner: $savedOwner\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      nextToken\n    }\n  }\n`;\nexport const queryByParent = /* GraphQL */ `\n  query QueryByParent(\n    $parentID: ID\n    $pageNumber: ModelIntKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelSessionFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    queryByParent(\n      parentID: $parentID\n      pageNumber: $pageNumber\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      nextToken\n    }\n  }\n`;\nexport const queryByparentBoardID = /* GraphQL */ `\n  query QueryByparentBoardID(\n    $parentBoardID: ID\n    $createdAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelSessionFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    queryByparentBoardID(\n      parentBoardID: $parentBoardID\n      createdAt: $createdAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      nextToken\n    }\n  }\n`;\nexport const queryByClassroom = /* GraphQL */ `\n  query QueryByClassroom(\n    $Classroom: ID\n    $createdAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelSessionFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    queryByClassroom(\n      Classroom: $Classroom\n      createdAt: $createdAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      nextToken\n    }\n  }\n`;\nexport const queryByCreatorLocalId = /* GraphQL */ `\n  query QueryByCreatorLocalId(\n    $CreatorLocalID: ID\n    $createdAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelSessionFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    queryByCreatorLocalId(\n      CreatorLocalID: $CreatorLocalID\n      createdAt: $createdAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      nextToken\n    }\n  }\n`;\nexport const queryByJoinCode = /* GraphQL */ `\n  query QueryByJoinCode(\n    $joinCode: ID\n    $createdAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelSessionFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    queryByJoinCode(\n      joinCode: $joinCode\n      createdAt: $createdAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      nextToken\n    }\n  }\n`;\nexport const queryByFolder = /* GraphQL */ `\n  query QueryByFolder(\n    $folderID: ID\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelSessionFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    queryByFolder(\n      folderID: $folderID\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      nextToken\n    }\n  }\n`;\nexport const querybycreator = /* GraphQL */ `\n  query Querybycreator(\n    $CreatorLocalID: ID\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelCommunityBoardFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    querybycreator(\n      CreatorLocalID: $CreatorLocalID\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        description\n        creator\n        creatorEmail\n        CreatorLocalID\n        Country\n        Grade\n        Subject\n        boardLink\n        content\n        createdAt\n        updatedAt\n        title\n        deleted\n      }\n      nextToken\n    }\n  }\n`;\nexport const queryByGrade = /* GraphQL */ `\n  query QueryByGrade(\n    $Grade: String\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelCommunityBoardFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    queryByGrade(\n      Grade: $Grade\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        description\n        creator\n        creatorEmail\n        CreatorLocalID\n        Country\n        Grade\n        Subject\n        boardLink\n        content\n        createdAt\n        updatedAt\n        title\n        deleted\n      }\n      nextToken\n    }\n  }\n`;\nexport const queryByTeacher = /* GraphQL */ `\n  query QueryByTeacher(\n    $TeacherID: ID\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelClassroomFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    queryByTeacher(\n      TeacherID: $TeacherID\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        TeacherID\n        content\n        Teacher {\n          id\n          name\n          createdAt\n          updatedAt\n          email\n          boardConfig\n          avatar\n          personalConfig\n          emailOptIn\n          paidPlan\n          validTeacher\n          adminOfTenant\n          TenantID\n          FEMStatus\n          lastVisitedSubs\n          MemberOfTeam\n          TutorGroupID\n        }\n        Users {\n          nextToken\n        }\n        ttl\n        createdAt\n        updatedAt\n        TeacherList\n      }\n      nextToken\n    }\n  }\n`;\nexport const queryGamePlayBySession = /* GraphQL */ `\n  query QueryGamePlayBySession(\n    $Session: ID\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelGamePlayFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    queryGamePlayBySession(\n      Session: $Session\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        Session\n        type\n        content\n        createdAt\n        updatedAt\n        version\n        ttl\n      }\n      nextToken\n    }\n  }\n`;\nexport const queryByGroupsClassroom = /* GraphQL */ `\n  query QueryByGroupsClassroom(\n    $Classroom: ID\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelClassGroupFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    queryByGroupsClassroom(\n      Classroom: $Classroom\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        createdAt\n        updatedAt\n        ttl\n        name\n        content\n        Classroom\n        SessionID\n        deleted\n      }\n      nextToken\n    }\n  }\n`;\nexport const queryByEventsClassroom = /* GraphQL */ `\n  query QueryByEventsClassroom(\n    $Classroom: ID\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelClassroomEventFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    queryByEventsClassroom(\n      Classroom: $Classroom\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        createdAt\n        updatedAt\n        ttl\n        type\n        event\n        For\n        State\n        Content\n        Classroom\n        deleted\n      }\n      nextToken\n    }\n  }\n`;\nexport const querybyEngagementClass = /* GraphQL */ `\n  query QuerybyEngagementClass(\n    $Classroom: ID\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelEngagementEventFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    querybyEngagementClass(\n      Classroom: $Classroom\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        createdAt\n        updatedAt\n        luid\n        name\n        time\n        ttl\n        Content\n        Classroom\n      }\n      nextToken\n    }\n  }\n`;\nexport const queryLocalUserByClass = /* GraphQL */ `\n  query QueryLocalUserByClass(\n    $ClassroomID: ID\n    $createdAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelLocalUsersFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    queryLocalUserByClass(\n      ClassroomID: $ClassroomID\n      createdAt: $createdAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        content\n        createdAt\n        updatedAt\n        CurrentSession {\n          id\n          name\n          content\n          createdAt\n          updatedAt\n          ttl\n          savedOwner\n          parentID\n          pageNumber\n          boardConfig\n          parentBoardID\n          folderID\n          Classroom\n          CreatorLocalID\n          isGroup\n          joinCode\n          TenantID\n          deleted\n          TutorClass\n        }\n        CurrentSessionId\n        CurrentUserId\n        CurrentUser {\n          id\n          name\n          createdAt\n          updatedAt\n          SessionID\n          content\n          UserProfile\n          ttl\n          avatar\n        }\n        ClassroomID\n        ttl\n        deleted\n      }\n      nextToken\n    }\n  }\n`;\nexport const queryByParentID = /* GraphQL */ `\n  query QueryByParentID(\n    $parentBoardID: ID\n    $sortDirection: ModelSortDirection\n    $filter: ModelMultiBoardFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    queryByParentID(\n      parentBoardID: $parentBoardID\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        parentBoardID\n        parentBoard {\n          id\n          name\n          content\n          createdAt\n          updatedAt\n          ttl\n          savedOwner\n          parentID\n          pageNumber\n          boardConfig\n          parentBoardID\n          folderID\n          Classroom\n          CreatorLocalID\n          isGroup\n          joinCode\n          TenantID\n          deleted\n          TutorClass\n        }\n        childBoardID\n        childBoard {\n          id\n          name\n          content\n          createdAt\n          updatedAt\n          ttl\n          savedOwner\n          parentID\n          pageNumber\n          boardConfig\n          parentBoardID\n          folderID\n          Classroom\n          CreatorLocalID\n          isGroup\n          joinCode\n          TenantID\n          deleted\n          TutorClass\n        }\n        ttl\n        createdAt\n        updatedAt\n      }\n      nextToken\n    }\n  }\n`;\nexport const sessionSorted = /* GraphQL */ `\n  query SessionSorted(\n    $SessionID: ID\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelObjectFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    sessionSorted(\n      SessionID: $SessionID\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        content\n        type\n        objType\n        ended\n        createdAt\n        updatedAt\n        SessionID\n        ttl\n        animate\n        CreatedBy\n        CreatorLocalID\n        DisableSync\n        Session {\n          id\n          name\n          content\n          createdAt\n          updatedAt\n          ttl\n          savedOwner\n          parentID\n          pageNumber\n          boardConfig\n          parentBoardID\n          folderID\n          Classroom\n          CreatorLocalID\n          isGroup\n          joinCode\n          TenantID\n          deleted\n          TutorClass\n        }\n        deleted\n      }\n      nextToken\n    }\n  }\n`;\nexport const byTeamTenant = /* GraphQL */ `\n  query ByTeamTenant(\n    $TenantID: ID\n    $sortDirection: ModelSortDirection\n    $filter: ModelTeamFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    byTeamTenant(\n      TenantID: $TenantID\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        TenantID\n        Members\n        Config\n        createdAt\n        updatedAt\n      }\n      nextToken\n    }\n  }\n`;\nexport const UPByTenant = /* GraphQL */ `\n  query UPByTenant(\n    $TenantID: ID\n    $sortDirection: ModelSortDirection\n    $filter: ModelUserProfileFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    UPByTenant(\n      TenantID: $TenantID\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        createdAt\n        updatedAt\n        email\n        boardConfig\n        avatar\n        personalConfig\n        emailOptIn\n        paidPlan\n        validTeacher\n        adminOfTenant\n        TenantID\n        FEMStatus\n        lastVisitedSubs\n        MemberOfTeam\n        TutorGroupID\n      }\n      nextToken\n    }\n  }\n`;\nexport const byEmamilUP = /* GraphQL */ `\n  query ByEmamilUP(\n    $email: String\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelUserProfileFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    byEmamilUP(\n      email: $email\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        createdAt\n        updatedAt\n        email\n        boardConfig\n        avatar\n        personalConfig\n        emailOptIn\n        paidPlan\n        validTeacher\n        adminOfTenant\n        TenantID\n        FEMStatus\n        lastVisitedSubs\n        MemberOfTeam\n        TutorGroupID\n      }\n      nextToken\n    }\n  }\n`;\nexport const queryClassByTutorGroup = /* GraphQL */ `\n  query QueryClassByTutorGroup(\n    $TutorGroupID: ID\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelTutorClassFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    queryClassByTutorGroup(\n      TutorGroupID: $TutorGroupID\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        description\n        videoMode\n        createdAt\n        updatedAt\n        config\n        roster\n        TutorGroupID\n        TutorGroup {\n          id\n          name\n          createdAt\n          updatedAt\n          config\n          roster\n          creator\n          TenantID\n        }\n        Sessions\n        TutorClassEvents {\n          nextToken\n        }\n      }\n      nextToken\n    }\n  }\n`;\nexport const eventByTutorClass = /* GraphQL */ `\n  query EventByTutorClass(\n    $TutorClassID: ID\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelTutorClassEventFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    eventByTutorClass(\n      TutorClassID: $TutorClassID\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        createdAt\n        updatedAt\n        config\n        type\n        TutorGroupID\n        TutorGroup {\n          id\n          name\n          createdAt\n          updatedAt\n          config\n          roster\n          creator\n          TenantID\n        }\n        TutorClassID\n        TutorClass {\n          id\n          name\n          description\n          videoMode\n          createdAt\n          updatedAt\n          config\n          roster\n          TutorGroupID\n          Sessions\n        }\n      }\n      nextToken\n    }\n  }\n`;\nexport const byAvatar = /* GraphQL */ `\n  query ByAvatar(\n    $AvatarName: String\n    $Minutes: ModelIntKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelFrequentEngagementMinFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    byAvatar(\n      AvatarName: $AvatarName\n      Minutes: $Minutes\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        AvatarName\n        Public\n        Minutes\n        Rating\n        Ranking\n        Content\n        TierQualifingPoints\n        createdAt\n        updatedAt\n      }\n      nextToken\n    }\n  }\n`;\nexport const ByFEMRanking = /* GraphQL */ `\n  query ByFEMRanking(\n    $Ranking: Int\n    $Minutes: ModelIntKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelFrequentEngagementMinFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    ByFEMRanking(\n      Ranking: $Ranking\n      Minutes: $Minutes\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        AvatarName\n        Public\n        Minutes\n        Rating\n        Ranking\n        Content\n        TierQualifingPoints\n        createdAt\n        updatedAt\n      }\n      nextToken\n    }\n  }\n`;\nexport const byApiKey = /* GraphQL */ `\n  query ByApiKey(\n    $key: ID\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelApiInfoFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    byApiKey(\n      key: $key\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        key\n        content\n        count\n        createdAt\n        updatedAt\n      }\n      nextToken\n    }\n  }\n`;\nexport const byPOwnerSorted = /* GraphQL */ `\n  query ByPOwnerSorted(\n    $owner: ID\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelPersonalPaletteFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    byPOwnerSorted(\n      owner: $owner\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        createdAt\n        updatedAt\n        path\n        owner\n        name\n        content\n      }\n      nextToken\n    }\n  }\n`;\nexport const byCOwnerSorted = /* GraphQL */ `\n  query ByCOwnerSorted(\n    $owner: ID\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelCommunityPaletteFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    byCOwnerSorted(\n      owner: $owner\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        createdAt\n        updatedAt\n        path\n        owner\n        name\n        content\n      }\n      nextToken\n    }\n  }\n`;\nexport const byUsersSessionSorted = /* GraphQL */ `\n  query ByUsersSessionSorted(\n    $SessionID: ID\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelUserFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    byUsersSessionSorted(\n      SessionID: $SessionID\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        createdAt\n        updatedAt\n        SessionID\n        Session {\n          id\n          name\n          content\n          createdAt\n          updatedAt\n          ttl\n          savedOwner\n          parentID\n          pageNumber\n          boardConfig\n          parentBoardID\n          folderID\n          Classroom\n          CreatorLocalID\n          isGroup\n          joinCode\n          TenantID\n          deleted\n          TutorClass\n        }\n        content\n        UserProfile\n        ttl\n        avatar\n      }\n      nextToken\n    }\n  }\n`;\nexport const byProfileSorted = /* GraphQL */ `\n  query ByProfileSorted(\n    $UserProfile: ID\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelUserFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    byProfileSorted(\n      UserProfile: $UserProfile\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        createdAt\n        updatedAt\n        SessionID\n        Session {\n          id\n          name\n          content\n          createdAt\n          updatedAt\n          ttl\n          savedOwner\n          parentID\n          pageNumber\n          boardConfig\n          parentBoardID\n          folderID\n          Classroom\n          CreatorLocalID\n          isGroup\n          joinCode\n          TenantID\n          deleted\n          TutorClass\n        }\n        content\n        UserProfile\n        ttl\n        avatar\n      }\n      nextToken\n    }\n  }\n`;\nexport const foldersByOwner = /* GraphQL */ `\n  query FoldersByOwner(\n    $userProfileId: ID\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelFolderFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    foldersByOwner(\n      userProfileId: $userProfileId\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        createdAt\n        updatedAt\n        userProfileId\n        user {\n          id\n          name\n          createdAt\n          updatedAt\n          email\n          boardConfig\n          avatar\n          personalConfig\n          emailOptIn\n          paidPlan\n          validTeacher\n          adminOfTenant\n          TenantID\n          FEMStatus\n          lastVisitedSubs\n          MemberOfTeam\n          TutorGroupID\n        }\n        parentFolderPath\n      }\n      nextToken\n    }\n  }\n`;\nexport const LEbyRegion = /* GraphQL */ `\n  query LEbyRegion(\n    $region: String\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelLatencyEndPointsFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    LEbyRegion(\n      region: $region\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        createdAt\n        updatedAt\n        region\n        content\n      }\n      nextToken\n    }\n  }\n`;\nexport const byParentID = /* GraphQL */ `\n  query ByParentID(\n    $parentID: ID\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelRemoteControlFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    byParentID(\n      parentID: $parentID\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        parentID\n        ttl\n        createdAt\n        updatedAt\n        content\n      }\n      nextToken\n    }\n  }\n`;\nexport const queryByTenantName = /* GraphQL */ `\n  query QueryByTenantName(\n    $name: String\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelTenantFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    queryByTenantName(\n      name: $name\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        domainName\n        createdAt\n        updatedAt\n        entitlements\n        adminUsers\n        tenantConfig\n        secondaryDomainConfig\n        licensedUsers {\n          nextToken\n        }\n      }\n      nextToken\n    }\n  }\n`;\nexport const queryByDomainName = /* GraphQL */ `\n  query QueryByDomainName(\n    $domainName: String\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelTenantFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    queryByDomainName(\n      domainName: $domainName\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        domainName\n        createdAt\n        updatedAt\n        entitlements\n        adminUsers\n        tenantConfig\n        secondaryDomainConfig\n        licensedUsers {\n          nextToken\n        }\n      }\n      nextToken\n    }\n  }\n`;\nexport const videoRoomBySession = /* GraphQL */ `\n  query VideoRoomBySession(\n    $SessionID: ID\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelVideoRoomFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    videoRoomBySession(\n      SessionID: $SessionID\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        SID\n        name\n        createdAt\n        updatedAt\n        state\n        url\n        content\n        SessionID\n        recordingTurnedOn\n        Session {\n          id\n          name\n          content\n          createdAt\n          updatedAt\n          ttl\n          savedOwner\n          parentID\n          pageNumber\n          boardConfig\n          parentBoardID\n          folderID\n          Classroom\n          CreatorLocalID\n          isGroup\n          joinCode\n          TenantID\n          deleted\n          TutorClass\n        }\n        ttl\n      }\n      nextToken\n    }\n  }\n`;\nexport const videoRoomBySID = /* GraphQL */ `\n  query VideoRoomBySID(\n    $SID: String\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelVideoRoomFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    videoRoomBySID(\n      SID: $SID\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        SID\n        name\n        createdAt\n        updatedAt\n        state\n        url\n        content\n        SessionID\n        recordingTurnedOn\n        Session {\n          id\n          name\n          content\n          createdAt\n          updatedAt\n          ttl\n          savedOwner\n          parentID\n          pageNumber\n          boardConfig\n          parentBoardID\n          folderID\n          Classroom\n          CreatorLocalID\n          isGroup\n          joinCode\n          TenantID\n          deleted\n          TutorClass\n        }\n        ttl\n      }\n      nextToken\n    }\n  }\n`;\n","/* eslint-disable */\n// this is an auto generated file. This will be overwritten\n\nexport const createSession = /* GraphQL */ `\n  mutation CreateSession(\n    $input: CreateSessionInput!\n    $condition: ModelSessionConditionInput\n  ) {\n    createSession(input: $input, condition: $condition) {\n      id\n      name\n      content\n      createdAt\n      updatedAt\n      Objects {\n        items {\n          id\n          name\n          content\n          type\n          objType\n          ended\n          createdAt\n          updatedAt\n          SessionID\n          ttl\n          animate\n          CreatedBy\n          CreatorLocalID\n          DisableSync\n          deleted\n        }\n        nextToken\n      }\n      ttl\n      savedOwner\n      parentID\n      pageNumber\n      boardConfig\n      Users {\n        items {\n          id\n          name\n          createdAt\n          updatedAt\n          SessionID\n          content\n          UserProfile\n          ttl\n          avatar\n        }\n        nextToken\n      }\n      parentBoardID\n      folderID\n      Classroom\n      CreatorLocalID\n      MultiBoard {\n        items {\n          id\n          parentBoardID\n          childBoardID\n          ttl\n          createdAt\n          updatedAt\n        }\n        nextToken\n      }\n      isGroup\n      joinCode\n      TenantID\n      deleted\n      TutorClass\n    }\n  }\n`;\nexport const updateSession = /* GraphQL */ `\n  mutation UpdateSession(\n    $input: UpdateSessionInput!\n    $condition: ModelSessionConditionInput\n  ) {\n    updateSession(input: $input, condition: $condition) {\n      id\n      name\n      content\n      createdAt\n      updatedAt\n      Objects {\n        items {\n          id\n          name\n          content\n          type\n          objType\n          ended\n          createdAt\n          updatedAt\n          SessionID\n          ttl\n          animate\n          CreatedBy\n          CreatorLocalID\n          DisableSync\n          deleted\n        }\n        nextToken\n      }\n      ttl\n      savedOwner\n      parentID\n      pageNumber\n      boardConfig\n      Users {\n        items {\n          id\n          name\n          createdAt\n          updatedAt\n          SessionID\n          content\n          UserProfile\n          ttl\n          avatar\n        }\n        nextToken\n      }\n      parentBoardID\n      folderID\n      Classroom\n      CreatorLocalID\n      MultiBoard {\n        items {\n          id\n          parentBoardID\n          childBoardID\n          ttl\n          createdAt\n          updatedAt\n        }\n        nextToken\n      }\n      isGroup\n      joinCode\n      TenantID\n      deleted\n      TutorClass\n    }\n  }\n`;\nexport const deleteSession = /* GraphQL */ `\n  mutation DeleteSession(\n    $input: DeleteSessionInput!\n    $condition: ModelSessionConditionInput\n  ) {\n    deleteSession(input: $input, condition: $condition) {\n      id\n      name\n      content\n      createdAt\n      updatedAt\n      Objects {\n        items {\n          id\n          name\n          content\n          type\n          objType\n          ended\n          createdAt\n          updatedAt\n          SessionID\n          ttl\n          animate\n          CreatedBy\n          CreatorLocalID\n          DisableSync\n          deleted\n        }\n        nextToken\n      }\n      ttl\n      savedOwner\n      parentID\n      pageNumber\n      boardConfig\n      Users {\n        items {\n          id\n          name\n          createdAt\n          updatedAt\n          SessionID\n          content\n          UserProfile\n          ttl\n          avatar\n        }\n        nextToken\n      }\n      parentBoardID\n      folderID\n      Classroom\n      CreatorLocalID\n      MultiBoard {\n        items {\n          id\n          parentBoardID\n          childBoardID\n          ttl\n          createdAt\n          updatedAt\n        }\n        nextToken\n      }\n      isGroup\n      joinCode\n      TenantID\n      deleted\n      TutorClass\n    }\n  }\n`;\nexport const createCommunityBoard = /* GraphQL */ `\n  mutation CreateCommunityBoard(\n    $input: CreateCommunityBoardInput!\n    $condition: ModelCommunityBoardConditionInput\n  ) {\n    createCommunityBoard(input: $input, condition: $condition) {\n      id\n      name\n      description\n      creator\n      creatorEmail\n      CreatorLocalID\n      Country\n      Grade\n      Subject\n      boardLink\n      content\n      createdAt\n      updatedAt\n      title\n      deleted\n    }\n  }\n`;\nexport const updateCommunityBoard = /* GraphQL */ `\n  mutation UpdateCommunityBoard(\n    $input: UpdateCommunityBoardInput!\n    $condition: ModelCommunityBoardConditionInput\n  ) {\n    updateCommunityBoard(input: $input, condition: $condition) {\n      id\n      name\n      description\n      creator\n      creatorEmail\n      CreatorLocalID\n      Country\n      Grade\n      Subject\n      boardLink\n      content\n      createdAt\n      updatedAt\n      title\n      deleted\n    }\n  }\n`;\nexport const deleteCommunityBoard = /* GraphQL */ `\n  mutation DeleteCommunityBoard(\n    $input: DeleteCommunityBoardInput!\n    $condition: ModelCommunityBoardConditionInput\n  ) {\n    deleteCommunityBoard(input: $input, condition: $condition) {\n      id\n      name\n      description\n      creator\n      creatorEmail\n      CreatorLocalID\n      Country\n      Grade\n      Subject\n      boardLink\n      content\n      createdAt\n      updatedAt\n      title\n      deleted\n    }\n  }\n`;\nexport const createClassroom = /* GraphQL */ `\n  mutation CreateClassroom(\n    $input: CreateClassroomInput!\n    $condition: ModelClassroomConditionInput\n  ) {\n    createClassroom(input: $input, condition: $condition) {\n      id\n      name\n      TeacherID\n      content\n      Teacher {\n        id\n        name\n        createdAt\n        updatedAt\n        email\n        boardConfig\n        avatar\n        personalConfig\n        emailOptIn\n        paidPlan\n        validTeacher\n        adminOfTenant\n        TenantID\n        FEMStatus\n        lastVisitedSubs\n        MemberOfTeam\n        TutorGroupID\n      }\n      Users {\n        items {\n          id\n          content\n          createdAt\n          updatedAt\n          CurrentSessionId\n          CurrentUserId\n          ClassroomID\n          ttl\n          deleted\n        }\n        nextToken\n      }\n      ttl\n      createdAt\n      updatedAt\n      TeacherList\n    }\n  }\n`;\nexport const updateClassroom = /* GraphQL */ `\n  mutation UpdateClassroom(\n    $input: UpdateClassroomInput!\n    $condition: ModelClassroomConditionInput\n  ) {\n    updateClassroom(input: $input, condition: $condition) {\n      id\n      name\n      TeacherID\n      content\n      Teacher {\n        id\n        name\n        createdAt\n        updatedAt\n        email\n        boardConfig\n        avatar\n        personalConfig\n        emailOptIn\n        paidPlan\n        validTeacher\n        adminOfTenant\n        TenantID\n        FEMStatus\n        lastVisitedSubs\n        MemberOfTeam\n        TutorGroupID\n      }\n      Users {\n        items {\n          id\n          content\n          createdAt\n          updatedAt\n          CurrentSessionId\n          CurrentUserId\n          ClassroomID\n          ttl\n          deleted\n        }\n        nextToken\n      }\n      ttl\n      createdAt\n      updatedAt\n      TeacherList\n    }\n  }\n`;\nexport const deleteClassroom = /* GraphQL */ `\n  mutation DeleteClassroom(\n    $input: DeleteClassroomInput!\n    $condition: ModelClassroomConditionInput\n  ) {\n    deleteClassroom(input: $input, condition: $condition) {\n      id\n      name\n      TeacherID\n      content\n      Teacher {\n        id\n        name\n        createdAt\n        updatedAt\n        email\n        boardConfig\n        avatar\n        personalConfig\n        emailOptIn\n        paidPlan\n        validTeacher\n        adminOfTenant\n        TenantID\n        FEMStatus\n        lastVisitedSubs\n        MemberOfTeam\n        TutorGroupID\n      }\n      Users {\n        items {\n          id\n          content\n          createdAt\n          updatedAt\n          CurrentSessionId\n          CurrentUserId\n          ClassroomID\n          ttl\n          deleted\n        }\n        nextToken\n      }\n      ttl\n      createdAt\n      updatedAt\n      TeacherList\n    }\n  }\n`;\nexport const createGamePlay = /* GraphQL */ `\n  mutation CreateGamePlay(\n    $input: CreateGamePlayInput!\n    $condition: ModelGamePlayConditionInput\n  ) {\n    createGamePlay(input: $input, condition: $condition) {\n      id\n      Session\n      type\n      content\n      createdAt\n      updatedAt\n      version\n      ttl\n    }\n  }\n`;\nexport const updateGamePlay = /* GraphQL */ `\n  mutation UpdateGamePlay(\n    $input: UpdateGamePlayInput!\n    $condition: ModelGamePlayConditionInput\n  ) {\n    updateGamePlay(input: $input, condition: $condition) {\n      id\n      Session\n      type\n      content\n      createdAt\n      updatedAt\n      version\n      ttl\n    }\n  }\n`;\nexport const deleteGamePlay = /* GraphQL */ `\n  mutation DeleteGamePlay(\n    $input: DeleteGamePlayInput!\n    $condition: ModelGamePlayConditionInput\n  ) {\n    deleteGamePlay(input: $input, condition: $condition) {\n      id\n      Session\n      type\n      content\n      createdAt\n      updatedAt\n      version\n      ttl\n    }\n  }\n`;\nexport const createClassGroup = /* GraphQL */ `\n  mutation CreateClassGroup(\n    $input: CreateClassGroupInput!\n    $condition: ModelClassGroupConditionInput\n  ) {\n    createClassGroup(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      ttl\n      name\n      content\n      Classroom\n      SessionID\n      deleted\n    }\n  }\n`;\nexport const updateClassGroup = /* GraphQL */ `\n  mutation UpdateClassGroup(\n    $input: UpdateClassGroupInput!\n    $condition: ModelClassGroupConditionInput\n  ) {\n    updateClassGroup(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      ttl\n      name\n      content\n      Classroom\n      SessionID\n      deleted\n    }\n  }\n`;\nexport const deleteClassGroup = /* GraphQL */ `\n  mutation DeleteClassGroup(\n    $input: DeleteClassGroupInput!\n    $condition: ModelClassGroupConditionInput\n  ) {\n    deleteClassGroup(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      ttl\n      name\n      content\n      Classroom\n      SessionID\n      deleted\n    }\n  }\n`;\nexport const createClassroomEvent = /* GraphQL */ `\n  mutation CreateClassroomEvent(\n    $input: CreateClassroomEventInput!\n    $condition: ModelClassroomEventConditionInput\n  ) {\n    createClassroomEvent(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      ttl\n      type\n      event\n      For\n      State\n      Content\n      Classroom\n      deleted\n    }\n  }\n`;\nexport const updateClassroomEvent = /* GraphQL */ `\n  mutation UpdateClassroomEvent(\n    $input: UpdateClassroomEventInput!\n    $condition: ModelClassroomEventConditionInput\n  ) {\n    updateClassroomEvent(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      ttl\n      type\n      event\n      For\n      State\n      Content\n      Classroom\n      deleted\n    }\n  }\n`;\nexport const deleteClassroomEvent = /* GraphQL */ `\n  mutation DeleteClassroomEvent(\n    $input: DeleteClassroomEventInput!\n    $condition: ModelClassroomEventConditionInput\n  ) {\n    deleteClassroomEvent(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      ttl\n      type\n      event\n      For\n      State\n      Content\n      Classroom\n      deleted\n    }\n  }\n`;\nexport const createEngagementEvent = /* GraphQL */ `\n  mutation CreateEngagementEvent(\n    $input: CreateEngagementEventInput!\n    $condition: ModelEngagementEventConditionInput\n  ) {\n    createEngagementEvent(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      luid\n      name\n      time\n      ttl\n      Content\n      Classroom\n    }\n  }\n`;\nexport const updateEngagementEvent = /* GraphQL */ `\n  mutation UpdateEngagementEvent(\n    $input: UpdateEngagementEventInput!\n    $condition: ModelEngagementEventConditionInput\n  ) {\n    updateEngagementEvent(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      luid\n      name\n      time\n      ttl\n      Content\n      Classroom\n    }\n  }\n`;\nexport const deleteEngagementEvent = /* GraphQL */ `\n  mutation DeleteEngagementEvent(\n    $input: DeleteEngagementEventInput!\n    $condition: ModelEngagementEventConditionInput\n  ) {\n    deleteEngagementEvent(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      luid\n      name\n      time\n      ttl\n      Content\n      Classroom\n    }\n  }\n`;\nexport const createLocalUsers = /* GraphQL */ `\n  mutation CreateLocalUsers(\n    $input: CreateLocalUsersInput!\n    $condition: ModelLocalUsersConditionInput\n  ) {\n    createLocalUsers(input: $input, condition: $condition) {\n      id\n      content\n      createdAt\n      updatedAt\n      CurrentSession {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      CurrentSessionId\n      CurrentUserId\n      CurrentUser {\n        id\n        name\n        createdAt\n        updatedAt\n        SessionID\n        Session {\n          id\n          name\n          content\n          createdAt\n          updatedAt\n          ttl\n          savedOwner\n          parentID\n          pageNumber\n          boardConfig\n          parentBoardID\n          folderID\n          Classroom\n          CreatorLocalID\n          isGroup\n          joinCode\n          TenantID\n          deleted\n          TutorClass\n        }\n        content\n        UserProfile\n        ttl\n        avatar\n      }\n      ClassroomID\n      ttl\n      deleted\n    }\n  }\n`;\nexport const updateLocalUsers = /* GraphQL */ `\n  mutation UpdateLocalUsers(\n    $input: UpdateLocalUsersInput!\n    $condition: ModelLocalUsersConditionInput\n  ) {\n    updateLocalUsers(input: $input, condition: $condition) {\n      id\n      content\n      createdAt\n      updatedAt\n      CurrentSession {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      CurrentSessionId\n      CurrentUserId\n      CurrentUser {\n        id\n        name\n        createdAt\n        updatedAt\n        SessionID\n        Session {\n          id\n          name\n          content\n          createdAt\n          updatedAt\n          ttl\n          savedOwner\n          parentID\n          pageNumber\n          boardConfig\n          parentBoardID\n          folderID\n          Classroom\n          CreatorLocalID\n          isGroup\n          joinCode\n          TenantID\n          deleted\n          TutorClass\n        }\n        content\n        UserProfile\n        ttl\n        avatar\n      }\n      ClassroomID\n      ttl\n      deleted\n    }\n  }\n`;\nexport const deleteLocalUsers = /* GraphQL */ `\n  mutation DeleteLocalUsers(\n    $input: DeleteLocalUsersInput!\n    $condition: ModelLocalUsersConditionInput\n  ) {\n    deleteLocalUsers(input: $input, condition: $condition) {\n      id\n      content\n      createdAt\n      updatedAt\n      CurrentSession {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      CurrentSessionId\n      CurrentUserId\n      CurrentUser {\n        id\n        name\n        createdAt\n        updatedAt\n        SessionID\n        Session {\n          id\n          name\n          content\n          createdAt\n          updatedAt\n          ttl\n          savedOwner\n          parentID\n          pageNumber\n          boardConfig\n          parentBoardID\n          folderID\n          Classroom\n          CreatorLocalID\n          isGroup\n          joinCode\n          TenantID\n          deleted\n          TutorClass\n        }\n        content\n        UserProfile\n        ttl\n        avatar\n      }\n      ClassroomID\n      ttl\n      deleted\n    }\n  }\n`;\nexport const createMultiBoard = /* GraphQL */ `\n  mutation CreateMultiBoard(\n    $input: CreateMultiBoardInput!\n    $condition: ModelMultiBoardConditionInput\n  ) {\n    createMultiBoard(input: $input, condition: $condition) {\n      id\n      parentBoardID\n      parentBoard {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      childBoardID\n      childBoard {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      ttl\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const updateMultiBoard = /* GraphQL */ `\n  mutation UpdateMultiBoard(\n    $input: UpdateMultiBoardInput!\n    $condition: ModelMultiBoardConditionInput\n  ) {\n    updateMultiBoard(input: $input, condition: $condition) {\n      id\n      parentBoardID\n      parentBoard {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      childBoardID\n      childBoard {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      ttl\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const deleteMultiBoard = /* GraphQL */ `\n  mutation DeleteMultiBoard(\n    $input: DeleteMultiBoardInput!\n    $condition: ModelMultiBoardConditionInput\n  ) {\n    deleteMultiBoard(input: $input, condition: $condition) {\n      id\n      parentBoardID\n      parentBoard {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      childBoardID\n      childBoard {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      ttl\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const createObject = /* GraphQL */ `\n  mutation CreateObject(\n    $input: CreateObjectInput!\n    $condition: ModelObjectConditionInput\n  ) {\n    createObject(input: $input, condition: $condition) {\n      id\n      name\n      content\n      type\n      objType\n      ended\n      createdAt\n      updatedAt\n      SessionID\n      ttl\n      animate\n      CreatedBy\n      CreatorLocalID\n      DisableSync\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      deleted\n    }\n  }\n`;\nexport const updateObject = /* GraphQL */ `\n  mutation UpdateObject(\n    $input: UpdateObjectInput!\n    $condition: ModelObjectConditionInput\n  ) {\n    updateObject(input: $input, condition: $condition) {\n      id\n      name\n      content\n      type\n      objType\n      ended\n      createdAt\n      updatedAt\n      SessionID\n      ttl\n      animate\n      CreatedBy\n      CreatorLocalID\n      DisableSync\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      deleted\n    }\n  }\n`;\nexport const deleteObject = /* GraphQL */ `\n  mutation DeleteObject(\n    $input: DeleteObjectInput!\n    $condition: ModelObjectConditionInput\n  ) {\n    deleteObject(input: $input, condition: $condition) {\n      id\n      name\n      content\n      type\n      objType\n      ended\n      createdAt\n      updatedAt\n      SessionID\n      ttl\n      animate\n      CreatedBy\n      CreatorLocalID\n      DisableSync\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      deleted\n    }\n  }\n`;\nexport const createTeam = /* GraphQL */ `\n  mutation CreateTeam(\n    $input: CreateTeamInput!\n    $condition: ModelTeamConditionInput\n  ) {\n    createTeam(input: $input, condition: $condition) {\n      id\n      name\n      TenantID\n      Members\n      Config\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const updateTeam = /* GraphQL */ `\n  mutation UpdateTeam(\n    $input: UpdateTeamInput!\n    $condition: ModelTeamConditionInput\n  ) {\n    updateTeam(input: $input, condition: $condition) {\n      id\n      name\n      TenantID\n      Members\n      Config\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const deleteTeam = /* GraphQL */ `\n  mutation DeleteTeam(\n    $input: DeleteTeamInput!\n    $condition: ModelTeamConditionInput\n  ) {\n    deleteTeam(input: $input, condition: $condition) {\n      id\n      name\n      TenantID\n      Members\n      Config\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const createUserProfile = /* GraphQL */ `\n  mutation CreateUserProfile(\n    $input: CreateUserProfileInput!\n    $condition: ModelUserProfileConditionInput\n  ) {\n    createUserProfile(input: $input, condition: $condition) {\n      id\n      name\n      createdAt\n      updatedAt\n      email\n      boardConfig\n      avatar\n      personalConfig\n      emailOptIn\n      paidPlan\n      validTeacher\n      adminOfTenant\n      TenantID\n      FEMStatus\n      lastVisitedSubs\n      MemberOfTeam\n      TutorGroupID\n    }\n  }\n`;\nexport const updateUserProfile = /* GraphQL */ `\n  mutation UpdateUserProfile(\n    $input: UpdateUserProfileInput!\n    $condition: ModelUserProfileConditionInput\n  ) {\n    updateUserProfile(input: $input, condition: $condition) {\n      id\n      name\n      createdAt\n      updatedAt\n      email\n      boardConfig\n      avatar\n      personalConfig\n      emailOptIn\n      paidPlan\n      validTeacher\n      adminOfTenant\n      TenantID\n      FEMStatus\n      lastVisitedSubs\n      MemberOfTeam\n      TutorGroupID\n    }\n  }\n`;\nexport const deleteUserProfile = /* GraphQL */ `\n  mutation DeleteUserProfile(\n    $input: DeleteUserProfileInput!\n    $condition: ModelUserProfileConditionInput\n  ) {\n    deleteUserProfile(input: $input, condition: $condition) {\n      id\n      name\n      createdAt\n      updatedAt\n      email\n      boardConfig\n      avatar\n      personalConfig\n      emailOptIn\n      paidPlan\n      validTeacher\n      adminOfTenant\n      TenantID\n      FEMStatus\n      lastVisitedSubs\n      MemberOfTeam\n      TutorGroupID\n    }\n  }\n`;\nexport const createTutorGroup = /* GraphQL */ `\n  mutation CreateTutorGroup(\n    $input: CreateTutorGroupInput!\n    $condition: ModelTutorGroupConditionInput\n  ) {\n    createTutorGroup(input: $input, condition: $condition) {\n      id\n      name\n      createdAt\n      updatedAt\n      config\n      roster\n      creator\n      TenantID\n      tutorClasses {\n        items {\n          id\n          name\n          description\n          videoMode\n          createdAt\n          updatedAt\n          config\n          roster\n          TutorGroupID\n          Sessions\n        }\n        nextToken\n      }\n    }\n  }\n`;\nexport const updateTutorGroup = /* GraphQL */ `\n  mutation UpdateTutorGroup(\n    $input: UpdateTutorGroupInput!\n    $condition: ModelTutorGroupConditionInput\n  ) {\n    updateTutorGroup(input: $input, condition: $condition) {\n      id\n      name\n      createdAt\n      updatedAt\n      config\n      roster\n      creator\n      TenantID\n      tutorClasses {\n        items {\n          id\n          name\n          description\n          videoMode\n          createdAt\n          updatedAt\n          config\n          roster\n          TutorGroupID\n          Sessions\n        }\n        nextToken\n      }\n    }\n  }\n`;\nexport const deleteTutorGroup = /* GraphQL */ `\n  mutation DeleteTutorGroup(\n    $input: DeleteTutorGroupInput!\n    $condition: ModelTutorGroupConditionInput\n  ) {\n    deleteTutorGroup(input: $input, condition: $condition) {\n      id\n      name\n      createdAt\n      updatedAt\n      config\n      roster\n      creator\n      TenantID\n      tutorClasses {\n        items {\n          id\n          name\n          description\n          videoMode\n          createdAt\n          updatedAt\n          config\n          roster\n          TutorGroupID\n          Sessions\n        }\n        nextToken\n      }\n    }\n  }\n`;\nexport const createTutorClass = /* GraphQL */ `\n  mutation CreateTutorClass(\n    $input: CreateTutorClassInput!\n    $condition: ModelTutorClassConditionInput\n  ) {\n    createTutorClass(input: $input, condition: $condition) {\n      id\n      name\n      description\n      videoMode\n      createdAt\n      updatedAt\n      config\n      roster\n      TutorGroupID\n      TutorGroup {\n        id\n        name\n        createdAt\n        updatedAt\n        config\n        roster\n        creator\n        TenantID\n        tutorClasses {\n          nextToken\n        }\n      }\n      Sessions\n      TutorClassEvents {\n        items {\n          id\n          createdAt\n          updatedAt\n          config\n          type\n          TutorGroupID\n          TutorClassID\n        }\n        nextToken\n      }\n    }\n  }\n`;\nexport const updateTutorClass = /* GraphQL */ `\n  mutation UpdateTutorClass(\n    $input: UpdateTutorClassInput!\n    $condition: ModelTutorClassConditionInput\n  ) {\n    updateTutorClass(input: $input, condition: $condition) {\n      id\n      name\n      description\n      videoMode\n      createdAt\n      updatedAt\n      config\n      roster\n      TutorGroupID\n      TutorGroup {\n        id\n        name\n        createdAt\n        updatedAt\n        config\n        roster\n        creator\n        TenantID\n        tutorClasses {\n          nextToken\n        }\n      }\n      Sessions\n      TutorClassEvents {\n        items {\n          id\n          createdAt\n          updatedAt\n          config\n          type\n          TutorGroupID\n          TutorClassID\n        }\n        nextToken\n      }\n    }\n  }\n`;\nexport const deleteTutorClass = /* GraphQL */ `\n  mutation DeleteTutorClass(\n    $input: DeleteTutorClassInput!\n    $condition: ModelTutorClassConditionInput\n  ) {\n    deleteTutorClass(input: $input, condition: $condition) {\n      id\n      name\n      description\n      videoMode\n      createdAt\n      updatedAt\n      config\n      roster\n      TutorGroupID\n      TutorGroup {\n        id\n        name\n        createdAt\n        updatedAt\n        config\n        roster\n        creator\n        TenantID\n        tutorClasses {\n          nextToken\n        }\n      }\n      Sessions\n      TutorClassEvents {\n        items {\n          id\n          createdAt\n          updatedAt\n          config\n          type\n          TutorGroupID\n          TutorClassID\n        }\n        nextToken\n      }\n    }\n  }\n`;\nexport const createTutorClassEvent = /* GraphQL */ `\n  mutation CreateTutorClassEvent(\n    $input: CreateTutorClassEventInput!\n    $condition: ModelTutorClassEventConditionInput\n  ) {\n    createTutorClassEvent(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      config\n      type\n      TutorGroupID\n      TutorGroup {\n        id\n        name\n        createdAt\n        updatedAt\n        config\n        roster\n        creator\n        TenantID\n        tutorClasses {\n          nextToken\n        }\n      }\n      TutorClassID\n      TutorClass {\n        id\n        name\n        description\n        videoMode\n        createdAt\n        updatedAt\n        config\n        roster\n        TutorGroupID\n        TutorGroup {\n          id\n          name\n          createdAt\n          updatedAt\n          config\n          roster\n          creator\n          TenantID\n        }\n        Sessions\n        TutorClassEvents {\n          nextToken\n        }\n      }\n    }\n  }\n`;\nexport const updateTutorClassEvent = /* GraphQL */ `\n  mutation UpdateTutorClassEvent(\n    $input: UpdateTutorClassEventInput!\n    $condition: ModelTutorClassEventConditionInput\n  ) {\n    updateTutorClassEvent(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      config\n      type\n      TutorGroupID\n      TutorGroup {\n        id\n        name\n        createdAt\n        updatedAt\n        config\n        roster\n        creator\n        TenantID\n        tutorClasses {\n          nextToken\n        }\n      }\n      TutorClassID\n      TutorClass {\n        id\n        name\n        description\n        videoMode\n        createdAt\n        updatedAt\n        config\n        roster\n        TutorGroupID\n        TutorGroup {\n          id\n          name\n          createdAt\n          updatedAt\n          config\n          roster\n          creator\n          TenantID\n        }\n        Sessions\n        TutorClassEvents {\n          nextToken\n        }\n      }\n    }\n  }\n`;\nexport const deleteTutorClassEvent = /* GraphQL */ `\n  mutation DeleteTutorClassEvent(\n    $input: DeleteTutorClassEventInput!\n    $condition: ModelTutorClassEventConditionInput\n  ) {\n    deleteTutorClassEvent(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      config\n      type\n      TutorGroupID\n      TutorGroup {\n        id\n        name\n        createdAt\n        updatedAt\n        config\n        roster\n        creator\n        TenantID\n        tutorClasses {\n          nextToken\n        }\n      }\n      TutorClassID\n      TutorClass {\n        id\n        name\n        description\n        videoMode\n        createdAt\n        updatedAt\n        config\n        roster\n        TutorGroupID\n        TutorGroup {\n          id\n          name\n          createdAt\n          updatedAt\n          config\n          roster\n          creator\n          TenantID\n        }\n        Sessions\n        TutorClassEvents {\n          nextToken\n        }\n      }\n    }\n  }\n`;\nexport const createFrequentEngagementMin = /* GraphQL */ `\n  mutation CreateFrequentEngagementMin(\n    $input: CreateFrequentEngagementMinInput!\n    $condition: ModelFrequentEngagementMinConditionInput\n  ) {\n    createFrequentEngagementMin(input: $input, condition: $condition) {\n      id\n      name\n      AvatarName\n      Public\n      Minutes\n      Rating\n      Ranking\n      Content\n      TierQualifingPoints\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const updateFrequentEngagementMin = /* GraphQL */ `\n  mutation UpdateFrequentEngagementMin(\n    $input: UpdateFrequentEngagementMinInput!\n    $condition: ModelFrequentEngagementMinConditionInput\n  ) {\n    updateFrequentEngagementMin(input: $input, condition: $condition) {\n      id\n      name\n      AvatarName\n      Public\n      Minutes\n      Rating\n      Ranking\n      Content\n      TierQualifingPoints\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const deleteFrequentEngagementMin = /* GraphQL */ `\n  mutation DeleteFrequentEngagementMin(\n    $input: DeleteFrequentEngagementMinInput!\n    $condition: ModelFrequentEngagementMinConditionInput\n  ) {\n    deleteFrequentEngagementMin(input: $input, condition: $condition) {\n      id\n      name\n      AvatarName\n      Public\n      Minutes\n      Rating\n      Ranking\n      Content\n      TierQualifingPoints\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const createApiInfo = /* GraphQL */ `\n  mutation CreateApiInfo(\n    $input: CreateApiInfoInput!\n    $condition: ModelApiInfoConditionInput\n  ) {\n    createApiInfo(input: $input, condition: $condition) {\n      id\n      key\n      content\n      count\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const updateApiInfo = /* GraphQL */ `\n  mutation UpdateApiInfo(\n    $input: UpdateApiInfoInput!\n    $condition: ModelApiInfoConditionInput\n  ) {\n    updateApiInfo(input: $input, condition: $condition) {\n      id\n      key\n      content\n      count\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const deleteApiInfo = /* GraphQL */ `\n  mutation DeleteApiInfo(\n    $input: DeleteApiInfoInput!\n    $condition: ModelApiInfoConditionInput\n  ) {\n    deleteApiInfo(input: $input, condition: $condition) {\n      id\n      key\n      content\n      count\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const createPersonalPalette = /* GraphQL */ `\n  mutation CreatePersonalPalette(\n    $input: CreatePersonalPaletteInput!\n    $condition: ModelPersonalPaletteConditionInput\n  ) {\n    createPersonalPalette(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      path\n      owner\n      name\n      content\n    }\n  }\n`;\nexport const updatePersonalPalette = /* GraphQL */ `\n  mutation UpdatePersonalPalette(\n    $input: UpdatePersonalPaletteInput!\n    $condition: ModelPersonalPaletteConditionInput\n  ) {\n    updatePersonalPalette(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      path\n      owner\n      name\n      content\n    }\n  }\n`;\nexport const deletePersonalPalette = /* GraphQL */ `\n  mutation DeletePersonalPalette(\n    $input: DeletePersonalPaletteInput!\n    $condition: ModelPersonalPaletteConditionInput\n  ) {\n    deletePersonalPalette(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      path\n      owner\n      name\n      content\n    }\n  }\n`;\nexport const createCommunityPalette = /* GraphQL */ `\n  mutation CreateCommunityPalette(\n    $input: CreateCommunityPaletteInput!\n    $condition: ModelCommunityPaletteConditionInput\n  ) {\n    createCommunityPalette(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      path\n      owner\n      name\n      content\n    }\n  }\n`;\nexport const updateCommunityPalette = /* GraphQL */ `\n  mutation UpdateCommunityPalette(\n    $input: UpdateCommunityPaletteInput!\n    $condition: ModelCommunityPaletteConditionInput\n  ) {\n    updateCommunityPalette(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      path\n      owner\n      name\n      content\n    }\n  }\n`;\nexport const deleteCommunityPalette = /* GraphQL */ `\n  mutation DeleteCommunityPalette(\n    $input: DeleteCommunityPaletteInput!\n    $condition: ModelCommunityPaletteConditionInput\n  ) {\n    deleteCommunityPalette(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      path\n      owner\n      name\n      content\n    }\n  }\n`;\nexport const createUser = /* GraphQL */ `\n  mutation CreateUser(\n    $input: CreateUserInput!\n    $condition: ModelUserConditionInput\n  ) {\n    createUser(input: $input, condition: $condition) {\n      id\n      name\n      createdAt\n      updatedAt\n      SessionID\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      content\n      UserProfile\n      ttl\n      avatar\n    }\n  }\n`;\nexport const updateUser = /* GraphQL */ `\n  mutation UpdateUser(\n    $input: UpdateUserInput!\n    $condition: ModelUserConditionInput\n  ) {\n    updateUser(input: $input, condition: $condition) {\n      id\n      name\n      createdAt\n      updatedAt\n      SessionID\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      content\n      UserProfile\n      ttl\n      avatar\n    }\n  }\n`;\nexport const deleteUser = /* GraphQL */ `\n  mutation DeleteUser(\n    $input: DeleteUserInput!\n    $condition: ModelUserConditionInput\n  ) {\n    deleteUser(input: $input, condition: $condition) {\n      id\n      name\n      createdAt\n      updatedAt\n      SessionID\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      content\n      UserProfile\n      ttl\n      avatar\n    }\n  }\n`;\nexport const createErrorLog = /* GraphQL */ `\n  mutation CreateErrorLog(\n    $input: CreateErrorLogInput!\n    $condition: ModelErrorLogConditionInput\n  ) {\n    createErrorLog(input: $input, condition: $condition) {\n      id\n      name\n      createdAt\n      updatedAt\n      content\n      ttl\n    }\n  }\n`;\nexport const updateErrorLog = /* GraphQL */ `\n  mutation UpdateErrorLog(\n    $input: UpdateErrorLogInput!\n    $condition: ModelErrorLogConditionInput\n  ) {\n    updateErrorLog(input: $input, condition: $condition) {\n      id\n      name\n      createdAt\n      updatedAt\n      content\n      ttl\n    }\n  }\n`;\nexport const deleteErrorLog = /* GraphQL */ `\n  mutation DeleteErrorLog(\n    $input: DeleteErrorLogInput!\n    $condition: ModelErrorLogConditionInput\n  ) {\n    deleteErrorLog(input: $input, condition: $condition) {\n      id\n      name\n      createdAt\n      updatedAt\n      content\n      ttl\n    }\n  }\n`;\nexport const createFolder = /* GraphQL */ `\n  mutation CreateFolder(\n    $input: CreateFolderInput!\n    $condition: ModelFolderConditionInput\n  ) {\n    createFolder(input: $input, condition: $condition) {\n      id\n      name\n      createdAt\n      updatedAt\n      userProfileId\n      user {\n        id\n        name\n        createdAt\n        updatedAt\n        email\n        boardConfig\n        avatar\n        personalConfig\n        emailOptIn\n        paidPlan\n        validTeacher\n        adminOfTenant\n        TenantID\n        FEMStatus\n        lastVisitedSubs\n        MemberOfTeam\n        TutorGroupID\n      }\n      parentFolderPath\n    }\n  }\n`;\nexport const updateFolder = /* GraphQL */ `\n  mutation UpdateFolder(\n    $input: UpdateFolderInput!\n    $condition: ModelFolderConditionInput\n  ) {\n    updateFolder(input: $input, condition: $condition) {\n      id\n      name\n      createdAt\n      updatedAt\n      userProfileId\n      user {\n        id\n        name\n        createdAt\n        updatedAt\n        email\n        boardConfig\n        avatar\n        personalConfig\n        emailOptIn\n        paidPlan\n        validTeacher\n        adminOfTenant\n        TenantID\n        FEMStatus\n        lastVisitedSubs\n        MemberOfTeam\n        TutorGroupID\n      }\n      parentFolderPath\n    }\n  }\n`;\nexport const deleteFolder = /* GraphQL */ `\n  mutation DeleteFolder(\n    $input: DeleteFolderInput!\n    $condition: ModelFolderConditionInput\n  ) {\n    deleteFolder(input: $input, condition: $condition) {\n      id\n      name\n      createdAt\n      updatedAt\n      userProfileId\n      user {\n        id\n        name\n        createdAt\n        updatedAt\n        email\n        boardConfig\n        avatar\n        personalConfig\n        emailOptIn\n        paidPlan\n        validTeacher\n        adminOfTenant\n        TenantID\n        FEMStatus\n        lastVisitedSubs\n        MemberOfTeam\n        TutorGroupID\n      }\n      parentFolderPath\n    }\n  }\n`;\nexport const createServiceNotice = /* GraphQL */ `\n  mutation CreateServiceNotice(\n    $input: CreateServiceNoticeInput!\n    $condition: ModelServiceNoticeConditionInput\n  ) {\n    createServiceNotice(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      noticeConfig\n    }\n  }\n`;\nexport const updateServiceNotice = /* GraphQL */ `\n  mutation UpdateServiceNotice(\n    $input: UpdateServiceNoticeInput!\n    $condition: ModelServiceNoticeConditionInput\n  ) {\n    updateServiceNotice(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      noticeConfig\n    }\n  }\n`;\nexport const deleteServiceNotice = /* GraphQL */ `\n  mutation DeleteServiceNotice(\n    $input: DeleteServiceNoticeInput!\n    $condition: ModelServiceNoticeConditionInput\n  ) {\n    deleteServiceNotice(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      noticeConfig\n    }\n  }\n`;\nexport const createLatencyEndPoints = /* GraphQL */ `\n  mutation CreateLatencyEndPoints(\n    $input: CreateLatencyEndPointsInput!\n    $condition: ModelLatencyEndPointsConditionInput\n  ) {\n    createLatencyEndPoints(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      region\n      content\n    }\n  }\n`;\nexport const updateLatencyEndPoints = /* GraphQL */ `\n  mutation UpdateLatencyEndPoints(\n    $input: UpdateLatencyEndPointsInput!\n    $condition: ModelLatencyEndPointsConditionInput\n  ) {\n    updateLatencyEndPoints(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      region\n      content\n    }\n  }\n`;\nexport const deleteLatencyEndPoints = /* GraphQL */ `\n  mutation DeleteLatencyEndPoints(\n    $input: DeleteLatencyEndPointsInput!\n    $condition: ModelLatencyEndPointsConditionInput\n  ) {\n    deleteLatencyEndPoints(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      region\n      content\n    }\n  }\n`;\nexport const createRemoteControl = /* GraphQL */ `\n  mutation CreateRemoteControl(\n    $input: CreateRemoteControlInput!\n    $condition: ModelRemoteControlConditionInput\n  ) {\n    createRemoteControl(input: $input, condition: $condition) {\n      id\n      parentID\n      ttl\n      createdAt\n      updatedAt\n      content\n    }\n  }\n`;\nexport const updateRemoteControl = /* GraphQL */ `\n  mutation UpdateRemoteControl(\n    $input: UpdateRemoteControlInput!\n    $condition: ModelRemoteControlConditionInput\n  ) {\n    updateRemoteControl(input: $input, condition: $condition) {\n      id\n      parentID\n      ttl\n      createdAt\n      updatedAt\n      content\n    }\n  }\n`;\nexport const deleteRemoteControl = /* GraphQL */ `\n  mutation DeleteRemoteControl(\n    $input: DeleteRemoteControlInput!\n    $condition: ModelRemoteControlConditionInput\n  ) {\n    deleteRemoteControl(input: $input, condition: $condition) {\n      id\n      parentID\n      ttl\n      createdAt\n      updatedAt\n      content\n    }\n  }\n`;\nexport const createLatencyCalculation = /* GraphQL */ `\n  mutation CreateLatencyCalculation(\n    $input: CreateLatencyCalculationInput!\n    $condition: ModelLatencyCalculationConditionInput\n  ) {\n    createLatencyCalculation(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      region\n      clientRegion\n      content\n    }\n  }\n`;\nexport const updateLatencyCalculation = /* GraphQL */ `\n  mutation UpdateLatencyCalculation(\n    $input: UpdateLatencyCalculationInput!\n    $condition: ModelLatencyCalculationConditionInput\n  ) {\n    updateLatencyCalculation(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      region\n      clientRegion\n      content\n    }\n  }\n`;\nexport const deleteLatencyCalculation = /* GraphQL */ `\n  mutation DeleteLatencyCalculation(\n    $input: DeleteLatencyCalculationInput!\n    $condition: ModelLatencyCalculationConditionInput\n  ) {\n    deleteLatencyCalculation(input: $input, condition: $condition) {\n      id\n      createdAt\n      updatedAt\n      region\n      clientRegion\n      content\n    }\n  }\n`;\nexport const createTenant = /* GraphQL */ `\n  mutation CreateTenant(\n    $input: CreateTenantInput!\n    $condition: ModelTenantConditionInput\n  ) {\n    createTenant(input: $input, condition: $condition) {\n      id\n      name\n      domainName\n      createdAt\n      updatedAt\n      entitlements\n      adminUsers\n      tenantConfig\n      secondaryDomainConfig\n      licensedUsers {\n        items {\n          id\n          name\n          createdAt\n          updatedAt\n          email\n          boardConfig\n          avatar\n          personalConfig\n          emailOptIn\n          paidPlan\n          validTeacher\n          adminOfTenant\n          TenantID\n          FEMStatus\n          lastVisitedSubs\n          MemberOfTeam\n          TutorGroupID\n        }\n        nextToken\n      }\n    }\n  }\n`;\nexport const updateTenant = /* GraphQL */ `\n  mutation UpdateTenant(\n    $input: UpdateTenantInput!\n    $condition: ModelTenantConditionInput\n  ) {\n    updateTenant(input: $input, condition: $condition) {\n      id\n      name\n      domainName\n      createdAt\n      updatedAt\n      entitlements\n      adminUsers\n      tenantConfig\n      secondaryDomainConfig\n      licensedUsers {\n        items {\n          id\n          name\n          createdAt\n          updatedAt\n          email\n          boardConfig\n          avatar\n          personalConfig\n          emailOptIn\n          paidPlan\n          validTeacher\n          adminOfTenant\n          TenantID\n          FEMStatus\n          lastVisitedSubs\n          MemberOfTeam\n          TutorGroupID\n        }\n        nextToken\n      }\n    }\n  }\n`;\nexport const deleteTenant = /* GraphQL */ `\n  mutation DeleteTenant(\n    $input: DeleteTenantInput!\n    $condition: ModelTenantConditionInput\n  ) {\n    deleteTenant(input: $input, condition: $condition) {\n      id\n      name\n      domainName\n      createdAt\n      updatedAt\n      entitlements\n      adminUsers\n      tenantConfig\n      secondaryDomainConfig\n      licensedUsers {\n        items {\n          id\n          name\n          createdAt\n          updatedAt\n          email\n          boardConfig\n          avatar\n          personalConfig\n          emailOptIn\n          paidPlan\n          validTeacher\n          adminOfTenant\n          TenantID\n          FEMStatus\n          lastVisitedSubs\n          MemberOfTeam\n          TutorGroupID\n        }\n        nextToken\n      }\n    }\n  }\n`;\nexport const createVideoRoom = /* GraphQL */ `\n  mutation CreateVideoRoom(\n    $input: CreateVideoRoomInput!\n    $condition: ModelVideoRoomConditionInput\n  ) {\n    createVideoRoom(input: $input, condition: $condition) {\n      id\n      SID\n      name\n      createdAt\n      updatedAt\n      state\n      url\n      content\n      SessionID\n      recordingTurnedOn\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      ttl\n    }\n  }\n`;\nexport const updateVideoRoom = /* GraphQL */ `\n  mutation UpdateVideoRoom(\n    $input: UpdateVideoRoomInput!\n    $condition: ModelVideoRoomConditionInput\n  ) {\n    updateVideoRoom(input: $input, condition: $condition) {\n      id\n      SID\n      name\n      createdAt\n      updatedAt\n      state\n      url\n      content\n      SessionID\n      recordingTurnedOn\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      ttl\n    }\n  }\n`;\nexport const deleteVideoRoom = /* GraphQL */ `\n  mutation DeleteVideoRoom(\n    $input: DeleteVideoRoomInput!\n    $condition: ModelVideoRoomConditionInput\n  ) {\n    deleteVideoRoom(input: $input, condition: $condition) {\n      id\n      SID\n      name\n      createdAt\n      updatedAt\n      state\n      url\n      content\n      SessionID\n      recordingTurnedOn\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      ttl\n    }\n  }\n`;\n","/* eslint-disable */\n// this is an auto generated file. This will be overwritten\n\nexport const subscribeToSessionObjects = /* GraphQL */ `\n  subscription SubscribeToSessionObjects($SessionID: ID) {\n    subscribeToSessionObjects(SessionID: $SessionID) {\n      id\n      name\n      content\n      type\n      objType\n      ended\n      createdAt\n      updatedAt\n      SessionID\n      ttl\n      animate\n      CreatedBy\n      CreatorLocalID\n      DisableSync\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      deleted\n    }\n  }\n`;\nexport const subscribeToSessionbyOwner = /* GraphQL */ `\n  subscription SubscribeToSessionbyOwner($savedOwner: ID) {\n    subscribeToSessionbyOwner(savedOwner: $savedOwner) {\n      id\n      name\n      content\n      createdAt\n      updatedAt\n      Objects {\n        items {\n          id\n          name\n          content\n          type\n          objType\n          ended\n          createdAt\n          updatedAt\n          SessionID\n          ttl\n          animate\n          CreatedBy\n          CreatorLocalID\n          DisableSync\n          deleted\n        }\n        nextToken\n      }\n      ttl\n      savedOwner\n      parentID\n      pageNumber\n      boardConfig\n      Users {\n        items {\n          id\n          name\n          createdAt\n          updatedAt\n          SessionID\n          content\n          UserProfile\n          ttl\n          avatar\n        }\n        nextToken\n      }\n      parentBoardID\n      folderID\n      Classroom\n      CreatorLocalID\n      MultiBoard {\n        items {\n          id\n          parentBoardID\n          childBoardID\n          ttl\n          createdAt\n          updatedAt\n        }\n        nextToken\n      }\n      isGroup\n      joinCode\n      TenantID\n      deleted\n      TutorClass\n    }\n  }\n`;\nexport const subscribeToSessionDelbyOwner = /* GraphQL */ `\n  subscription SubscribeToSessionDelbyOwner($savedOwner: ID) {\n    subscribeToSessionDelbyOwner(savedOwner: $savedOwner) {\n      id\n      name\n      content\n      createdAt\n      updatedAt\n      Objects {\n        items {\n          id\n          name\n          content\n          type\n          objType\n          ended\n          createdAt\n          updatedAt\n          SessionID\n          ttl\n          animate\n          CreatedBy\n          CreatorLocalID\n          DisableSync\n          deleted\n        }\n        nextToken\n      }\n      ttl\n      savedOwner\n      parentID\n      pageNumber\n      boardConfig\n      Users {\n        items {\n          id\n          name\n          createdAt\n          updatedAt\n          SessionID\n          content\n          UserProfile\n          ttl\n          avatar\n        }\n        nextToken\n      }\n      parentBoardID\n      folderID\n      Classroom\n      CreatorLocalID\n      MultiBoard {\n        items {\n          id\n          parentBoardID\n          childBoardID\n          ttl\n          createdAt\n          updatedAt\n        }\n        nextToken\n      }\n      isGroup\n      joinCode\n      TenantID\n      deleted\n      TutorClass\n    }\n  }\n`;\nexport const subscribeToSessionbyparentBoardID = /* GraphQL */ `\n  subscription SubscribeToSessionbyparentBoardID($parentBoardID: ID) {\n    subscribeToSessionbyparentBoardID(parentBoardID: $parentBoardID) {\n      id\n      name\n      content\n      createdAt\n      updatedAt\n      Objects {\n        items {\n          id\n          name\n          content\n          type\n          objType\n          ended\n          createdAt\n          updatedAt\n          SessionID\n          ttl\n          animate\n          CreatedBy\n          CreatorLocalID\n          DisableSync\n          deleted\n        }\n        nextToken\n      }\n      ttl\n      savedOwner\n      parentID\n      pageNumber\n      boardConfig\n      Users {\n        items {\n          id\n          name\n          createdAt\n          updatedAt\n          SessionID\n          content\n          UserProfile\n          ttl\n          avatar\n        }\n        nextToken\n      }\n      parentBoardID\n      folderID\n      Classroom\n      CreatorLocalID\n      MultiBoard {\n        items {\n          id\n          parentBoardID\n          childBoardID\n          ttl\n          createdAt\n          updatedAt\n        }\n        nextToken\n      }\n      isGroup\n      joinCode\n      TenantID\n      deleted\n      TutorClass\n    }\n  }\n`;\nexport const subscribeToSessionDelbyparentBoardID = /* GraphQL */ `\n  subscription SubscribeToSessionDelbyparentBoardID($parentBoardID: ID) {\n    subscribeToSessionDelbyparentBoardID(parentBoardID: $parentBoardID) {\n      id\n      name\n      content\n      createdAt\n      updatedAt\n      Objects {\n        items {\n          id\n          name\n          content\n          type\n          objType\n          ended\n          createdAt\n          updatedAt\n          SessionID\n          ttl\n          animate\n          CreatedBy\n          CreatorLocalID\n          DisableSync\n          deleted\n        }\n        nextToken\n      }\n      ttl\n      savedOwner\n      parentID\n      pageNumber\n      boardConfig\n      Users {\n        items {\n          id\n          name\n          createdAt\n          updatedAt\n          SessionID\n          content\n          UserProfile\n          ttl\n          avatar\n        }\n        nextToken\n      }\n      parentBoardID\n      folderID\n      Classroom\n      CreatorLocalID\n      MultiBoard {\n        items {\n          id\n          parentBoardID\n          childBoardID\n          ttl\n          createdAt\n          updatedAt\n        }\n        nextToken\n      }\n      isGroup\n      joinCode\n      TenantID\n      deleted\n      TutorClass\n    }\n  }\n`;\nexport const delSessionObject = /* GraphQL */ `\n  subscription DelSessionObject($SessionID: ID) {\n    delSessionObject(SessionID: $SessionID) {\n      id\n      name\n      content\n      type\n      objType\n      ended\n      createdAt\n      updatedAt\n      SessionID\n      ttl\n      animate\n      CreatedBy\n      CreatorLocalID\n      DisableSync\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      deleted\n    }\n  }\n`;\nexport const subscribeToSessionUsers = /* GraphQL */ `\n  subscription SubscribeToSessionUsers($SessionID: ID) {\n    subscribeToSessionUsers(SessionID: $SessionID) {\n      id\n      name\n      createdAt\n      updatedAt\n      SessionID\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      content\n      UserProfile\n      ttl\n      avatar\n    }\n  }\n`;\nexport const subscribeToSession = /* GraphQL */ `\n  subscription SubscribeToSession($id: ID) {\n    subscribeToSession(id: $id) {\n      id\n      name\n      content\n      createdAt\n      updatedAt\n      Objects {\n        items {\n          id\n          name\n          content\n          type\n          objType\n          ended\n          createdAt\n          updatedAt\n          SessionID\n          ttl\n          animate\n          CreatedBy\n          CreatorLocalID\n          DisableSync\n          deleted\n        }\n        nextToken\n      }\n      ttl\n      savedOwner\n      parentID\n      pageNumber\n      boardConfig\n      Users {\n        items {\n          id\n          name\n          createdAt\n          updatedAt\n          SessionID\n          content\n          UserProfile\n          ttl\n          avatar\n        }\n        nextToken\n      }\n      parentBoardID\n      folderID\n      Classroom\n      CreatorLocalID\n      MultiBoard {\n        items {\n          id\n          parentBoardID\n          childBoardID\n          ttl\n          createdAt\n          updatedAt\n        }\n        nextToken\n      }\n      isGroup\n      joinCode\n      TenantID\n      deleted\n      TutorClass\n    }\n  }\n`;\nexport const subscribeToDelSession = /* GraphQL */ `\n  subscription SubscribeToDelSession($id: ID) {\n    subscribeToDelSession(id: $id) {\n      id\n      name\n      content\n      createdAt\n      updatedAt\n      Objects {\n        items {\n          id\n          name\n          content\n          type\n          objType\n          ended\n          createdAt\n          updatedAt\n          SessionID\n          ttl\n          animate\n          CreatedBy\n          CreatorLocalID\n          DisableSync\n          deleted\n        }\n        nextToken\n      }\n      ttl\n      savedOwner\n      parentID\n      pageNumber\n      boardConfig\n      Users {\n        items {\n          id\n          name\n          createdAt\n          updatedAt\n          SessionID\n          content\n          UserProfile\n          ttl\n          avatar\n        }\n        nextToken\n      }\n      parentBoardID\n      folderID\n      Classroom\n      CreatorLocalID\n      MultiBoard {\n        items {\n          id\n          parentBoardID\n          childBoardID\n          ttl\n          createdAt\n          updatedAt\n        }\n        nextToken\n      }\n      isGroup\n      joinCode\n      TenantID\n      deleted\n      TutorClass\n    }\n  }\n`;\nexport const subscribeToMBByParent = /* GraphQL */ `\n  subscription SubscribeToMBByParent($parentBoardID: ID) {\n    subscribeToMBByParent(parentBoardID: $parentBoardID) {\n      id\n      parentBoardID\n      parentBoard {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      childBoardID\n      childBoard {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      ttl\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const subscribeToMBByParentDel = /* GraphQL */ `\n  subscription SubscribeToMBByParentDel($parentBoardID: ID) {\n    subscribeToMBByParentDel(parentBoardID: $parentBoardID) {\n      id\n      parentBoardID\n      parentBoard {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      childBoardID\n      childBoard {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      ttl\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const subscribeToSessionbyClassroom = /* GraphQL */ `\n  subscription SubscribeToSessionbyClassroom($Classroom: ID) {\n    subscribeToSessionbyClassroom(Classroom: $Classroom) {\n      id\n      name\n      content\n      createdAt\n      updatedAt\n      Objects {\n        items {\n          id\n          name\n          content\n          type\n          objType\n          ended\n          createdAt\n          updatedAt\n          SessionID\n          ttl\n          animate\n          CreatedBy\n          CreatorLocalID\n          DisableSync\n          deleted\n        }\n        nextToken\n      }\n      ttl\n      savedOwner\n      parentID\n      pageNumber\n      boardConfig\n      Users {\n        items {\n          id\n          name\n          createdAt\n          updatedAt\n          SessionID\n          content\n          UserProfile\n          ttl\n          avatar\n        }\n        nextToken\n      }\n      parentBoardID\n      folderID\n      Classroom\n      CreatorLocalID\n      MultiBoard {\n        items {\n          id\n          parentBoardID\n          childBoardID\n          ttl\n          createdAt\n          updatedAt\n        }\n        nextToken\n      }\n      isGroup\n      joinCode\n      TenantID\n      deleted\n      TutorClass\n    }\n  }\n`;\nexport const subscribeToSessionDelbyClassroom = /* GraphQL */ `\n  subscription SubscribeToSessionDelbyClassroom($Classroom: ID) {\n    subscribeToSessionDelbyClassroom(Classroom: $Classroom) {\n      id\n      name\n      content\n      createdAt\n      updatedAt\n      Objects {\n        items {\n          id\n          name\n          content\n          type\n          objType\n          ended\n          createdAt\n          updatedAt\n          SessionID\n          ttl\n          animate\n          CreatedBy\n          CreatorLocalID\n          DisableSync\n          deleted\n        }\n        nextToken\n      }\n      ttl\n      savedOwner\n      parentID\n      pageNumber\n      boardConfig\n      Users {\n        items {\n          id\n          name\n          createdAt\n          updatedAt\n          SessionID\n          content\n          UserProfile\n          ttl\n          avatar\n        }\n        nextToken\n      }\n      parentBoardID\n      folderID\n      Classroom\n      CreatorLocalID\n      MultiBoard {\n        items {\n          id\n          parentBoardID\n          childBoardID\n          ttl\n          createdAt\n          updatedAt\n        }\n        nextToken\n      }\n      isGroup\n      joinCode\n      TenantID\n      deleted\n      TutorClass\n    }\n  }\n`;\nexport const subscribeToClassroomById = /* GraphQL */ `\n  subscription SubscribeToClassroomById($id: ID) {\n    subscribeToClassroomById(id: $id) {\n      id\n      name\n      TeacherID\n      content\n      Teacher {\n        id\n        name\n        createdAt\n        updatedAt\n        email\n        boardConfig\n        avatar\n        personalConfig\n        emailOptIn\n        paidPlan\n        validTeacher\n        adminOfTenant\n        TenantID\n        FEMStatus\n        lastVisitedSubs\n        MemberOfTeam\n        TutorGroupID\n      }\n      Users {\n        items {\n          id\n          content\n          createdAt\n          updatedAt\n          CurrentSessionId\n          CurrentUserId\n          ClassroomID\n          ttl\n          deleted\n        }\n        nextToken\n      }\n      ttl\n      createdAt\n      updatedAt\n      TeacherList\n    }\n  }\n`;\nexport const subscribeToClassroomEvents = /* GraphQL */ `\n  subscription SubscribeToClassroomEvents($Classroom: ID) {\n    subscribeToClassroomEvents(Classroom: $Classroom) {\n      id\n      createdAt\n      updatedAt\n      ttl\n      type\n      event\n      For\n      State\n      Content\n      Classroom\n      deleted\n    }\n  }\n`;\nexport const subscribeToClassroomEventsDel = /* GraphQL */ `\n  subscription SubscribeToClassroomEventsDel($Classroom: ID) {\n    subscribeToClassroomEventsDel(Classroom: $Classroom) {\n      id\n      createdAt\n      updatedAt\n      ttl\n      type\n      event\n      For\n      State\n      Content\n      Classroom\n      deleted\n    }\n  }\n`;\nexport const subscribeToClassGroup = /* GraphQL */ `\n  subscription SubscribeToClassGroup($Classroom: ID) {\n    subscribeToClassGroup(Classroom: $Classroom) {\n      id\n      createdAt\n      updatedAt\n      ttl\n      name\n      content\n      Classroom\n      SessionID\n      deleted\n    }\n  }\n`;\nexport const subscribeToDelClassGroup = /* GraphQL */ `\n  subscription SubscribeToDelClassGroup($Classroom: ID) {\n    subscribeToDelClassGroup(Classroom: $Classroom) {\n      id\n      createdAt\n      updatedAt\n      ttl\n      name\n      content\n      Classroom\n      SessionID\n      deleted\n    }\n  }\n`;\nexport const subscribeToLocalUsersByClass = /* GraphQL */ `\n  subscription SubscribeToLocalUsersByClass($ClassroomID: ID) {\n    subscribeToLocalUsersByClass(ClassroomID: $ClassroomID) {\n      id\n      content\n      createdAt\n      updatedAt\n      CurrentSession {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      CurrentSessionId\n      CurrentUserId\n      CurrentUser {\n        id\n        name\n        createdAt\n        updatedAt\n        SessionID\n        Session {\n          id\n          name\n          content\n          createdAt\n          updatedAt\n          ttl\n          savedOwner\n          parentID\n          pageNumber\n          boardConfig\n          parentBoardID\n          folderID\n          Classroom\n          CreatorLocalID\n          isGroup\n          joinCode\n          TenantID\n          deleted\n          TutorClass\n        }\n        content\n        UserProfile\n        ttl\n        avatar\n      }\n      ClassroomID\n      ttl\n      deleted\n    }\n  }\n`;\nexport const subscribeToDelLocalUsersByClass = /* GraphQL */ `\n  subscription SubscribeToDelLocalUsersByClass($ClassroomID: ID) {\n    subscribeToDelLocalUsersByClass(ClassroomID: $ClassroomID) {\n      id\n      content\n      createdAt\n      updatedAt\n      CurrentSession {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      CurrentSessionId\n      CurrentUserId\n      CurrentUser {\n        id\n        name\n        createdAt\n        updatedAt\n        SessionID\n        Session {\n          id\n          name\n          content\n          createdAt\n          updatedAt\n          ttl\n          savedOwner\n          parentID\n          pageNumber\n          boardConfig\n          parentBoardID\n          folderID\n          Classroom\n          CreatorLocalID\n          isGroup\n          joinCode\n          TenantID\n          deleted\n          TutorClass\n        }\n        content\n        UserProfile\n        ttl\n        avatar\n      }\n      ClassroomID\n      ttl\n      deleted\n    }\n  }\n`;\nexport const subscribeToFoldersbyOwner = /* GraphQL */ `\n  subscription SubscribeToFoldersbyOwner($userProfileId: ID) {\n    subscribeToFoldersbyOwner(userProfileId: $userProfileId) {\n      id\n      name\n      createdAt\n      updatedAt\n      userProfileId\n      user {\n        id\n        name\n        createdAt\n        updatedAt\n        email\n        boardConfig\n        avatar\n        personalConfig\n        emailOptIn\n        paidPlan\n        validTeacher\n        adminOfTenant\n        TenantID\n        FEMStatus\n        lastVisitedSubs\n        MemberOfTeam\n        TutorGroupID\n      }\n      parentFolderPath\n    }\n  }\n`;\nexport const subscribeToDelFoldersbyOwner = /* GraphQL */ `\n  subscription SubscribeToDelFoldersbyOwner($userProfileId: ID) {\n    subscribeToDelFoldersbyOwner(userProfileId: $userProfileId) {\n      id\n      name\n      createdAt\n      updatedAt\n      userProfileId\n      user {\n        id\n        name\n        createdAt\n        updatedAt\n        email\n        boardConfig\n        avatar\n        personalConfig\n        emailOptIn\n        paidPlan\n        validTeacher\n        adminOfTenant\n        TenantID\n        FEMStatus\n        lastVisitedSubs\n        MemberOfTeam\n        TutorGroupID\n      }\n      parentFolderPath\n    }\n  }\n`;\nexport const subscribeToPalette = /* GraphQL */ `\n  subscription SubscribeToPalette($owner: ID) {\n    subscribeToPalette(owner: $owner) {\n      id\n      createdAt\n      updatedAt\n      path\n      owner\n      name\n      content\n    }\n  }\n`;\nexport const subscribeToDelPalette = /* GraphQL */ `\n  subscription SubscribeToDelPalette($owner: ID) {\n    subscribeToDelPalette(owner: $owner) {\n      id\n      createdAt\n      updatedAt\n      path\n      owner\n      name\n      content\n    }\n  }\n`;\nexport const subscribeToGamePlay = /* GraphQL */ `\n  subscription SubscribeToGamePlay($id: ID) {\n    subscribeToGamePlay(id: $id) {\n      id\n      Session\n      type\n      content\n      createdAt\n      updatedAt\n      version\n      ttl\n    }\n  }\n`;\nexport const subscribeToEngagementEvent = /* GraphQL */ `\n  subscription SubscribeToEngagementEvent($Classroom: ID) {\n    subscribeToEngagementEvent(Classroom: $Classroom) {\n      id\n      createdAt\n      updatedAt\n      luid\n      name\n      time\n      ttl\n      Content\n      Classroom\n    }\n  }\n`;\nexport const subscribeToRemoteControl = /* GraphQL */ `\n  subscription SubscribeToRemoteControl($parentID: ID) {\n    subscribeToRemoteControl(parentID: $parentID) {\n      id\n      parentID\n      ttl\n      createdAt\n      updatedAt\n      content\n    }\n  }\n`;\nexport const subscribeToTutorClassEvent = /* GraphQL */ `\n  subscription SubscribeToTutorClassEvent($TutorClassID: ID) {\n    subscribeToTutorClassEvent(TutorClassID: $TutorClassID) {\n      id\n      createdAt\n      updatedAt\n      config\n      type\n      TutorGroupID\n      TutorGroup {\n        id\n        name\n        createdAt\n        updatedAt\n        config\n        roster\n        creator\n        TenantID\n        tutorClasses {\n          nextToken\n        }\n      }\n      TutorClassID\n      TutorClass {\n        id\n        name\n        description\n        videoMode\n        createdAt\n        updatedAt\n        config\n        roster\n        TutorGroupID\n        TutorGroup {\n          id\n          name\n          createdAt\n          updatedAt\n          config\n          roster\n          creator\n          TenantID\n        }\n        Sessions\n        TutorClassEvents {\n          nextToken\n        }\n      }\n    }\n  }\n`;\nexport const subscribeToTutorClassEventDel = /* GraphQL */ `\n  subscription SubscribeToTutorClassEventDel($TutorClassID: ID) {\n    subscribeToTutorClassEventDel(TutorClassID: $TutorClassID) {\n      id\n      createdAt\n      updatedAt\n      config\n      type\n      TutorGroupID\n      TutorGroup {\n        id\n        name\n        createdAt\n        updatedAt\n        config\n        roster\n        creator\n        TenantID\n        tutorClasses {\n          nextToken\n        }\n      }\n      TutorClassID\n      TutorClass {\n        id\n        name\n        description\n        videoMode\n        createdAt\n        updatedAt\n        config\n        roster\n        TutorGroupID\n        TutorGroup {\n          id\n          name\n          createdAt\n          updatedAt\n          config\n          roster\n          creator\n          TenantID\n        }\n        Sessions\n        TutorClassEvents {\n          nextToken\n        }\n      }\n    }\n  }\n`;\nexport const onCreateSession = /* GraphQL */ `\n  subscription OnCreateSession {\n    onCreateSession {\n      id\n      name\n      content\n      createdAt\n      updatedAt\n      Objects {\n        items {\n          id\n          name\n          content\n          type\n          objType\n          ended\n          createdAt\n          updatedAt\n          SessionID\n          ttl\n          animate\n          CreatedBy\n          CreatorLocalID\n          DisableSync\n          deleted\n        }\n        nextToken\n      }\n      ttl\n      savedOwner\n      parentID\n      pageNumber\n      boardConfig\n      Users {\n        items {\n          id\n          name\n          createdAt\n          updatedAt\n          SessionID\n          content\n          UserProfile\n          ttl\n          avatar\n        }\n        nextToken\n      }\n      parentBoardID\n      folderID\n      Classroom\n      CreatorLocalID\n      MultiBoard {\n        items {\n          id\n          parentBoardID\n          childBoardID\n          ttl\n          createdAt\n          updatedAt\n        }\n        nextToken\n      }\n      isGroup\n      joinCode\n      TenantID\n      deleted\n      TutorClass\n    }\n  }\n`;\nexport const onUpdateSession = /* GraphQL */ `\n  subscription OnUpdateSession {\n    onUpdateSession {\n      id\n      name\n      content\n      createdAt\n      updatedAt\n      Objects {\n        items {\n          id\n          name\n          content\n          type\n          objType\n          ended\n          createdAt\n          updatedAt\n          SessionID\n          ttl\n          animate\n          CreatedBy\n          CreatorLocalID\n          DisableSync\n          deleted\n        }\n        nextToken\n      }\n      ttl\n      savedOwner\n      parentID\n      pageNumber\n      boardConfig\n      Users {\n        items {\n          id\n          name\n          createdAt\n          updatedAt\n          SessionID\n          content\n          UserProfile\n          ttl\n          avatar\n        }\n        nextToken\n      }\n      parentBoardID\n      folderID\n      Classroom\n      CreatorLocalID\n      MultiBoard {\n        items {\n          id\n          parentBoardID\n          childBoardID\n          ttl\n          createdAt\n          updatedAt\n        }\n        nextToken\n      }\n      isGroup\n      joinCode\n      TenantID\n      deleted\n      TutorClass\n    }\n  }\n`;\nexport const onDeleteSession = /* GraphQL */ `\n  subscription OnDeleteSession {\n    onDeleteSession {\n      id\n      name\n      content\n      createdAt\n      updatedAt\n      Objects {\n        items {\n          id\n          name\n          content\n          type\n          objType\n          ended\n          createdAt\n          updatedAt\n          SessionID\n          ttl\n          animate\n          CreatedBy\n          CreatorLocalID\n          DisableSync\n          deleted\n        }\n        nextToken\n      }\n      ttl\n      savedOwner\n      parentID\n      pageNumber\n      boardConfig\n      Users {\n        items {\n          id\n          name\n          createdAt\n          updatedAt\n          SessionID\n          content\n          UserProfile\n          ttl\n          avatar\n        }\n        nextToken\n      }\n      parentBoardID\n      folderID\n      Classroom\n      CreatorLocalID\n      MultiBoard {\n        items {\n          id\n          parentBoardID\n          childBoardID\n          ttl\n          createdAt\n          updatedAt\n        }\n        nextToken\n      }\n      isGroup\n      joinCode\n      TenantID\n      deleted\n      TutorClass\n    }\n  }\n`;\nexport const onCreateCommunityBoard = /* GraphQL */ `\n  subscription OnCreateCommunityBoard {\n    onCreateCommunityBoard {\n      id\n      name\n      description\n      creator\n      creatorEmail\n      CreatorLocalID\n      Country\n      Grade\n      Subject\n      boardLink\n      content\n      createdAt\n      updatedAt\n      title\n      deleted\n    }\n  }\n`;\nexport const onUpdateCommunityBoard = /* GraphQL */ `\n  subscription OnUpdateCommunityBoard {\n    onUpdateCommunityBoard {\n      id\n      name\n      description\n      creator\n      creatorEmail\n      CreatorLocalID\n      Country\n      Grade\n      Subject\n      boardLink\n      content\n      createdAt\n      updatedAt\n      title\n      deleted\n    }\n  }\n`;\nexport const onDeleteCommunityBoard = /* GraphQL */ `\n  subscription OnDeleteCommunityBoard {\n    onDeleteCommunityBoard {\n      id\n      name\n      description\n      creator\n      creatorEmail\n      CreatorLocalID\n      Country\n      Grade\n      Subject\n      boardLink\n      content\n      createdAt\n      updatedAt\n      title\n      deleted\n    }\n  }\n`;\nexport const onCreateClassroom = /* GraphQL */ `\n  subscription OnCreateClassroom {\n    onCreateClassroom {\n      id\n      name\n      TeacherID\n      content\n      Teacher {\n        id\n        name\n        createdAt\n        updatedAt\n        email\n        boardConfig\n        avatar\n        personalConfig\n        emailOptIn\n        paidPlan\n        validTeacher\n        adminOfTenant\n        TenantID\n        FEMStatus\n        lastVisitedSubs\n        MemberOfTeam\n        TutorGroupID\n      }\n      Users {\n        items {\n          id\n          content\n          createdAt\n          updatedAt\n          CurrentSessionId\n          CurrentUserId\n          ClassroomID\n          ttl\n          deleted\n        }\n        nextToken\n      }\n      ttl\n      createdAt\n      updatedAt\n      TeacherList\n    }\n  }\n`;\nexport const onUpdateClassroom = /* GraphQL */ `\n  subscription OnUpdateClassroom {\n    onUpdateClassroom {\n      id\n      name\n      TeacherID\n      content\n      Teacher {\n        id\n        name\n        createdAt\n        updatedAt\n        email\n        boardConfig\n        avatar\n        personalConfig\n        emailOptIn\n        paidPlan\n        validTeacher\n        adminOfTenant\n        TenantID\n        FEMStatus\n        lastVisitedSubs\n        MemberOfTeam\n        TutorGroupID\n      }\n      Users {\n        items {\n          id\n          content\n          createdAt\n          updatedAt\n          CurrentSessionId\n          CurrentUserId\n          ClassroomID\n          ttl\n          deleted\n        }\n        nextToken\n      }\n      ttl\n      createdAt\n      updatedAt\n      TeacherList\n    }\n  }\n`;\nexport const onDeleteClassroom = /* GraphQL */ `\n  subscription OnDeleteClassroom {\n    onDeleteClassroom {\n      id\n      name\n      TeacherID\n      content\n      Teacher {\n        id\n        name\n        createdAt\n        updatedAt\n        email\n        boardConfig\n        avatar\n        personalConfig\n        emailOptIn\n        paidPlan\n        validTeacher\n        adminOfTenant\n        TenantID\n        FEMStatus\n        lastVisitedSubs\n        MemberOfTeam\n        TutorGroupID\n      }\n      Users {\n        items {\n          id\n          content\n          createdAt\n          updatedAt\n          CurrentSessionId\n          CurrentUserId\n          ClassroomID\n          ttl\n          deleted\n        }\n        nextToken\n      }\n      ttl\n      createdAt\n      updatedAt\n      TeacherList\n    }\n  }\n`;\nexport const onCreateGamePlay = /* GraphQL */ `\n  subscription OnCreateGamePlay {\n    onCreateGamePlay {\n      id\n      Session\n      type\n      content\n      createdAt\n      updatedAt\n      version\n      ttl\n    }\n  }\n`;\nexport const onUpdateGamePlay = /* GraphQL */ `\n  subscription OnUpdateGamePlay {\n    onUpdateGamePlay {\n      id\n      Session\n      type\n      content\n      createdAt\n      updatedAt\n      version\n      ttl\n    }\n  }\n`;\nexport const onDeleteGamePlay = /* GraphQL */ `\n  subscription OnDeleteGamePlay {\n    onDeleteGamePlay {\n      id\n      Session\n      type\n      content\n      createdAt\n      updatedAt\n      version\n      ttl\n    }\n  }\n`;\nexport const onCreateClassGroup = /* GraphQL */ `\n  subscription OnCreateClassGroup {\n    onCreateClassGroup {\n      id\n      createdAt\n      updatedAt\n      ttl\n      name\n      content\n      Classroom\n      SessionID\n      deleted\n    }\n  }\n`;\nexport const onUpdateClassGroup = /* GraphQL */ `\n  subscription OnUpdateClassGroup {\n    onUpdateClassGroup {\n      id\n      createdAt\n      updatedAt\n      ttl\n      name\n      content\n      Classroom\n      SessionID\n      deleted\n    }\n  }\n`;\nexport const onDeleteClassGroup = /* GraphQL */ `\n  subscription OnDeleteClassGroup {\n    onDeleteClassGroup {\n      id\n      createdAt\n      updatedAt\n      ttl\n      name\n      content\n      Classroom\n      SessionID\n      deleted\n    }\n  }\n`;\nexport const onCreateClassroomEvent = /* GraphQL */ `\n  subscription OnCreateClassroomEvent {\n    onCreateClassroomEvent {\n      id\n      createdAt\n      updatedAt\n      ttl\n      type\n      event\n      For\n      State\n      Content\n      Classroom\n      deleted\n    }\n  }\n`;\nexport const onUpdateClassroomEvent = /* GraphQL */ `\n  subscription OnUpdateClassroomEvent {\n    onUpdateClassroomEvent {\n      id\n      createdAt\n      updatedAt\n      ttl\n      type\n      event\n      For\n      State\n      Content\n      Classroom\n      deleted\n    }\n  }\n`;\nexport const onDeleteClassroomEvent = /* GraphQL */ `\n  subscription OnDeleteClassroomEvent {\n    onDeleteClassroomEvent {\n      id\n      createdAt\n      updatedAt\n      ttl\n      type\n      event\n      For\n      State\n      Content\n      Classroom\n      deleted\n    }\n  }\n`;\nexport const onCreateEngagementEvent = /* GraphQL */ `\n  subscription OnCreateEngagementEvent {\n    onCreateEngagementEvent {\n      id\n      createdAt\n      updatedAt\n      luid\n      name\n      time\n      ttl\n      Content\n      Classroom\n    }\n  }\n`;\nexport const onUpdateEngagementEvent = /* GraphQL */ `\n  subscription OnUpdateEngagementEvent {\n    onUpdateEngagementEvent {\n      id\n      createdAt\n      updatedAt\n      luid\n      name\n      time\n      ttl\n      Content\n      Classroom\n    }\n  }\n`;\nexport const onDeleteEngagementEvent = /* GraphQL */ `\n  subscription OnDeleteEngagementEvent {\n    onDeleteEngagementEvent {\n      id\n      createdAt\n      updatedAt\n      luid\n      name\n      time\n      ttl\n      Content\n      Classroom\n    }\n  }\n`;\nexport const onCreateLocalUsers = /* GraphQL */ `\n  subscription OnCreateLocalUsers {\n    onCreateLocalUsers {\n      id\n      content\n      createdAt\n      updatedAt\n      CurrentSession {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      CurrentSessionId\n      CurrentUserId\n      CurrentUser {\n        id\n        name\n        createdAt\n        updatedAt\n        SessionID\n        Session {\n          id\n          name\n          content\n          createdAt\n          updatedAt\n          ttl\n          savedOwner\n          parentID\n          pageNumber\n          boardConfig\n          parentBoardID\n          folderID\n          Classroom\n          CreatorLocalID\n          isGroup\n          joinCode\n          TenantID\n          deleted\n          TutorClass\n        }\n        content\n        UserProfile\n        ttl\n        avatar\n      }\n      ClassroomID\n      ttl\n      deleted\n    }\n  }\n`;\nexport const onUpdateLocalUsers = /* GraphQL */ `\n  subscription OnUpdateLocalUsers {\n    onUpdateLocalUsers {\n      id\n      content\n      createdAt\n      updatedAt\n      CurrentSession {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      CurrentSessionId\n      CurrentUserId\n      CurrentUser {\n        id\n        name\n        createdAt\n        updatedAt\n        SessionID\n        Session {\n          id\n          name\n          content\n          createdAt\n          updatedAt\n          ttl\n          savedOwner\n          parentID\n          pageNumber\n          boardConfig\n          parentBoardID\n          folderID\n          Classroom\n          CreatorLocalID\n          isGroup\n          joinCode\n          TenantID\n          deleted\n          TutorClass\n        }\n        content\n        UserProfile\n        ttl\n        avatar\n      }\n      ClassroomID\n      ttl\n      deleted\n    }\n  }\n`;\nexport const onDeleteLocalUsers = /* GraphQL */ `\n  subscription OnDeleteLocalUsers {\n    onDeleteLocalUsers {\n      id\n      content\n      createdAt\n      updatedAt\n      CurrentSession {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      CurrentSessionId\n      CurrentUserId\n      CurrentUser {\n        id\n        name\n        createdAt\n        updatedAt\n        SessionID\n        Session {\n          id\n          name\n          content\n          createdAt\n          updatedAt\n          ttl\n          savedOwner\n          parentID\n          pageNumber\n          boardConfig\n          parentBoardID\n          folderID\n          Classroom\n          CreatorLocalID\n          isGroup\n          joinCode\n          TenantID\n          deleted\n          TutorClass\n        }\n        content\n        UserProfile\n        ttl\n        avatar\n      }\n      ClassroomID\n      ttl\n      deleted\n    }\n  }\n`;\nexport const onCreateMultiBoard = /* GraphQL */ `\n  subscription OnCreateMultiBoard {\n    onCreateMultiBoard {\n      id\n      parentBoardID\n      parentBoard {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      childBoardID\n      childBoard {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      ttl\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const onUpdateMultiBoard = /* GraphQL */ `\n  subscription OnUpdateMultiBoard {\n    onUpdateMultiBoard {\n      id\n      parentBoardID\n      parentBoard {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      childBoardID\n      childBoard {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      ttl\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const onDeleteMultiBoard = /* GraphQL */ `\n  subscription OnDeleteMultiBoard {\n    onDeleteMultiBoard {\n      id\n      parentBoardID\n      parentBoard {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      childBoardID\n      childBoard {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      ttl\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const onCreateObject = /* GraphQL */ `\n  subscription OnCreateObject {\n    onCreateObject {\n      id\n      name\n      content\n      type\n      objType\n      ended\n      createdAt\n      updatedAt\n      SessionID\n      ttl\n      animate\n      CreatedBy\n      CreatorLocalID\n      DisableSync\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      deleted\n    }\n  }\n`;\nexport const onUpdateObject = /* GraphQL */ `\n  subscription OnUpdateObject {\n    onUpdateObject {\n      id\n      name\n      content\n      type\n      objType\n      ended\n      createdAt\n      updatedAt\n      SessionID\n      ttl\n      animate\n      CreatedBy\n      CreatorLocalID\n      DisableSync\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      deleted\n    }\n  }\n`;\nexport const onDeleteObject = /* GraphQL */ `\n  subscription OnDeleteObject {\n    onDeleteObject {\n      id\n      name\n      content\n      type\n      objType\n      ended\n      createdAt\n      updatedAt\n      SessionID\n      ttl\n      animate\n      CreatedBy\n      CreatorLocalID\n      DisableSync\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      deleted\n    }\n  }\n`;\nexport const onCreateTeam = /* GraphQL */ `\n  subscription OnCreateTeam {\n    onCreateTeam {\n      id\n      name\n      TenantID\n      Members\n      Config\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const onUpdateTeam = /* GraphQL */ `\n  subscription OnUpdateTeam {\n    onUpdateTeam {\n      id\n      name\n      TenantID\n      Members\n      Config\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const onDeleteTeam = /* GraphQL */ `\n  subscription OnDeleteTeam {\n    onDeleteTeam {\n      id\n      name\n      TenantID\n      Members\n      Config\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const onCreateUserProfile = /* GraphQL */ `\n  subscription OnCreateUserProfile {\n    onCreateUserProfile {\n      id\n      name\n      createdAt\n      updatedAt\n      email\n      boardConfig\n      avatar\n      personalConfig\n      emailOptIn\n      paidPlan\n      validTeacher\n      adminOfTenant\n      TenantID\n      FEMStatus\n      lastVisitedSubs\n      MemberOfTeam\n      TutorGroupID\n    }\n  }\n`;\nexport const onUpdateUserProfile = /* GraphQL */ `\n  subscription OnUpdateUserProfile {\n    onUpdateUserProfile {\n      id\n      name\n      createdAt\n      updatedAt\n      email\n      boardConfig\n      avatar\n      personalConfig\n      emailOptIn\n      paidPlan\n      validTeacher\n      adminOfTenant\n      TenantID\n      FEMStatus\n      lastVisitedSubs\n      MemberOfTeam\n      TutorGroupID\n    }\n  }\n`;\nexport const onDeleteUserProfile = /* GraphQL */ `\n  subscription OnDeleteUserProfile {\n    onDeleteUserProfile {\n      id\n      name\n      createdAt\n      updatedAt\n      email\n      boardConfig\n      avatar\n      personalConfig\n      emailOptIn\n      paidPlan\n      validTeacher\n      adminOfTenant\n      TenantID\n      FEMStatus\n      lastVisitedSubs\n      MemberOfTeam\n      TutorGroupID\n    }\n  }\n`;\nexport const onCreateTutorGroup = /* GraphQL */ `\n  subscription OnCreateTutorGroup {\n    onCreateTutorGroup {\n      id\n      name\n      createdAt\n      updatedAt\n      config\n      roster\n      creator\n      TenantID\n      tutorClasses {\n        items {\n          id\n          name\n          description\n          videoMode\n          createdAt\n          updatedAt\n          config\n          roster\n          TutorGroupID\n          Sessions\n        }\n        nextToken\n      }\n    }\n  }\n`;\nexport const onUpdateTutorGroup = /* GraphQL */ `\n  subscription OnUpdateTutorGroup {\n    onUpdateTutorGroup {\n      id\n      name\n      createdAt\n      updatedAt\n      config\n      roster\n      creator\n      TenantID\n      tutorClasses {\n        items {\n          id\n          name\n          description\n          videoMode\n          createdAt\n          updatedAt\n          config\n          roster\n          TutorGroupID\n          Sessions\n        }\n        nextToken\n      }\n    }\n  }\n`;\nexport const onDeleteTutorGroup = /* GraphQL */ `\n  subscription OnDeleteTutorGroup {\n    onDeleteTutorGroup {\n      id\n      name\n      createdAt\n      updatedAt\n      config\n      roster\n      creator\n      TenantID\n      tutorClasses {\n        items {\n          id\n          name\n          description\n          videoMode\n          createdAt\n          updatedAt\n          config\n          roster\n          TutorGroupID\n          Sessions\n        }\n        nextToken\n      }\n    }\n  }\n`;\nexport const onCreateTutorClass = /* GraphQL */ `\n  subscription OnCreateTutorClass {\n    onCreateTutorClass {\n      id\n      name\n      description\n      videoMode\n      createdAt\n      updatedAt\n      config\n      roster\n      TutorGroupID\n      TutorGroup {\n        id\n        name\n        createdAt\n        updatedAt\n        config\n        roster\n        creator\n        TenantID\n        tutorClasses {\n          nextToken\n        }\n      }\n      Sessions\n      TutorClassEvents {\n        items {\n          id\n          createdAt\n          updatedAt\n          config\n          type\n          TutorGroupID\n          TutorClassID\n        }\n        nextToken\n      }\n    }\n  }\n`;\nexport const onUpdateTutorClass = /* GraphQL */ `\n  subscription OnUpdateTutorClass {\n    onUpdateTutorClass {\n      id\n      name\n      description\n      videoMode\n      createdAt\n      updatedAt\n      config\n      roster\n      TutorGroupID\n      TutorGroup {\n        id\n        name\n        createdAt\n        updatedAt\n        config\n        roster\n        creator\n        TenantID\n        tutorClasses {\n          nextToken\n        }\n      }\n      Sessions\n      TutorClassEvents {\n        items {\n          id\n          createdAt\n          updatedAt\n          config\n          type\n          TutorGroupID\n          TutorClassID\n        }\n        nextToken\n      }\n    }\n  }\n`;\nexport const onDeleteTutorClass = /* GraphQL */ `\n  subscription OnDeleteTutorClass {\n    onDeleteTutorClass {\n      id\n      name\n      description\n      videoMode\n      createdAt\n      updatedAt\n      config\n      roster\n      TutorGroupID\n      TutorGroup {\n        id\n        name\n        createdAt\n        updatedAt\n        config\n        roster\n        creator\n        TenantID\n        tutorClasses {\n          nextToken\n        }\n      }\n      Sessions\n      TutorClassEvents {\n        items {\n          id\n          createdAt\n          updatedAt\n          config\n          type\n          TutorGroupID\n          TutorClassID\n        }\n        nextToken\n      }\n    }\n  }\n`;\nexport const onCreateTutorClassEvent = /* GraphQL */ `\n  subscription OnCreateTutorClassEvent {\n    onCreateTutorClassEvent {\n      id\n      createdAt\n      updatedAt\n      config\n      type\n      TutorGroupID\n      TutorGroup {\n        id\n        name\n        createdAt\n        updatedAt\n        config\n        roster\n        creator\n        TenantID\n        tutorClasses {\n          nextToken\n        }\n      }\n      TutorClassID\n      TutorClass {\n        id\n        name\n        description\n        videoMode\n        createdAt\n        updatedAt\n        config\n        roster\n        TutorGroupID\n        TutorGroup {\n          id\n          name\n          createdAt\n          updatedAt\n          config\n          roster\n          creator\n          TenantID\n        }\n        Sessions\n        TutorClassEvents {\n          nextToken\n        }\n      }\n    }\n  }\n`;\nexport const onUpdateTutorClassEvent = /* GraphQL */ `\n  subscription OnUpdateTutorClassEvent {\n    onUpdateTutorClassEvent {\n      id\n      createdAt\n      updatedAt\n      config\n      type\n      TutorGroupID\n      TutorGroup {\n        id\n        name\n        createdAt\n        updatedAt\n        config\n        roster\n        creator\n        TenantID\n        tutorClasses {\n          nextToken\n        }\n      }\n      TutorClassID\n      TutorClass {\n        id\n        name\n        description\n        videoMode\n        createdAt\n        updatedAt\n        config\n        roster\n        TutorGroupID\n        TutorGroup {\n          id\n          name\n          createdAt\n          updatedAt\n          config\n          roster\n          creator\n          TenantID\n        }\n        Sessions\n        TutorClassEvents {\n          nextToken\n        }\n      }\n    }\n  }\n`;\nexport const onDeleteTutorClassEvent = /* GraphQL */ `\n  subscription OnDeleteTutorClassEvent {\n    onDeleteTutorClassEvent {\n      id\n      createdAt\n      updatedAt\n      config\n      type\n      TutorGroupID\n      TutorGroup {\n        id\n        name\n        createdAt\n        updatedAt\n        config\n        roster\n        creator\n        TenantID\n        tutorClasses {\n          nextToken\n        }\n      }\n      TutorClassID\n      TutorClass {\n        id\n        name\n        description\n        videoMode\n        createdAt\n        updatedAt\n        config\n        roster\n        TutorGroupID\n        TutorGroup {\n          id\n          name\n          createdAt\n          updatedAt\n          config\n          roster\n          creator\n          TenantID\n        }\n        Sessions\n        TutorClassEvents {\n          nextToken\n        }\n      }\n    }\n  }\n`;\nexport const onCreateFrequentEngagementMin = /* GraphQL */ `\n  subscription OnCreateFrequentEngagementMin {\n    onCreateFrequentEngagementMin {\n      id\n      name\n      AvatarName\n      Public\n      Minutes\n      Rating\n      Ranking\n      Content\n      TierQualifingPoints\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const onUpdateFrequentEngagementMin = /* GraphQL */ `\n  subscription OnUpdateFrequentEngagementMin {\n    onUpdateFrequentEngagementMin {\n      id\n      name\n      AvatarName\n      Public\n      Minutes\n      Rating\n      Ranking\n      Content\n      TierQualifingPoints\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const onDeleteFrequentEngagementMin = /* GraphQL */ `\n  subscription OnDeleteFrequentEngagementMin {\n    onDeleteFrequentEngagementMin {\n      id\n      name\n      AvatarName\n      Public\n      Minutes\n      Rating\n      Ranking\n      Content\n      TierQualifingPoints\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const onCreateApiInfo = /* GraphQL */ `\n  subscription OnCreateApiInfo {\n    onCreateApiInfo {\n      id\n      key\n      content\n      count\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const onUpdateApiInfo = /* GraphQL */ `\n  subscription OnUpdateApiInfo {\n    onUpdateApiInfo {\n      id\n      key\n      content\n      count\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const onDeleteApiInfo = /* GraphQL */ `\n  subscription OnDeleteApiInfo {\n    onDeleteApiInfo {\n      id\n      key\n      content\n      count\n      createdAt\n      updatedAt\n    }\n  }\n`;\nexport const onCreatePersonalPalette = /* GraphQL */ `\n  subscription OnCreatePersonalPalette {\n    onCreatePersonalPalette {\n      id\n      createdAt\n      updatedAt\n      path\n      owner\n      name\n      content\n    }\n  }\n`;\nexport const onUpdatePersonalPalette = /* GraphQL */ `\n  subscription OnUpdatePersonalPalette {\n    onUpdatePersonalPalette {\n      id\n      createdAt\n      updatedAt\n      path\n      owner\n      name\n      content\n    }\n  }\n`;\nexport const onDeletePersonalPalette = /* GraphQL */ `\n  subscription OnDeletePersonalPalette {\n    onDeletePersonalPalette {\n      id\n      createdAt\n      updatedAt\n      path\n      owner\n      name\n      content\n    }\n  }\n`;\nexport const onCreateCommunityPalette = /* GraphQL */ `\n  subscription OnCreateCommunityPalette {\n    onCreateCommunityPalette {\n      id\n      createdAt\n      updatedAt\n      path\n      owner\n      name\n      content\n    }\n  }\n`;\nexport const onUpdateCommunityPalette = /* GraphQL */ `\n  subscription OnUpdateCommunityPalette {\n    onUpdateCommunityPalette {\n      id\n      createdAt\n      updatedAt\n      path\n      owner\n      name\n      content\n    }\n  }\n`;\nexport const onDeleteCommunityPalette = /* GraphQL */ `\n  subscription OnDeleteCommunityPalette {\n    onDeleteCommunityPalette {\n      id\n      createdAt\n      updatedAt\n      path\n      owner\n      name\n      content\n    }\n  }\n`;\nexport const onCreateUser = /* GraphQL */ `\n  subscription OnCreateUser {\n    onCreateUser {\n      id\n      name\n      createdAt\n      updatedAt\n      SessionID\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      content\n      UserProfile\n      ttl\n      avatar\n    }\n  }\n`;\nexport const onUpdateUser = /* GraphQL */ `\n  subscription OnUpdateUser {\n    onUpdateUser {\n      id\n      name\n      createdAt\n      updatedAt\n      SessionID\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      content\n      UserProfile\n      ttl\n      avatar\n    }\n  }\n`;\nexport const onDeleteUser = /* GraphQL */ `\n  subscription OnDeleteUser {\n    onDeleteUser {\n      id\n      name\n      createdAt\n      updatedAt\n      SessionID\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      content\n      UserProfile\n      ttl\n      avatar\n    }\n  }\n`;\nexport const onCreateErrorLog = /* GraphQL */ `\n  subscription OnCreateErrorLog {\n    onCreateErrorLog {\n      id\n      name\n      createdAt\n      updatedAt\n      content\n      ttl\n    }\n  }\n`;\nexport const onUpdateErrorLog = /* GraphQL */ `\n  subscription OnUpdateErrorLog {\n    onUpdateErrorLog {\n      id\n      name\n      createdAt\n      updatedAt\n      content\n      ttl\n    }\n  }\n`;\nexport const onDeleteErrorLog = /* GraphQL */ `\n  subscription OnDeleteErrorLog {\n    onDeleteErrorLog {\n      id\n      name\n      createdAt\n      updatedAt\n      content\n      ttl\n    }\n  }\n`;\nexport const onCreateFolder = /* GraphQL */ `\n  subscription OnCreateFolder {\n    onCreateFolder {\n      id\n      name\n      createdAt\n      updatedAt\n      userProfileId\n      user {\n        id\n        name\n        createdAt\n        updatedAt\n        email\n        boardConfig\n        avatar\n        personalConfig\n        emailOptIn\n        paidPlan\n        validTeacher\n        adminOfTenant\n        TenantID\n        FEMStatus\n        lastVisitedSubs\n        MemberOfTeam\n        TutorGroupID\n      }\n      parentFolderPath\n    }\n  }\n`;\nexport const onUpdateFolder = /* GraphQL */ `\n  subscription OnUpdateFolder {\n    onUpdateFolder {\n      id\n      name\n      createdAt\n      updatedAt\n      userProfileId\n      user {\n        id\n        name\n        createdAt\n        updatedAt\n        email\n        boardConfig\n        avatar\n        personalConfig\n        emailOptIn\n        paidPlan\n        validTeacher\n        adminOfTenant\n        TenantID\n        FEMStatus\n        lastVisitedSubs\n        MemberOfTeam\n        TutorGroupID\n      }\n      parentFolderPath\n    }\n  }\n`;\nexport const onDeleteFolder = /* GraphQL */ `\n  subscription OnDeleteFolder {\n    onDeleteFolder {\n      id\n      name\n      createdAt\n      updatedAt\n      userProfileId\n      user {\n        id\n        name\n        createdAt\n        updatedAt\n        email\n        boardConfig\n        avatar\n        personalConfig\n        emailOptIn\n        paidPlan\n        validTeacher\n        adminOfTenant\n        TenantID\n        FEMStatus\n        lastVisitedSubs\n        MemberOfTeam\n        TutorGroupID\n      }\n      parentFolderPath\n    }\n  }\n`;\nexport const onCreateServiceNotice = /* GraphQL */ `\n  subscription OnCreateServiceNotice {\n    onCreateServiceNotice {\n      id\n      createdAt\n      updatedAt\n      noticeConfig\n    }\n  }\n`;\nexport const onUpdateServiceNotice = /* GraphQL */ `\n  subscription OnUpdateServiceNotice {\n    onUpdateServiceNotice {\n      id\n      createdAt\n      updatedAt\n      noticeConfig\n    }\n  }\n`;\nexport const onDeleteServiceNotice = /* GraphQL */ `\n  subscription OnDeleteServiceNotice {\n    onDeleteServiceNotice {\n      id\n      createdAt\n      updatedAt\n      noticeConfig\n    }\n  }\n`;\nexport const onCreateLatencyEndPoints = /* GraphQL */ `\n  subscription OnCreateLatencyEndPoints {\n    onCreateLatencyEndPoints {\n      id\n      createdAt\n      updatedAt\n      region\n      content\n    }\n  }\n`;\nexport const onUpdateLatencyEndPoints = /* GraphQL */ `\n  subscription OnUpdateLatencyEndPoints {\n    onUpdateLatencyEndPoints {\n      id\n      createdAt\n      updatedAt\n      region\n      content\n    }\n  }\n`;\nexport const onDeleteLatencyEndPoints = /* GraphQL */ `\n  subscription OnDeleteLatencyEndPoints {\n    onDeleteLatencyEndPoints {\n      id\n      createdAt\n      updatedAt\n      region\n      content\n    }\n  }\n`;\nexport const onCreateRemoteControl = /* GraphQL */ `\n  subscription OnCreateRemoteControl {\n    onCreateRemoteControl {\n      id\n      parentID\n      ttl\n      createdAt\n      updatedAt\n      content\n    }\n  }\n`;\nexport const onUpdateRemoteControl = /* GraphQL */ `\n  subscription OnUpdateRemoteControl {\n    onUpdateRemoteControl {\n      id\n      parentID\n      ttl\n      createdAt\n      updatedAt\n      content\n    }\n  }\n`;\nexport const onDeleteRemoteControl = /* GraphQL */ `\n  subscription OnDeleteRemoteControl {\n    onDeleteRemoteControl {\n      id\n      parentID\n      ttl\n      createdAt\n      updatedAt\n      content\n    }\n  }\n`;\nexport const onCreateLatencyCalculation = /* GraphQL */ `\n  subscription OnCreateLatencyCalculation {\n    onCreateLatencyCalculation {\n      id\n      createdAt\n      updatedAt\n      region\n      clientRegion\n      content\n    }\n  }\n`;\nexport const onUpdateLatencyCalculation = /* GraphQL */ `\n  subscription OnUpdateLatencyCalculation {\n    onUpdateLatencyCalculation {\n      id\n      createdAt\n      updatedAt\n      region\n      clientRegion\n      content\n    }\n  }\n`;\nexport const onDeleteLatencyCalculation = /* GraphQL */ `\n  subscription OnDeleteLatencyCalculation {\n    onDeleteLatencyCalculation {\n      id\n      createdAt\n      updatedAt\n      region\n      clientRegion\n      content\n    }\n  }\n`;\nexport const onCreateTenant = /* GraphQL */ `\n  subscription OnCreateTenant {\n    onCreateTenant {\n      id\n      name\n      domainName\n      createdAt\n      updatedAt\n      entitlements\n      adminUsers\n      tenantConfig\n      secondaryDomainConfig\n      licensedUsers {\n        items {\n          id\n          name\n          createdAt\n          updatedAt\n          email\n          boardConfig\n          avatar\n          personalConfig\n          emailOptIn\n          paidPlan\n          validTeacher\n          adminOfTenant\n          TenantID\n          FEMStatus\n          lastVisitedSubs\n          MemberOfTeam\n          TutorGroupID\n        }\n        nextToken\n      }\n    }\n  }\n`;\nexport const onUpdateTenant = /* GraphQL */ `\n  subscription OnUpdateTenant {\n    onUpdateTenant {\n      id\n      name\n      domainName\n      createdAt\n      updatedAt\n      entitlements\n      adminUsers\n      tenantConfig\n      secondaryDomainConfig\n      licensedUsers {\n        items {\n          id\n          name\n          createdAt\n          updatedAt\n          email\n          boardConfig\n          avatar\n          personalConfig\n          emailOptIn\n          paidPlan\n          validTeacher\n          adminOfTenant\n          TenantID\n          FEMStatus\n          lastVisitedSubs\n          MemberOfTeam\n          TutorGroupID\n        }\n        nextToken\n      }\n    }\n  }\n`;\nexport const onDeleteTenant = /* GraphQL */ `\n  subscription OnDeleteTenant {\n    onDeleteTenant {\n      id\n      name\n      domainName\n      createdAt\n      updatedAt\n      entitlements\n      adminUsers\n      tenantConfig\n      secondaryDomainConfig\n      licensedUsers {\n        items {\n          id\n          name\n          createdAt\n          updatedAt\n          email\n          boardConfig\n          avatar\n          personalConfig\n          emailOptIn\n          paidPlan\n          validTeacher\n          adminOfTenant\n          TenantID\n          FEMStatus\n          lastVisitedSubs\n          MemberOfTeam\n          TutorGroupID\n        }\n        nextToken\n      }\n    }\n  }\n`;\nexport const onCreateVideoRoom = /* GraphQL */ `\n  subscription OnCreateVideoRoom {\n    onCreateVideoRoom {\n      id\n      SID\n      name\n      createdAt\n      updatedAt\n      state\n      url\n      content\n      SessionID\n      recordingTurnedOn\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      ttl\n    }\n  }\n`;\nexport const onUpdateVideoRoom = /* GraphQL */ `\n  subscription OnUpdateVideoRoom {\n    onUpdateVideoRoom {\n      id\n      SID\n      name\n      createdAt\n      updatedAt\n      state\n      url\n      content\n      SessionID\n      recordingTurnedOn\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      ttl\n    }\n  }\n`;\nexport const onDeleteVideoRoom = /* GraphQL */ `\n  subscription OnDeleteVideoRoom {\n    onDeleteVideoRoom {\n      id\n      SID\n      name\n      createdAt\n      updatedAt\n      state\n      url\n      content\n      SessionID\n      recordingTurnedOn\n      Session {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        folderID\n        Classroom\n        CreatorLocalID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n        joinCode\n        TenantID\n        deleted\n        TutorClass\n      }\n      ttl\n    }\n  }\n`;\n","export const queryByParent = /* GraphQL */ `\n  query QueryByParent(\n    $parentID: ID\n    $pageNumber: ModelIntKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelSessionFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    queryByParent(\n      parentID: $parentID\n      pageNumber: $pageNumber\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          items {\n            id\n            name\n            createdAt\n            updatedAt\n            SessionID\n            content\n            UserProfile\n            ttl\n            avatar\n          }\n          nextToken      \n        }\n        parentBoardID\n        Classroom\n        CreatorLocalID\n        folderID\n        MultiBoard {\n          nextToken\n        }\n        isGroup\n      }\n      nextToken\n    }\n  }\n`;\nexport const queryByClassroom = /* GraphQL */ `\nquery QueryByClassroom(\n  $Classroom: ID\n  $createdAt: ModelStringKeyConditionInput\n  $sortDirection: ModelSortDirection\n  $filter: ModelSessionFilterInput\n  $limit: Int\n  $nextToken: String\n) {\n  queryByClassroom(\n    Classroom: $Classroom\n    createdAt: $createdAt\n    sortDirection: $sortDirection\n    filter: $filter\n    limit: $limit\n    nextToken: $nextToken\n  ) {\n    items {\n      id\n      name\n      content\n      createdAt\n      updatedAt\n      Objects {\n        nextToken\n      }\n      ttl\n      savedOwner\n      parentID\n      pageNumber\n      boardConfig\n      Users {\n        items {\n          id\n          name\n          createdAt\n          updatedAt\n          SessionID\n          content\n          UserProfile\n          ttl\n          avatar\n        }\n        nextToken      \n      }\n      parentBoardID\n      Classroom\n      CreatorLocalID\n      folderID\n      MultiBoard {\n        nextToken\n      }\n      isGroup\n    }\n    nextToken\n  }\n}\n`;\n\nexport const queryBySavedOwner = /* GraphQL */ `\n  query QueryBySavedOwner(\n    $savedOwner: ID\n    $updatedAt: ModelStringKeyConditionInput\n    $sortDirection: ModelSortDirection\n    $filter: ModelSessionFilterInput\n    $limit: Int\n    $nextToken: String\n  ) {\n    queryBySavedOwner(\n      savedOwner: $savedOwner\n      updatedAt: $updatedAt\n      sortDirection: $sortDirection\n      filter: $filter\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items {\n        id\n        name\n        content\n        createdAt\n        updatedAt\n        Objects {\n          nextToken\n        }\n        ttl\n        savedOwner\n        parentID\n        pageNumber\n        boardConfig\n        Users {\n          nextToken\n        }\n        parentBoardID\n        Classroom\n        CreatorLocalID\n        folderID\n        MultiBoard {\n            items {\n                id\n                parentBoardID\n                childBoardID\n                createdAt\n                updatedAt\n            }\n            nextToken\n        }\n      }\n      nextToken\n    }\n  }\n`;\n\nexport const queryByJoinCode = /* GraphQL */ `\n  query QueryByJoinCode($joinCode: ID) {\n    queryByJoinCode(joinCode: $joinCode) {\n      items {\n        id\n        createdAt\n        joinCode\n      }\n      nextToken\n    }\n  }\n`;\n\nexport const queryByTenantName = /* GraphQL */ `\n  query QueryByTenantName(\n    $name: String\n    $limit: Int\n    $nextToken: String\n  ) {\n    queryByTenantName(\n      name: $name\n      limit: $limit\n      nextToken: $nextToken\n    ) {\n      items{\n        id\n        name\n        domainName\n        createdAt\n      }\n      nextToken\n    }\n  }\n`;\n\n","import * as autoQuery from './graphql/queries'\nimport * as autoMutation from './graphql/mutations'\nimport * as autoSub from './graphql/subscriptions'\nimport * as customops from './graphql/customops'\nimport * as WBCReactGA from './WBCReactGA';\n\nimport { API, graphqlOperation } from 'aws-amplify';\nimport { v4 as uuid } from \"uuid\";\nimport { Auth } from 'aws-amplify';\nimport pako from 'pako'\nimport * as mylocalStorage from \"./mylocalStorage\";\nimport { copyFile } from './ImageUtils';\nimport * as uUtils from './UsersUtils'\nimport { CacheDraw } from \"./CacheDraw\"\nimport { LocalDB } from \"./LocalDB\";\nconst OBS = process.env.REACT_APP_OBS\nvar gProfiles = {}\n\n// 946684800 = 1/1/2000 start of day\n// AWS TTL mechanism will ignore items with expiry more than 5 years ago.\n// Using 950000000 so it is easy to identify in ddb.\n// 950000000 = Tuesday, February 8, 2000 8:53:20 AM GMT\nexport const NO_EXPIRY_TTL = 950000000\nexport const MAX_SAVED_BOARDS_BASIC_PAID_PLAN = 20;\nvar dispatchCB = null\nexport function setDispatchCB(fn) {\n    dispatchCB = fn\n}\nfunction callDispatch(data) {\n    if (dispatchCB) {\n        dispatchCB(data)\n    }\n}\n\nfunction getDelTTL() {\n    const secondsSinceEpoch = Math.round(Date.now() / 1000);\n    const expirationTime = secondsSinceEpoch + 30; //expire in 30 seconds\n    return expirationTime\n}\nfunction getTTL() {\n    var paidUserPlan = userPaidPlan();\n    if ((Auth && Auth.user) || paidUserPlan) {\n        if (uUtils.userHasNoBoardExpiry() || paidUserPlan && (paidUserPlan === \"gold\" || paidUserPlan === \"goldannual\")) {\n            return NO_EXPIRY_TTL\n        }\n        if (!paidUserPlan || paidUserPlan === 'educator-free') {\n            return getTTLForDays(7)\n        }\n        return getTTL2Week()\n    }\n    return getTTL2Week()\n    // const secondsSinceEpoch = Math.round(Date.now() / 1000);\n    // const SECONDS_IN_AN_HOUR = 60 * 60;\n    // const expirationTime = secondsSinceEpoch + 8 * SECONDS_IN_AN_HOUR; //expire in 8 hours \n    // return expirationTime\n}\n\nfunction getTTL3Days() {\n    const secondsSinceEpoch = Math.round(Date.now() / 1000);\n    const SECONDS_IN_AN_HOUR = 60 * 60;\n    const HOURS_IN_3_DAYS = 24 * 3\n    const expirationTime = secondsSinceEpoch + 3 * SECONDS_IN_AN_HOUR * HOURS_IN_3_DAYS; //expire in 3 hours \n    return expirationTime\n}\n\nconst wait = ms => new Promise(r => setTimeout(r, ms));\nexport const MAX_RETRY_COUNT = 2;\nexport const RETRY_DELAY = 500; // 0.5 second in milliseconds.\nconst SUB_RETRY_DELAY = 3000; // 3 seconds in milliseconds\nconst SUB_MAX_RETRY_COUNT = 3;\nconst MAX_RELOAD_TIMEOUT = 900; // 15 Mins (in secs)\nconst s3HostPattern = /^https:\\/\\/[\\w-]+.s3.[\\w-]+.amazonaws.com/i;\nconst s3UrlPattern = /https:\\/\\/[\\w-]+.s3.[\\w-]+.amazonaws.com\\/public\\/(images|paidImages)\\/[\\w-]+.\\w+/gi;\n\nfunction handleCommonErrors(errStr, gaAction, context) {\n    var dt = Math.floor(Date.now().valueOf() / 1000)\n    var timeSet = mylocalStorage.getItem('maxSubReloadTime')\n\n    if (!timeSet || ((dt - timeSet) > MAX_RELOAD_TIMEOUT)) {\n        let msidx = errStr.indexOf('MaxSubscriptionsReachedError');\n        if (msidx !== -1) {\n            mylocalStorage.setItem('maxSubReloadTime', dt)\n            sendWBCReactGAEvent(\"MAX_SUBCRIPTION_ERROR\", gaAction,\n                errStr, context.retryCount);\n            // Hit MaxSubscriptions error, reload the page...\n            windowreload();\n            return true;\n        }\n    }\n\n    return false;\n}\n\nfunction checkAndReSubscribe(retried, gaAction, errorObj,\n    unSubObj, subFunc, context) {\n    if (retried) return;\n    context.retryCount -= 1;\n\n    let errStr = getErrorString(errorObj);\n    if (handleCommonErrors(errStr, gaAction, context)) return;\n\n    if (context.retryCount >= (SUB_MAX_RETRY_COUNT - 1)) {\n        sendWBCReactGAEvent(\"SUBCRIPTION_ERROR\", gaAction,\n            errStr, context.retryCount);\n    }\n    if (!(context.retryCount > 0)) {\n        sendWBCReactGAEvent(\"SUBCRIPTION_ERROR_GIVEUP\", gaAction,\n            errStr, context.retryCount);\n        //disconnected\n        callDispatch({ msg: \"NETWORK ERROR 1: Please Click refresh to re-connect\", sev: \"error\", button: \"Refresh\", timeout: 20000 })\n        return;\n    }\n    try {\n        if (unSubObj) unSubObj.unsubscribe();\n    } catch (e) {\n        // Ignore error\n    }\n    context.doList = false;\n    wait(SUB_RETRY_DELAY).then(() => {\n        subFunc(context);\n    });\n}\n\n// label has the actual error string\nfunction sendWBCReactGAEvent(category, label, action, value) {\n    let msg = {\n        category: category,\n        // action cannot be more than 500 characters\n        action: action.slice(0, 499)\n    }\n\n    if (label) msg.label = label.slice(0, 499);\n    if (value) msg.value = value\n\n    WBCReactGA.event(msg);\n}\n\nexport function getErrorString(error) {\n    let errArr = null;\n    let errStr = \"\";\n\n    if (error.errors) {\n        errArr = error.errors;\n    } else if (error.error && error.error.errors) {\n        errArr = error.error.errors;\n    } else if (error.stack && typeof error.stack === \"string\") {\n        let tmpIdx = error.stack.indexOf('\\n');\n        if (tmpIdx !== -1) errStr = error.stack.slice(0, tmpIdx);\n    } else if (error.message) {\n        errStr = error.message;\n    }\n\n    if (errArr) {\n        for (let idx in errArr) {\n            let item = errArr[idx];\n\n            if (item.errorType && item.message) {\n                errStr = `${item.errorType}: ${item.message}`\n            } else if (item.message) {\n                errStr = item.message\n            } else if (item.errorType) {\n                errStr = item.errorType\n            }\n\n            if (errStr !== \"\") break;\n        }\n    }\n\n    if (errStr === \"\") errStr = \"getErrorString: Could not parse error\"\n\n    // replace \"@\" symbol from error string b/c WBCReactGA gets confused\n    // and thinks that there is an email and redacts the whole error string\n    return errStr.replace(\"@\", \"--\");\n}\n\n// var subCount = 0\nclass Sub {\n    constructor(subObj, subArgs, subAction) {\n        this.subsciption = null\n        this.subObj = subObj\n        this.subArgs = subArgs\n        this.subAction = subAction\n    }\n\n    reallySubscribe() {\n        // subCount++\n        if (this.subsciption) {\n            this.unsubscribe()\n        }\n        this.subsciption = trySubscribeReal(this.subObj, this.subArgs, this.subAction)\n    }\n    setSubscription(subs) {\n        this.subsciption = subs\n    }\n\n    unsubscribe() {\n        // subCount--\n        if (this.subsciption) {\n            this.subsciption.unsubscribe()\n            this.subsciption = null\n        }\n    }\n}\n\nfunction trySubscribe(subObj, subArgs, subAction) {\n    let n = new Sub(subObj, subArgs, subAction)\n    n.reallySubscribe()\n\n    return n\n}\n\nfunction trySubscribeReal(subObj, subArgs, subAction) {\n    var sub = null;\n    try {\n        sub = subObj.subscribe(subArgs)\n    } catch (error) {\n        sendWBCReactGAEvent(\"TRY_SUBCRIPTION_ERROR\", subAction,\n            getErrorString(error));\n        console.log(\"trySubscribe: got error:\", error);\n    }\n\n    return sub;\n}\n\nexport function getQueryName(query) {\n    let q1 = query.replace(/^\\s+/g, '');\n    let q2;\n    try {\n        q2 = q1.split('(')[0]\n        return q2.split(\" \")[1]\n    } catch (e) {\n        // Ignore error\n    }\n\n    let errIdx = q1.indexOf(\"\\n\");\n    return (errIdx !== -1) ? q1.slice(0, errIdx) : query.slice(0, 20);\n}\n\n// based on: https://stackoverflow.com/questions/38213668/promise-retry-design-patterns\n// answer by: Yair Kukielka\nconst gqlOperationWithRetry = (query, args, delay, retryCount) => new Promise((resolve, reject) => {\n    if ((delay === null) || (delay === undefined)) delay = RETRY_DELAY;\n    if ((retryCount === null) || (retryCount === undefined)) retryCount = MAX_RETRY_COUNT;\n    //console.log(\"gqlOperationWithRetry:\", args);\n    return API.graphql(graphqlOperation(query, args))\n        .then(resolve)\n        .catch((error) => {\n            let errStr = getErrorString(error);\n            let qStr = getQueryName(query);\n            console.log(\"gqlOperationWithRetry:\", error, args);\n            try {\n                let doRetry = true;\n                if ((\"errors\" in error) && Array.isArray(error.errors)) {\n                    for (let idx in error.errors) {\n                        if (error.errors[idx].errorType === \"DynamoDB:ConditionalCheckFailedException\") {\n                            doRetry = false;\n                            errStr = `DynamoDB:ConditionalCheckFailedException`\n                            qStr = `${qStr}: ${JSON.stringify(args)}`;\n                            break;\n                        }\n                        if (error.errors[idx].errorType === \"DynamoDB:DynamoDbException\") {\n                            doRetry = false;\n                            errStr = `DynamoDB:DynamoDbException`\n                            qStr = `${qStr}: ${JSON.stringify(args)}`;\n                            break;\n                        }\n                        // TODO: Add checks for more errors here.\n                    }\n                } else if (error.message || error.stack) {\n                    // Try to retry\n                } else {\n                    // Could not figure out the error type.\n                    doRetry = false;\n                }\n                if (doRetry) {\n                    // Check & Retry the API call\n                    retryCount = retryCount - 1;\n\n                    if (retryCount > 0) {\n                        if (retryCount >= (MAX_RETRY_COUNT - 1)) {\n                            sendWBCReactGAEvent(\"GQL_OPER_ERROR_RETRY\", qStr,\n                                errStr, retryCount);\n                        }\n                        return wait(delay)\n                            .then(gqlOperationWithRetry.bind(null, query, args, delay, retryCount))\n                            .then(resolve)\n                            .catch(reject);\n                    }\n                }\n            } catch (e) {\n                // got an error while processing API call error, just break out\n                sendWBCReactGAEvent(\"GQL_OPER_HANDLER_ERROR\", qStr,\n                    getErrorString(e), retryCount);\n                console.log(\"gqlOperationWithRetry: Got an error while processing API call error:\", e)\n            }\n\n            sendWBCReactGAEvent(retryCount ? \"GQL_OPER_ERROR\" : \"GQL_OPER_ERROR_GIVEUP\",\n                qStr, errStr, retryCount);\n            if (!retryCount) {\n                if (qStr && qStr.includes('Object')) {\n                    callDispatch({ msg: \"NETWORK ERROR 2: Please Click refresh to re-connect\", sev: \"error\", button: \"Refresh\", timeout: 20000 })\n                }\n            }\n            return reject(error);\n        })\n})\n\nfunction replaceChars(origStr, allowedLen, oneChar) {\n    let retStr = \"\";\n    if (origStr.length > allowedLen) {\n        let repLen = allowedLen / 2;\n\n        if (Math.floor(repLen) !== repLen) {\n            // It an odd number\n            repLen = Math.floor(repLen) - 2;\n            retStr = origStr.slice(0, repLen) + oneChar.repeat(5) + origStr.slice(origStr.length - repLen, origStr.length)\n        } else {\n            repLen = repLen - 2;\n            retStr = origStr.slice(0, repLen) + oneChar.repeat(4) + origStr.slice(origStr.length - repLen, origStr.length)\n        }\n    } else {\n        retStr = origStr;\n    }\n\n    return retStr;\n}\n\nexport function removeMSTeamsEmail(em) {\n    let email = em\n    if (em && email.includes(\"@microsoftteams\")) {\n        email = email.split(\"@\")[0]\n        email = email.replace(\"__\", \"@\")\n    }\n    return email\n}\n\nexport function getUserString(userName, userEmail) {\n    let MAX_EMAIL_LEN = 56;\n    if (userName && userEmail) {\n        try {\n            let socialLogin = \"\";\n            if (userName.startsWith(\"Google\")) {\n                socialLogin = \"(via Google)\"\n            } else if (userName.startsWith(\"Facebook\")) {\n                socialLogin = \"(via Facebook)\"\n            } else if (userName.startsWith(\"Microsoft\")) {\n                socialLogin = \"(via Microsoft)\"\n            }\n\n            let email = userEmail;\n            if (email && email.includes(\"@microsoftteams\")) {\n                socialLogin = \"(via Teams)\"\n                if (mylocalStorage.getItem('webex')) {\n                    socialLogin = \"(via Webex)\"\n\n                }\n                email = removeMSTeamsEmail(email)\n            }\n            // upto MAX_EMAIL_LEN chars show nicely in the dialog box\n            if (email.length > MAX_EMAIL_LEN) {\n                let sp = email.split(\"@\");\n                if ((sp[0].length > (MAX_EMAIL_LEN / 2)) &&\n                    (sp[1].length > (MAX_EMAIL_LEN / 2))) {\n                    // both parts (username and domain) are greater than MAX_EMAIL_LEN / 2\n                    email = replaceChars(sp[0], MAX_EMAIL_LEN / 2, '*') + '@' + replaceChars(sp[1], MAX_EMAIL_LEN / 2, '*');\n                } else if ((sp[0].length > (MAX_EMAIL_LEN / 2)) &&\n                    (sp[1].length <= (MAX_EMAIL_LEN / 2))) {\n                    // only username is greater than MAX_EMAIL_LEN / 2\n                    email = replaceChars(sp[0], MAX_EMAIL_LEN - sp[1].length, '*') + '@' + sp[1];\n                } else {\n                    // only domain is greater than MAX_EMAIL_LEN / 2\n                    email = sp[0] + '@' + replaceChars(sp[1], MAX_EMAIL_LEN - sp[0].length, '*');\n                }\n            }\n            return `${email} ${socialLogin}`\n        } catch (e) {\n            // Ignore error\n            console.log(\"getUserString:\", e);\n        }\n    }\n    return \"\";\n}\n\nexport function getTTL2Week() {\n    const secondsSinceEpoch = Math.round(Date.now() / 1000);\n    const SECONDS_IN_AN_HOUR = 60 * 60;\n    const HOURS_IN_2_WEEK = 24 * 14\n    // Reduced from previous 6 weeks to 4 weeks\n    const expirationTime = secondsSinceEpoch + 2 * SECONDS_IN_AN_HOUR * HOURS_IN_2_WEEK; //expire in 3 hours \n    return expirationTime\n}\nexport function getTTLForDays(days) {\n    const secondsSinceEpoch = Math.round(Date.now() / 1000);\n    const SECONDS_IN_AN_HOUR = 60 * 60;\n    const HOURS_IN_2_WEEK = 24 * days\n    // Reduced from previous 6 weeks to 4 weeks\n    const expirationTime = secondsSinceEpoch + 1 * SECONDS_IN_AN_HOUR * HOURS_IN_2_WEEK; //expire in 3 hours \n    return expirationTime\n}\n\nexport function genJoinCode() {\n    var d = new Date();\n    let m = d.getMonth()\n    m = m + 1\n    let y = d.getFullYear()\n    y = y - 2020\n    var array = new Uint8Array(5);\n    window.crypto.getRandomValues(array);\n    var code = \"\" + y + m\n    const chars = \"abcdefghijkmnpqrstuvwxyz0123456789\"\n    for (var i = 0; i < array.length; i++) {\n        code += chars[array[i] % chars.length]\n    }\n    return code;\n}\n\nexport const KEEPALIVE_TIMEOUT_SECONDS = 60;\nconst RESTRICTED = \"restricted.whiteboard.chat\"\n\nexport function isRestricted() {\n    if (window.location.host === RESTRICTED) {\n        return true\n    }\n    return false\n}\nfunction checkRestriction(cmd) {\n    const host = window.location.host\n    if (host !== RESTRICTED) {\n        return false\n    }\n    let id = cmd.id.split(\"-pgNum-\")[0]\n    if (cmd.Classroom && id !== cmd.Classroom) {\n        //not a parent\n        return false\n    }\n    let lu = mylocalStorage.getItem('mystoreID');\n    if (lu && gProfiles[lu]) {\n        let p = gProfiles[lu]\n        if (p && 'paidPlan' in p) return false\n        if (p && p.validTeacher) return false\n    }\n    alert(\"Only registered Teachers can create boards\")\n    return true\n}\n\nexport function checkDomain(email, bc, props) {\n    let match = true\n    let em = removeMSTeamsEmail(email)\n    let domain = em.split('@')[1]\n    if (domain) {\n        domain = domain.toLowerCase()\n        getTenantById(bc.boardsInternalTenantId).then(res => {\n            let t = res.data.getTenant\n            if (t && t.tenantConfig) {\n                let nc = {}\n\n                let c = JSON.parse(t.tenantConfig)\n                if (c.allLogin) nc.boardAuthUsersOnly = true\n                if (c.boardsInternalTenant) {\n                    nc.boardsInternalTenantId = t.id\n                    nc.boardsInternalTenantDomain = t.domainName\n                    if (t.secondaryDomainConfig) {\n                        let x = JSON.parse(t.secondaryDomainConfig)\n                        if (x.allowedDomains) {\n                            nc.boardsInternalTenantDomain = x.allowedDomains\n                        }\n                    }\n                    match = false\n                    let matchD = nc.boardsInternalTenantDomain.toLowerCase()\n                    if (matchD.includes(domain)) {\n                        match = true\n                    }\n\n                    if (!match) {\n                        alert(\"Sorry you are not authorized to access, sign in with the right email domain\")\n                        mylocalStorage.clear();\n                        props.history.push(\"/\")\n                    }\n                }\n            }\n        })\n    }\n    return true\n}\nfunction createSessionCommon(cmd) {\n    let ten = mylocalStorage.getItem('tenant');\n    if (!ten) {\n        return gqlOperationWithRetry(autoMutation.createSession, { input: cmd });\n    }\n\n    return new Promise((resolve, reject) => {\n        cmd.TenantID = ten\n        gqlOperationWithRetry(autoQuery.getTenant, { 'id': ten }).then(res => {\n            let t = res.data.getTenant\n            if (t && t.tenantConfig) {\n                let nc = {}\n\n                let c = JSON.parse(t.tenantConfig)\n                if (c.allLogin) nc.boardAuthUsersOnly = true\n                if (c.boardsInternalTenant) {\n                    nc.boardsInternalTenantId = t.id\n                    nc.boardsInternalTenantDomain = t.domainName\n                    if (t.secondaryDomainConfig) {\n                        let x = JSON.parse(t.secondaryDomainConfig)\n                        if (x.allowedDomains) {\n                            nc.boardsInternalTenantDomain = x.allowedDomains\n                        }\n                    }\n\n                }\n                if (Object.keys(nc).length > 0) {\n                    let old = {}\n                    if (cmd.boardConfig) {\n                        old = JSON.parse(cmd.boardConfig)\n                    }\n                    nc = { ...old, ...nc }\n                    cmd.boardConfig = JSON.stringify(nc)\n                }\n            }\n            done()\n        }).catch(() => {\n            done()\n        })\n        function done() {\n            gqlOperationWithRetry(autoMutation.createSession, { input: cmd }).then(r => {\n                resolve(r)\n            }).catch(e => {\n                reject(e)\n            })\n        }\n    })\n}\n\nexport async function createWhiteboard(opts, name, TutorGroupID) {\n    const id = uuid()\n    var luid = mylocalStorage.getItem('mystoreID');\n\n    const pg1 = id + \"-pgNum-1\"\n    var j = opts\n    if (opts.multiBoardOption)\n        await createClassroom({ id: id, TeacherID: luid, name: name })\n    let boardConfig = JSON.stringify(j)\n    let sess = await createSession(pg1, name, \"somecontent\",\n        id, 1, null, boardConfig, opts.multiBoardOption ? id : null, false, 0, TutorGroupID)\n    return sess.data.createSession\n}\n\nexport function createSession(id, name, content, parentId,\n    pageNumber, parentBoardID, boardConfig, classr, isGroup = false, ttl = 0, TutorClass = null) {\n    const cmd = {\n        id: id, 'name': name, 'content': content, ttl: (!ttl) ? getTTL() : ttl,\n        'parentID': parentId, pageNumber: pageNumber,\n        'isGroup': isGroup, joinCode: genJoinCode().toString(),\n        TutorClass: TutorClass\n    }\n    if (boardConfig) cmd['boardConfig'] = boardConfig\n    if (parentBoardID) {\n        cmd['parentBoardID'] = parentBoardID\n    } else {\n        cmd['parentBoardID'] = id//parentId for all otherwise its page to page \n    }\n    var luid = mylocalStorage.getItem('mystoreID');\n    if (!luid) {\n        luid = uuid()\n        mylocalStorage.setItem('mystoreID', luid)\n    }\n    cmd['CreatorLocalID'] = luid\n    if (classr) cmd[\"Classroom\"] = classr\n    if (checkRestriction(cmd)) {\n        return Promise.reject()\n    }\n    return createSessionCommon(cmd)\n}\n\nexport function createSessionPlain(cmd) {\n    return createSessionCommon(cmd)\n}\nexport function deleteSessionPlain(id) {\n    let cmd = { id: id }\n    setupdel(cmd)\n    return gqlOperationWithRetry(autoMutation.updateSession, { input: cmd })\n}\nexport function createSessionIfNotThere(id) {\n    getSession(id).then((res) => {\n        var sess = res.data.getSession\n        if (sess && sess.deleted) {\n            alert(\"Session has been deleted\")\n            return\n        }\n        if (!sess) createSessionNotFound(id)\n    })\n}\nexport function createSessionNotFound(id) {\n    return new Promise((resolve, reject) => {\n        const pgSplit = id.split(\"-pgNum-\")\n        if (pgSplit.length !== 2) {\n            reject(new Error(\"Invalid URL\"))\n            return\n        }\n        getSession(pgSplit[0] + \"-pgNum-1\").then((res) => {\n            var pg1 = res.data.getSession\n            if (!pg1) {\n                reject(new Error(\"Invalid URL with no page1\"))\n                return\n            }\n            pg1.id = id\n            pg1.pageNumber = pgSplit[1]\n            const parentSplit = pg1.parentBoardID.split(\"-pgNum-\")\n            pg1.parentBoardID = parentSplit[0] + \"-pgNum-\" + pgSplit[1]\n            delete pg1['createdAt']\n            delete pg1['updatedAt']\n            delete pg1['Objects']\n            delete pg1['Users']\n            let bc = pg1.boardConfig\n            if (bc) {\n                let cc = JSON.parse(bc)\n                if (cc) {\n                    delete cc['autoGrade']\n                    delete cc['manualGrade']\n                    pg1.boardConfig = JSON.stringify(cc)\n                }\n            }\n            if (pg1['savedOwner'] === null) {\n                delete pg1['savedOwner']\n            }\n            if (pg1['Classroom'] === null) {\n                delete pg1['Classroom']\n            }\n            delete pg1['Users']\n            // When a session is being created, we cannot have folderID be equal to\n            // an empty string (\"\") or null. If we don't have a valid folderID,\n            // remove the key from the object being created.\n            if (!(pg1[\"folderID\"])) {\n                delete pg1[\"folderID\"]\n            }\n            delete pg1['MultiBoard']\n            gqlOperationWithRetry(autoMutation.createSession, { input: pg1 }).then(r => {\n                resolve(r)\n            })\n        })\n    })\n}\n\nexport async function findCreateSession(classroom) {\n    return new Promise(async (resolve, reject) => {\n        var nt = null\n        var luid = mylocalStorage.getItem('mystoreID');\n        if (!luid) {\n            luid = uuid()\n            mylocalStorage.setItem('mystoreID', luid)\n        }\n\n        do {\n            const cmd = {\n                limit: 100, nextToken: nt, sortDirection: \"ASC\",\n                CreatorLocalID: luid, filter: { and: { Classroom: { eq: classroom }, deleted: { ne: true } } }\n            }\n            var res = await gqlOperationWithRetry(autoQuery.queryByCreatorLocalId, cmd)\n            const dat = res.data.queryByCreatorLocalId\n            if (dat && dat.items) {\n                for (let i = 0; i < dat.items.length; i++) {\n                    const d = dat.items[i]\n                    if (!d.isGroup)\n                        resolve(d)\n                    return\n                }\n            }\n            nt = dat.nextToken\n        } while (nt !== null)\n        resolve(null)\n    })\n}\nexport async function findSessionbyID(classroom, luid) {\n    return new Promise(async (resolve, reject) => {\n        var nt = null\n        do {\n            const cmd = {\n                limit: 100, nextToken: nt, sortDirection: \"ASC\",\n                CreatorLocalID: luid, filter: { and: { Classroom: { eq: classroom }, deleted: { ne: true } } }\n            }\n            var res = await gqlOperationWithRetry(autoQuery.queryByCreatorLocalId, cmd)\n            const dat = res.data.queryByCreatorLocalId\n            if (dat && dat.items) {\n                for (let i = 0; i < dat.items.length; i++) {\n                    const d = dat.items[i]\n                    resolve(d)\n                }\n            }\n            nt = dat.nextToken\n        } while (nt !== null)\n        resolve(null)\n    })\n}\nexport async function deleteUserAndBoard(classroom, luid) {\n    findSessionbyID(classroom, luid).then((r) => {\n        var pp = r.id.split(\"-pgNum-\")\n        getboardsbyparent(pp[0], null, delPages)\n        function delPages(items) {\n            if (!items) return\n            items.forEach((item) => {\n                try {\n                    deletePage(item.id, function () { })\n                } catch (err) {\n                    console.log(\"ERROR DELETE\", err)\n                    // Ignore it\n                }\n            })\n        }\n    })\n    const localId = luid + \"-CL-\" + classroom\n    getLocalUsers(localId).then((dat) => {\n        const lu = dat.data.getLocalUsers\n\n        if (lu && lu.CurrentUser) {\n            deleteUser(lu.CurrentUser)\n        }\n    })\n    await new Promise(r => setTimeout(r, 1000));\n\n    deleteLocalUsers(localId)\n}\nexport async function findCreateSessionByName(classroom) {\n    return new Promise(async (resolve, reject) => {\n        var nt = null\n        var luid = mylocalStorage.getItem('mystoreID');\n        var name = mylocalStorage.getItem('myname');\n        var luname = name.toLowerCase()\n        luname = luname.replace(/\\s/g, \"\")\n        do {\n            const cmd = {\n                limit: 100, nextToken: nt, sortDirection: \"ASC\", Classroom: classroom, filter: { deleted: { ne: true } }\n            }\n\n            var res = await gqlOperationWithRetry(customops.queryByClassroom, cmd)\n            const dat = res.data.queryByClassroom\n            if (dat && dat.items) {\n                for (let i = 0; i < dat.items.length; i++) {\n                    const d = dat.items[i]\n                    if (d.CreatorLocalID === luid) {\n                        resolve(d)\n                        return\n                    }\n                }\n                // // did not find any\n                // if (!timeSet || dt - timeSet > 100) {\n                //     resolve(null)\n                //     return\n                // }\n\n                for (let i = 0; i < dat.items.length; i++) {\n                    const d = dat.items[i]\n                    if (d.isGroup) continue\n                    if (d.parentID === d.Classroom) {\n                        // cannot join teacher with same name \n                        continue\n                    }\n\n                    // const localId = d.CreatorLocalID + \"-CL-\" + classroom\n                    if (!d.Users || !d.Users.items) continue\n\n                    for (let j = 0; j < d.Users.items.length; j++) {\n                        const uu1 = d.Users.items[j]\n                        var js\n                        try {\n                            js = JSON.parse(uu1.content)\n                        } catch {\n                            continue\n                        }\n\n                        if (js.localID === d.CreatorLocalID) {\n                            if (!uu1.name || uu1.name === \"\") continue\n                            let uname = uu1.name.toLowerCase().replace(/\\s/g, \"\")\n                            if (uname === luname) {\n                                // set old luid back \n                                mylocalStorage.setItem(\"mystoreID\", js.localID)\n                                resolve(d)\n                                return\n                            }\n                        }\n                    }\n                }\n                nt = dat.nextToken\n            }\n        } while (nt !== null)\n        resolve(null)\n    })\n}\n\nexport function setupdel(cmd) {\n    cmd.deleted = true\n    cmd.ttl = getDelTTL()\n}\nexport function delObject(cmd) {\n    if (!cmd) return\n    CacheDraw.delObject(cmd.id)\n    cmd.deleted = true\n    cmd.ttl = getDelTTL()\n    return updateObject(cmd)\n    // return gqlOperationWithRetry(autoMutation.deleteObject, { input: { id: id } });\n}\n\nexport function deletePage(id, cb) {\n    listObject(id, null, function (items) {\n        items.forEach((item) => {\n            delObject(item)\n        })\n    })\n    deleteSessionPlain(id).then((res) => {\n        if (cb) cb()\n    }).catch((error)=>{\n        console.log(\"Error while deleting page::\", error);\n    });\n}\n\nexport async function duplicatePage(id, newNum, copy) {\n    return new Promise(async (resolve, reject) => {\n        const pgSplit = id.split(\"-pgNum-\")\n        // var pages = await getboardsbyparentSync(pgSplit[0])\n        // //delete page\n        // for (let i = pages.length - 1; i >= page; i--) {\n        //     var foo = await updatePageNumer(pages[i].id, i + 2)\n        // }\n        const oldSessionID = id\n        var oldPageVal = await getSession(oldSessionID)\n        var sess = oldPageVal.data.getSession\n        if (sess) {\n            var pluson = newNum\n            sess.id = pgSplit[0] + \"-pgNum-\" + pluson\n            sess.pageNumber = newNum\n            sess.parentBoardID = sess.id\n            delete sess['Classroom']\n            delete sess['Objects']\n            delete sess['Users']\n            delete sess['MultiBoard']\n            delete sess['folderID']\n            if (sess['savedOwner'] === null) {\n                delete sess['savedOwner']\n            }\n            var p = await createSessionPlain(sess)\n            if (copy) {\n                listObject(oldSessionID, null, async function (items) {\n                    items.forEach((item) => {\n                        delete item['Session']\n                        delete item['id']\n                        item.SessionID = sess.id\n\n                        createObjPlain(item)\n                    })\n                    await new Promise(r => setTimeout(r, 300));\n                    resolve(p.data.createSession)\n                })\n            } else {\n                await new Promise(r => setTimeout(r, 300));\n                resolve(p.data.createSession)\n\n            }\n        }\n    })\n}\n\nexport async function checkBoards(sess) {\n    const pgSplit = sess.id.split(\"-pgNum-\")\n    var pages\n    // if (sess.Classroom)\n    //         pages = await getSessionByClassroomSync(sess.Classroom)\n    //     else\n    pages = await getboardsbyparentSync(pgSplit[0])\n    return pages\n}\nexport async function updateClassBoardsOrderAll(sess, bo) {\n    return new Promise(async (resolve, reject) => {\n        const pgSplit = sess.id.split(\"-pgNum-\")\n        var pages\n        if (sess.Classroom)\n            pages = await getSessionByClassroomSync(sess.Classroom)\n        else\n            pages = await getboardsbyparentSync(pgSplit[0])\n        const slowLoad = pages.filter((p, i) => {\n            return (i !== 0) && (p.pageNumber !== sess.pageNumber);\n        })\n        const quickLoad = pages.filter((p, i) => {\n            return p.pageNumber === sess.pageNumber || p.pageNumber === 1;\n        })\n        for (let i = 0; i < slowLoad.length; i++) {\n            var page = slowLoad[i]\n            var bc = JSON.parse(page.boardConfig)\n            if(bc){\n                bc.boardOrder = bo\n                page.boardConfig = JSON.stringify(bc)\n            } else {\n                page.boardConfig = JSON.stringify({boardOrder: bo})\n            }\n            updateSession(page)\n        }\n\n        for (let i = 0; i < quickLoad.length; i++) {\n            page = quickLoad[i]\n            bc = JSON.parse(page.boardConfig)\n            if(bc){\n                bc.boardOrder = bo\n                page.boardConfig = JSON.stringify(bc)\n            } else {\n                page.boardConfig = JSON.stringify({boardOrder: bo})\n            }\n            await updateSession(page)\n            resolve()\n        }\n    })\n}\n\nexport async function updateClassBoardsConfig(id, bo, cb) {\n    const sess2 = await getSession(id)\n    const sess = sess2?.data?.getSession\n    if (!sess2 || !sess) cb()\n\n    const pgSplit = sess.id.split(\"-pgNum-\")\n    var pages\n    if (sess.Classroom)\n        pages = await getSessionByClassroomSync(sess.Classroom)\n    else\n        pages = await getboardsbyparentSync(pgSplit[0])\n\n    for (let i = 0; i < pages.length; i++) {\n        var page = pages[i]\n        var bc = JSON.parse(page.boardConfig)\n        let keys = Object.keys(bo)\n        for (let i = 0; i < keys.length; i++) {\n            let k = keys[i]\n            bc[k] = bo[k]\n        }\n        page.boardConfig = JSON.stringify(bc)\n        await updateSession(page)\n    }\n    cb()\n}\nexport async function updateClassBoardsTools(sess, bo) {\n    return new Promise(async (resolve, reject) => {\n        const pgSplit = sess.id.split(\"-pgNum-\")\n        var pages\n        if (sess.Classroom)\n            pages = await getSessionByClassroomSync(sess.Classroom)\n        else\n            pages = await getboardsbyparentSync(pgSplit[0])\n        for (let i = 0; i < pages.length; i++) {\n            var page = pages[i]\n            var bc = JSON.parse(page.boardConfig)\n            bc.boardTools = bo\n            page.boardConfig = JSON.stringify(bc)\n            await updateSession(page)\n        }\n        let luid = mylocalStorage.getItem('mystoreID');\n        var lu = await getUserProfie(luid)\n        if (lu && lu.data.getUserProfile) {\n            var r = lu.data.getUserProfile\n            var p = r.boardConfig ? JSON.parse(r.boardConfig) : {}\n            p.boardTools = bo\n            r.boardConfig = JSON.stringify(p)\n            updateUserProfile(r)\n        }\n        resolve()\n    })\n}\n\nexport async function updateClassBoardsOrder(sess) {\n    return new Promise(async (resolve, reject) => {\n        const pgSplit = sess.id.split(\"-pgNum-\")\n        var pages\n        if (sess.Classroom)\n            pages = await getSessionByClassroomSync(sess.Classroom)\n        else\n            pages = await getboardsbyparentSync(pgSplit[0])\n        for (let i = 0; i < pages.length; i++) {\n            var page = pages[i]\n            var bc = JSON.parse(page.boardConfig)\n            bc.boardHasSkipPage = true\n            if (page.id === sess.id) bc.hidden = true\n            page.boardConfig = JSON.stringify(bc)\n            await updateSession(page)\n        }\n        resolve()\n    })\n}\nexport async function deletePageNumber(id) {\n    return new Promise(async (resolve, reject) => {\n        deletePage(id, done)\n        async function done() {\n            resolve()\n        }\n    })\n}\nexport function updatePageNumer(id, newPage) {\n    return new Promise((resolve, reject) => {\n        const pgSplit = id.split(\"-pgNum-\")\n        const oldParent = id.split(\"-pgNum-\")\n        var newParent = oldParent[0] + \"-pgNum-\" + newPage\n        var newID = pgSplit[0] + \"-pgNum-\" + newPage\n        var prom = []\n        getSession(id).then(async (r) => {\n            var sess = r.data.getSession\n            if (!sess) {\n                return\n            }\n            var items = await listObjectSync(id)\n\n            items.forEach((item) => {\n                item.SessionID = newID\n                delete item['Session']\n                var p = updateObject(item)\n                prom.push(p)\n            })\n            sess.id = newID\n            sess.pageNumber = newPage\n            sess.parentBoardID = newParent\n            delete sess['Objects']\n            delete sess['Users']\n            delete sess['MultiBoard']\n            delete sess['folderID']\n\n            var p = createSessionPlain(sess)\n            prom.push(p)\n            p = deleteSessionPlain(id)\n            prom.push(p)\n            Promise.all(prom).then(() => {\n                resolve()\n            })\n        })\n    })\n}\nexport function createPaperObj(objIn, sessionid, ttl, raster, isJson = false) {\n    const id = uuid()\n    var copy1 = objIn\n    if(!isJson) {\n        objIn.data.drawPaper = true\n        var ff = objIn.exportJSON()\n        copy1 = JSON.parse(JSON.stringify(ff))\n    }\n    let copy = {}\n    copy.type = JSON.stringify({ 'compressed': true })\n    copy.content = pako.deflate(copy1, { to: 'string' });\n    return createObject(id, \"name\", sessionid, copy.content, \"drawPaper\", null, copy.type, ttl)\n}\n\nexport function delSession(id, cb) {\n    // const ttl = getTTL()\n    // const pgSplit = id.split(\"-pgNum-\")\n    // const ids = uuid()\n    // const pg1 = ids + \"-pgNum-\" + pgSplit[1]\n\n    // createSession(pg1, \"backup\", \"backup\", ids, pgSplit[1]).then((res) => {\n    //     const back = res.data.createSession\n    //     //move all old objects\n    //     listObject(id, null, function (items) {\n    //         items.map((item) => {\n    //             item.SessionID = back.id\n    //             item.ttl = ttl\n    //             delete item['Session']\n    //             updateObject(item)\n    //             return null\n    //         })\n    //     })\n    deleteSessionPlain(id).then(() => {\n        if (cb) cb()\n    });\n    // })\n}\n\nfunction checkObjLocked(obj) {\n    if (obj.objType !== \"drawPaper\") return false\n    let newobj = {}\n    newobj.content = obj.content\n    try {\n        if ('type' in obj) {\n            newobj['type'] = JSON.parse(obj['type'])\n            if (newobj.type && newobj.type.compressed) {\n                newobj.content = pako.inflate(obj.content, { to: 'string' });\n            }\n        }\n    } catch (e) {\n        console.error(\"cannot decode\", e, obj)\n        return false\n    }\n    var rr\n    try {\n        rr = JSON.parse(newobj.content)\n    } catch (e) {\n        return false\n    }\n    if (!rr || !rr.length || rr.length < 2) return false\n    if (rr[1] && rr[1].data && rr[1].data.lockedClearAllowed) return false\n    if (rr[1] && rr[1].data && rr[1].data.lock) return true\n\n    return false\n}\nexport async function delAllObjSession(id, group, userId) {\n    listObject(id, null, function (items) {\n        items.forEach((item) => {\n            if (userId && item.CreatedBy && userId !== item.CreatedBy) {\n                return\n            }\n            if (!checkObjLocked(item))\n                delObject(item)\n        })\n    })\n}\n\nexport function updateSession(cmd) {\n    delete cmd['Objects']\n    delete cmd['Users']\n    delete cmd['MultiBoard']\n    if (cmd.TutorClass) {\n        let item = cmd\n        let jj = item.boardConfig ? JSON.parse(item.boardConfig) : {}\n        jj[\"boardAuthUsersOnly\"] = true\n        cmd.boardConfig = JSON.stringify(jj)\n    }\n    // If a session is moved from within a folder to the root folder,\n    // folderID is set to null so that the folderID field is removed\n    // from the session object. folderID can be set to null while\n    // updating a session. It cannot be set to an empty string (\"\")\n    // while updating a session\n    if (cmd[\"folderID\"] === \"\") {\n        delete cmd[\"folderID\"]\n    }\n    if (cmd[\"folderID\"] === undefined) {\n        delete cmd[\"folderID\"]\n    }\n    return gqlOperationWithRetry(autoMutation.updateSession, { input: cmd });\n}\n\nexport function getSession(id) {\n    return gqlOperationWithRetry(autoQuery.getSession, { 'id': id });\n}\n\nexport function getSessionByJoinCode(joinCode) {\n    return gqlOperationWithRetry(customops.queryByJoinCode, { 'joinCode': joinCode });\n}\n\nexport function getUserProfie(id) {\n    return new Promise((resolve, reject) => {\n        gqlOperationWithRetry(autoQuery.getUserProfile, { 'id': id }).then(r => {\n            let v = r.data.getUserProfile\n            gProfiles[id] = v\n            resolve(r)\n        }).catch(e => {\n            reject(e)\n        })\n    })\n    // console.error(\"GOT USER PROFILE CALL\", id)\n    // return gqlOperationWithRetry(autoQuery.getUserProfile, { 'id': id });\n}\n\nexport function createUserProfile(id, name, email, avatar) {\n    return new Promise((resolve, reject) => {\n\n        var emailOptIn = mylocalStorage.getItem('emailOptIn');\n        const cmd = { id: id, 'name': name, 'email': email, 'emailOptIn': emailOptIn !== null ? emailOptIn : false }\n        //if value is there ok else by default true email }\n\n        if (avatar && avatar !== \"\") {\n            cmd['avatar'] = avatar;\n        }\n\n        function processTenant(t) {\n            let tvalue = null\n            if (t && t.tenantConfig) {\n                let tc = JSON.parse(t.tenantConfig)\n                if (tc.assignLicensesAutomatically === true) {\n                    tvalue = t.id\n                    if (t.entitlements) {\n                        let en = JSON.parse(t.entitlements)\n                        if (en.planType) {\n                            cmd.paidPlan = en.planType\n                        }\n                    }\n                }\n            }\n            done(tvalue)\n        }\n\n        var wait = false\n        if (email) {\n            let em = removeMSTeamsEmail(email)\n            let dom = em.split('@')[1]\n            if (dom) {\n                wait = true\n                listTenantByDomain(dom).then(d => {\n                    let res = d.data.queryByDomainName\n                    let t1 = res && res.items && res.items.length > 0 ? res.items[0] : null\n                    if (t1) {\n                        //found domain\n                        if (t1.secondaryDomainConfig) {\n                            let x = JSON.parse(t1.secondaryDomainConfig)\n                            if (x.mainDomain) {\n                                // get the main domain and get config from there\n                                gqlOperationWithRetry(autoQuery.getTenant, { 'id': x.mainDomain }).then(p => {\n                                    let r = p.data.getTenant\n                                    if (!r) {\n                                        processTenant(t1)\n                                        return\n                                    }\n                                    processTenant(r)\n                                }).catch(() => {\n                                    processTenant(t1)\n                                })\n                                return\n                            }\n                        }\n                    }\n                    processTenant(t1)\n                }).catch(() => {\n                    done(null)\n                })\n            }\n        }\n        if (!wait) done(null)\n        function done(tval) {\n            if (tval) {\n                cmd.TenantID = tval\n            }\n            gqlOperationWithRetry(autoMutation.createUserProfile, { input: cmd }).then(r => {\n                resolve(r)\n            }).catch(e => {\n                reject(e)\n            })\n        }\n    })\n}\n\nexport function updateUserProfile(obj) {\n    var name = mylocalStorage.getItem('myname');\n    if (name && obj.name === null) {\n        obj.name = name\n    }\n    //no need to update tenant details everytime \n    delete obj['Tenant']\n    delete obj['TenantID']\n    return gqlOperationWithRetry(autoMutation.updateUserProfile, { input: obj });\n}\n\nexport async function updatePersonalConfig(pc) {\n    let luid = mylocalStorage.getItem('mystoreID');\n    var lu = await getUserProfie(luid)\n    if (lu && lu.data.getUserProfile) {\n        var r = lu.data.getUserProfile\n        r.personalConfig = JSON.stringify(pc)\n        updateUserProfile(r)\n    }\n}\n\nfunction updateClassIfNeeded(cb, url, up) {\n    if (!url) {\n        cb(up)\n        return\n    }\n    const JOINURL = url.split(\"/board/\")\n    if (JOINURL.length < 2) {\n        cb(up)\n        return\n    }\n    var localluid = mylocalStorage.getItem('mystoreID'); //timing if not updated yet\n\n    var luid = mylocalStorage.getItem('backupLocalID');\n    if (!luid) {\n        luid = localluid//timing if not updated yet\n        if (!luid) {\n            cb(up)\n            return\n        }\n    }\n    if (luid === up.id) {\n        cb(up)\n        return\n    }\n    if (localluid === up.id) {\n        cb(up)\n        return\n    }\n    getSession(JOINURL[1]).then((r) => {\n        const sess = r.data.getSession\n        if (!sess || !sess.Classroom) {\n            cb(up)\n            return\n        }\n        getClassroom(sess.Classroom, function (cl) {\n            if (cl) {\n                if (cl.TeacherID === luid) {\n                    cl.TeacherID = up.id\n\n                    // Newly logged in user needs to be added to teacher list\n                    // as well for all controls to work properly after a login.\n                    if (cl.TeacherList) {\n                        if (cl.TeacherList.indexOf(up.id) < 0) {\n                            cl.TeacherList.push(up.id);\n                        }\n                    } else {\n                        cl.TeacherList = [up.id];\n                    }\n\n                    delete (cl['Teacher'])\n                    delete (cl['Users'])\n                    updateClassroom(cl)\n                }\n            }\n        })\n        // delete local user\n        const localId = luid + \"-CL-\" + sess.Classroom\n        getLocalUsers(localId).then((dat) => {\n            const lu = dat.data.getLocalUsers\n            if (lu && lu.CurrentUser) {\n                deleteUser(lu.CurrentUser)\n            }\n        })\n        deleteLocalUsers(localId)\n        delUsers(null)\n        // delete all users by this name\n        function delUsers(nt) {\n            const cmd = {\n                limit: 100, nextToken: nt, sortDirection: \"ASC\",\n                UserProfile: luid\n            }\n            gqlOperationWithRetry(autoQuery.byProfileSorted, cmd).then((re3) => {\n                var dats = re3.data.byProfileSorted\n                for (let i = 0; i < dats.items.length; i++) {\n                    var up = dats[i]\n                    if (up && up.Session && up.Session.Classroom === sess.Classroom) {\n                        deleteUser(up)\n                    }\n                }\n                //update class to the right user\n                if (dats.nextToken) {\n                    delUsers(dats.nextToken)\n                }\n            })\n        }\n\n        function getBoards(nt) {\n            const cmd = {\n                limit: 100, nextToken: nt, sortDirection: \"ASC\",\n                CreatorLocalID: luid, filter: { and: { Classroom: { eq: sess.Classroom }, deleted: { ne: true } } }\n            }\n            gqlOperationWithRetry(autoQuery.queryByCreatorLocalId, cmd).then((res) => {\n                const dats = res.data.queryByCreatorLocalId\n                var promises = []\n                for (let i = 0; i < dats.items.length; i++) {\n                    var dat = dats.items[i]\n                    if (dat && luid !== up.id) {\n                        dat.CreatorLocalID = up.id\n                        dat.savedOwner = up.id;\n                        promises.push(updateSession(dat))\n                    }\n                }\n\n                //update class to the right user\n                if (!dats.nextToken) {\n                    Promise.all(promises).then(() => {\n                        cb(up)\n                    })\n                } else {\n                    Promise.all(promises).then(() => {\n                        getBoards(dats.nextToken)\n                    })\n                }\n            })\n        }\n        getBoards(null)\n    })\n}\n\nexport async function getClassboardsByClass(classRoom) {\n    var allList = []\n    const cl = classRoom + \"-pgNum-1\"\n    var nt = null\n    do {\n        const cmd = {\n            limit: 100, nextToken: nt, sortDirection: \"ASC\",\n            Classroom: classRoom, filter: { and: { id: { ne: cl }, pageNumber: { eq: 1 }, deleted: { ne: true } } }\n        }\n        var res = await gqlOperationWithRetry(autoQuery.queryByClassroom, cmd)\n        const dat = res.data.queryByClassroom\n        allList = [...allList, ...dat.items]\n        nt = dat.nextToken\n    } while (nt !== null)\n    return allList\n}\n\nexport async function getBoardsByTeacher(localID, dateLast) {\n    var allList = []\n    var nt = null\n    do {\n        const cmd = {\n            limit: 100, nextToken: nt, sortDirection: \"ASC\",\n            CreatorLocalID: localID, filter: { and: { updatedAt: { gt: dateLast }, deleted: { ne: true }, pageNumber: { eq: 1 } } }\n        }\n        var res = await gqlOperationWithRetry(autoQuery.queryByCreatorLocalId, cmd)\n        const dat = res.data.queryByCreatorLocalId\n        dat.items.forEach(async i => {\n            i.studentCount = 0\n            if (i.Classroom) {\n                var t = await getClassboardsByClass(i.Classroom)\n                i.studentCount = t.length\n            }\n        })\n        allList = [...allList, ...dat.items]\n        nt = dat.nextToken\n    } while (nt !== null)\n    return allList\n}\n\nexport function findCreateUserProfile(id, email, avatar, name, url, cb, signup) {\n    getUserProfie(id).then((res) => {\n        var emailOptIn = mylocalStorage.getItem('emailOptIn');\n        if (res && res.data.getUserProfile) {\n            var u = res.data.getUserProfile;\n            var needsUpdate = false;\n            if (avatar && avatar !== \"\" && res.data.getUserProfile.avatar !== avatar) {\n                u['avatar'] = avatar;\n                needsUpdate = true;\n            }\n            if (name && name !== \"\" && !res.data.getUserProfile.name) {\n                // If the profile did not have a name set, update\n                // it from the social login (if we got any).\n                u['name'] = name;\n                needsUpdate = true;\n            }\n            if (emailOptIn && emailOptIn !== '' && !res.data.getUserProfile.emailOptIn) {\n                u['emailOptIn'] = emailOptIn\n                needsUpdate = true;\n            }\n            if (needsUpdate) {\n                updateUserProfile(u).then((re) => {\n                    updateClassIfNeeded(cb, url, re.data.updateUserProfile)\n                });\n            } else {\n                updateClassIfNeeded(cb, url, res.data.getUserProfile)\n            }\n        } else {\n            var tmpName = mylocalStorage.getItem('myname');\n\n            if (!(tmpName && tmpName !== \"\") && name) {\n                // If the user has not set a name, use the one\n                // that we got (if any) from a social login\n                // (google or facebook).\n                tmpName = name;\n                mylocalStorage.setItem('myname', tmpName);\n            }\n\n            createUserProfile(id, tmpName, email, avatar).then((re) => {\n                updateClassIfNeeded(cb, url, re.data.createUserProfile)\n            }).catch(error => { console.log('user exist already', error) })\n        }\n    }).catch(e => {\n        alert(\"Please check the TIME on your computer and make sure it is right.\")\n    })\n}\nexport function createObject(id, name, sessionID, content, objType, userid, intype = null, ttl = 0) {\n    const cmd = { 'id': id, 'name': name, 'content': content, 'SessionID': sessionID, ended: false, objType: objType };\n    (!ttl) ? cmd.ttl = getTTL() : cmd.ttl = ttl;\n    if (userid) cmd['CreatedBy'] = userid\n    if (intype) cmd['type'] = intype\n\n    return createObjPlain(cmd);\n}\n\nexport function createObjectanimate(id, name, sessionID, content, objType, userid, intype = null, ttl = 0, animate) {\n    const cmd = { 'id': id, 'name': name, 'content': content, 'SessionID': sessionID, ended: false, objType: objType, animate: animate };\n    (!ttl) ? cmd.ttl = getTTL() : cmd.ttl = ttl;\n    if (userid) cmd['CreatedBy'] = userid\n    if (intype) cmd['type'] = intype\n    return createObjPlain(cmd);\n}\n\nexport function reCreateObject(id, name, sessionID, content, objType, userid, ended = false, animate = null, type = \"\", ttl = 0) {\n    const cmd = { 'id': id, 'name': name, 'content': content, 'SessionID': sessionID, ended: ended, objType: objType, animate: animate, type: type };\n    (!ttl) ? cmd.ttl = getTTL() : cmd.ttl = ttl;\n    if (userid) cmd['CreatedBy'] = userid\n\n    if (!type || type === \"\") cmd[\"type\"] = JSON.stringify({ 'compressed': false })\n    return createObjPlain(cmd);\n}\n\nexport function getObject(id) {\n    return gqlOperationWithRetry(autoQuery.getObject, { id: id });\n}\nexport function updateAnimateObject(inp) {\n    const cmd = { ...inp, animate: inp.animate }\n    return updateObjPlain(cmd);\n}\n\nexport function updateObject(cmd) {\n    delete cmd['Session']\n    return updateObjPlain(cmd);\n}\n\nexport function listObject(sessionID, nextToken, cb) {\n    const cmd = { limit: 100, nextToken: nextToken, sortDirection: \"ASC\", SessionID: sessionID, filter: { deleted: { ne: true } } }\n    gqlOperationWithRetry(autoQuery.sessionSorted, cmd).then(res => {\n        const dat = res.data.sessionSorted\n        cb(dat.items)\n        if (dat.nextToken) {\n            listObject(sessionID, dat.nextToken, cb)\n        }\n    })\n}\n\nexport async function listObjectSync(sessionID) {\n    var allList = []\n    var nt = null\n    do {\n        const cmd = { limit: 100, nextToken: nt, sortDirection: \"ASC\", SessionID: sessionID, filter: { deleted: { ne: true } } }\n        var res = await gqlOperationWithRetry(autoQuery.sessionSorted, cmd)\n        const dat = res.data.sessionSorted\n        allList = [...allList, ...dat.items]\n        nt = dat.nextToken\n    } while (nt !== null)\n    return allList\n}\n\n\nexport async function getboardsbyparentSync(parentID) {\n    var allList = []\n    var nt = null\n    do {\n        const cmd = { limit: 100, nextToken: nt, sortDirection: \"ASC\", parentID: parentID, filter: { deleted: { ne: true } } }\n\n        var res = await gqlOperationWithRetry(customops.queryByParent, cmd)\n        const dat = res.data.queryByParent\n        allList = [...allList, ...dat.items]\n        nt = dat.nextToken\n    } while (nt !== null)\n    return allList\n}\n\nexport function callObjectcb(sessionID, nextToken, cb) {\n    listObject(sessionID, nextToken).then((res) => {\n        const dat = res.data.listObjects\n        if (dat.nextToken) {\n            listObject(sessionID, dat.nextToken).then((res2) => {\n                const dat2 = res.data.listObjects\n\n                console.log(\"FOUND CO NT2\", res2, dat2.items.length, dat2.nextToken)\n\n            })\n        }\n    })\n}\n\n// context args: sessionID, cb, delCB, subCB, doList, retryCount=SUB_MAX_RETRY_COUNT\nexport function ObjectSubscribe(context) {\n    if (context.retryCount === undefined) context.retryCount = SUB_MAX_RETRY_COUNT;\n    if (context.doList) listObject(context.sessionID, null, context.cb)\n    const s1 = API.graphql(graphqlOperation(autoSub.subscribeToSessionObjects, { SessionID: context.sessionID }))\n    var s2, s4;\n    let retried = false;\n    s2 = trySubscribe(s1, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.subscribeToSessionObjects\n            if (!data.deleted) {\n                context.cb([data])\n            } else {\n                context.delCB(data)\n            }\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(retried, \"ObjectSubscribe:subscribeToSessionObjects\",\n                error, s4, ObjectSubscribe, context);\n            retried = true;\n        }\n    }, \"ObjectSubscribe:subscribeToSessionObjects\");\n    context.subCB([s2, s4])\n}\n\n/* user stuff */\nexport function findUserLoop(filter, nextToken, cb, userList, content, session) {\n    var cmd = { limit: 100, nextToken: nextToken, SessionID: session }\n    if (filter && Object.keys(filter).length > 0) {\n        cmd['filter'] = filter\n    }\n    gqlOperationWithRetry(autoQuery.byUsersSessionSorted, cmd).then(res => {\n        const dat = res.data.byUsersSessionSorted;\n        userList = userList.concat(dat.items);\n        if (dat.nextToken) {\n            findUserLoop(filter, dat.nextToken, cb, userList, content);\n        } else {\n            // Send a complete list in one callback at the end\n            cb(userList, content);\n        }\n    })\n}\n\nexport function findUser(sessionID, content, userProfileID, cb) {\n    var filter = {}\n\n    if (userProfileID) filter['UserProfile'] = { 'eq': userProfileID };\n    if (content['email'] || content['localID']) filter['or'] = [];\n    if (content['email']) filter['or'].push({ 'content': { 'contains': `\"email\":\"${content['email']}\"` } })\n    if (content['localID']) filter['or'].push({ 'content': { 'contains': `\"localID\":\"${content['localID']}\"` } })\n\n    return findUserLoop(filter, null, cb, [], content, sessionID);\n}\n\nexport function createUser(name, sessionID, content, userProfileID, userAvatar, ttl = 0) {\n    const cmd = { 'name': name, 'content': content, 'SessionID': sessionID };\n    (!ttl) ? cmd.ttl = getTTL() : cmd.ttl = ttl;\n    if (userProfileID) cmd['UserProfile'] = userProfileID\n    if (userAvatar) cmd['avatar'] = userAvatar;\n    return gqlOperationWithRetry(autoMutation.createUser, { input: cmd });\n}\n\nexport function deleteUser(cmd) {\n    return gqlOperationWithRetry(autoMutation.deleteUser, { input: { id: cmd.id } });\n}\n\nexport function updateUser(cmd) {\n    var cmdCopy = JSON.parse(JSON.stringify(cmd));\n    delete cmdCopy['Session']\n    delete cmdCopy['updatedAt']\n    delete cmdCopy['createdAt']\n    return gqlOperationWithRetry(autoMutation.updateUser, { input: cmdCopy });\n}\n\nexport function listUser(sessionID, nextToken, cb) {\n    const cmd = { limit: 100, nextToken: nextToken, SessionID: sessionID }\n    gqlOperationWithRetry(autoQuery.byUsersSessionSorted, cmd).then(res => {\n        const dat = res.data.byUsersSessionSorted\n        cb(dat.items)\n        if (dat.nextToken) {\n            listUser(sessionID, dat.nextToken, cb)\n        }\n    })\n}\n\n// noList was inverted and changed to doList\n// context args: sessionID, cb, doList, subCB, retryCount=SUB_MAX_RETRY_COUNT\nexport function UserSubscribe(context) {\n    if (context.retryCount === undefined) context.retryCount = SUB_MAX_RETRY_COUNT;\n    if (context.doList) listUser(context.sessionID, null, context.cb)\n    const s1 = API.graphql(graphqlOperation(autoSub.subscribeToSessionUsers, { SessionID: context.sessionID }))\n    var s2 = trySubscribe(s1, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.subscribeToSessionUsers\n            context.cb([data])\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(false, \"UserSubscribe\",\n                error, null, UserSubscribe, context);\n        }\n    }, \"UserSubscribe\");\n    context.subCB(s2);\n}\n\n// context args: sessionID, cb, delcb, subCB, retryCount=SUB_MAX_RETRY_COUNT\nexport function SessionSubscribe(context) {\n    if (context.retryCount === undefined) context.retryCount = SUB_MAX_RETRY_COUNT;\n    const s1 = API.graphql(graphqlOperation(autoSub.subscribeToSession, { id: context.sessionID }))\n    var s2, s4;\n    let retried = false;\n    s2 = trySubscribe(s1, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.subscribeToSession\n            if (!data.deleted) {\n                context.cb(data)\n            } else {\n                context.delcb(data)\n            }\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(retried, \"SessionSubscribe:subscribeToSession\",\n                error, null, SessionSubscribe, context);\n            retried = true;\n        }\n    }, \"SessionSubscribe:subscribeToSession\");\n    context.subCB([s2, s4]);\n}\n\nfunction getDate() {\n    var today = new Date();\n    today.setHours(today.getHours() - 6);\n    return today\n}\nexport function listSession(cb, nextToken) {\n\n    var cmd = { limit: 100, nextToken: nextToken, filter: { deleted: { ne: true } } }\n    if (OBS) {\n        var f = getDate()\n        cmd['filter'] = { createdAt: { gt: f } }\n    }\n    gqlOperationWithRetry(autoQuery.listSessions, cmd).then(res => {\n        const dat = res.data.listSessions\n        cb(dat.items)\n        if (dat.nextToken) {\n            listSession(cb, dat.nextToken)\n        }\n    })\n}\n\n// context args: cb, doList, subCB, retryCount=SUB_MAX_RETRY_COUNT\nexport function SessionSubscribeAll(context) {\n    if (context.retryCount === undefined) context.retryCount = SUB_MAX_RETRY_COUNT;\n    if (context.doList) listSession(context.cb, null);\n    const s1 = API.graphql(graphqlOperation(autoSub.onCreateSession, null))\n    var s2 = trySubscribe(s1, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.onCreateSession\n            context.cb([data])\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(false, \"SessionSubscribeAll\",\n                error, null, SessionSubscribeAll, context);\n        }\n    }, \"SessionSubscribeAll\");\n    context.subCB(s2);\n}\n\nexport function createSessionSave(id, name, user, parentId, pageNumber, parentBoardID, boardConfig, classr, jc) {\n    var luid = mylocalStorage.getItem('mystoreID');\n    if (!luid) {\n        luid = uuid()\n        mylocalStorage.setItem('mystoreID', luid)\n    }\n    const cmd = {\n        id: id, 'name': name, ttl: getTTL2Week(),\n        'parentID': parentId, pageNumber: pageNumber, 'savedOwner': user\n    }\n    if (!user) {\n        cmd['savedOwner'] = luid\n    }\n    if (jc) {\n        cmd['joinCode'] = jc\n    } else {\n        cmd['joinCode'] = genJoinCode()\n    }\n    if (classr) {\n        const pgSplit = id.split(\"-pgNum-\")\n        if (pgSplit.length > 1 && pgSplit[1] === \"1\") {\n            getClassroom(classr, function (cl) {\n                if (cl === null || cl === undefined) {\n                    createClassroom({ id: parentId, TeacherID: luid, name: \"myclass\" })\n                } else {\n                    try {\n                        delete cl['Teacher']\n                        delete cl['Users']\n                        delete cl['createdAt']\n                        delete cl['updatedAt']\n                        cl.TeacherID = luid\n                        cl.id = parentId\n                        cl.ttl = cmd.ttl\n                        createClassroom(cl)\n                    } catch (error) {\n                        console.log(\"Class already exists\", error)\n                    }\n                }\n            })\n        }\n        cmd['Classroom'] = parentId\n    }\n    if (boardConfig) cmd['boardConfig'] = boardConfig\n    if (parentBoardID) {\n        cmd['parentBoardID'] = parentBoardID\n    } else {\n        cmd['parentBoardID'] = id//parentId for all otherwise its page to page \n    }\n    cmd['CreatorLocalID'] = luid\n    return createSessionCommon(cmd)\n}\n\nexport function createMultiBoard(parentId, childId, ttl = 0) {\n    const cmd = { id: parentId + \"-\" + childId, parentBoardID: parentId, childBoardID: childId };\n    (!ttl) ? cmd.ttl = getTTL() : cmd.ttl = ttl;\n    return gqlOperationWithRetry(autoMutation.createMultiBoard, { input: cmd });\n}\n\nexport function listMultiBoardbyParent(parentID, cb, nextToken) {\n    const cmd = { limit: 100, nextToken: nextToken, parentBoardID: parentID, filter: { deleted: { ne: true } } }\n    gqlOperationWithRetry(autoQuery.queryByParentID, cmd).then(res => {\n        const dat = res.data.queryByParentID\n        if (dat) cb(dat.items)\n        if (dat.nextToken) {\n            listMultiBoardbyParent(parentID, cb, dat.nextToken)\n        }\n    })\n}\n\n// context args: parentID, cb, delcb, doList, subCB, retryCount=SUB_MAX_RETRY_COUNT\nexport function SessionMultiBoardByParent(context) {\n    if (context.retryCount === undefined) context.retryCount = SUB_MAX_RETRY_COUNT;\n    let retried = false;\n    if (context.doList) listMultiBoardbyParent(context.parentID, context.cb, null);\n    const s1 = API.graphql(graphqlOperation(autoSub.subscribeToMBByParent, { parentBoardID: context.parentID }))\n    var s2, s4;\n    s2 = trySubscribe(s1, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.subscribeToMBByParent\n            context.cb([data])\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(retried, \"SessionMultiBoardByParent:subscribeToMBByParent\",\n                error, s4, SessionMultiBoardByParent, context);\n            retried = true;\n        }\n    }, \"SessionMultiBoardByParent:subscribeToMBByParent\");\n    const s3 = API.graphql(graphqlOperation(autoSub.subscribeToMBByParentDel, { parentBoardID: context.parentID }))\n    s4 = trySubscribe(s3, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.subscribeToMBByParentDel\n            context.delcb(data)\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(retried, \"SessionMultiBoardByParent:subscribeToMBByParentDel\",\n                error, s2, SessionMultiBoardByParent, context);\n            retried = true;\n        }\n    }, \"SessionMultiBoardByParent:subscribeToMBByParentDel\");\n    context.subCB([s2, s4]);\n}\n\nexport function updateClassGroupTTL(classroomID, ttl, nextToken) {\n    const cmd = { limit: 100, nextToken: nextToken, sortDirection: \"ASC\", Classroom: classroomID }\n    gqlOperationWithRetry(autoQuery.queryByGroupsClassroom, cmd).then(res => {\n        const dat = res.data.queryByGroupsClassroom\n        dat.items.forEach((item) => {\n            // update class group TTL\n            if (!item.deleted) {\n                let inputDict = { id: item.id, ttl: ttl };\n                gqlOperationWithRetry(autoMutation.updateClassGroup, { input: inputDict })\n            }\n        })\n        if (dat.nextToken) {\n            updateClassGroupTTL(classroomID, ttl, dat.nextToken)\n        }\n    })\n}\n\nexport function updateClassroomEventsTTL(classroomID, ttl, nextToken) {\n    const cmd = { limit: 100, nextToken: nextToken, sortDirection: \"ASC\", Classroom: classroomID }\n    gqlOperationWithRetry(autoQuery.queryByEventsClassroom, cmd).then(res => {\n        const dat = res.data.queryByEventsClassroom\n        dat.items.forEach((item) => {\n            // update classroom events TTL\n            if (!item.deleted) {\n                let inputDict = { id: item.id, ttl: ttl };\n                gqlOperationWithRetry(autoMutation.updateClassroomEvent, { input: inputDict })\n            }\n        })\n        if (dat.nextToken) {\n            updateClassroomEventsTTL(classroomID, ttl, dat.nextToken)\n        }\n    })\n}\n\nexport function updateLocalUsersTTL(classroomID, ttl, nextToken) {\n    const cmd = { limit: 100, nextToken: nextToken, sortDirection: \"ASC\", ClassroomID: classroomID }\n    gqlOperationWithRetry(autoQuery.queryLocalUserByClass, cmd).then(res => {\n        const dat = res.data.queryLocalUserByClass\n        dat.items.forEach((item) => {\n            // update localusers TTL\n            if (!item.deleted) {\n                let inputDict = { id: item.id, ttl: ttl };\n                gqlOperationWithRetry(autoMutation.updateLocalUsers, { input: inputDict })\n            }\n        })\n        if (dat.nextToken) {\n            updateLocalUsersTTL(classroomID, ttl, dat.nextToken)\n        }\n    })\n}\n\nexport function updateMultiBoardTTL(parentBoardID, ttl, nextToken) {\n    const cmd = { limit: 100, nextToken: nextToken, parentBoardID: parentBoardID, filter: { deleted: { ne: true } } }\n    gqlOperationWithRetry(autoQuery.queryByParentID, cmd).then(res => {\n        const dat = res.data.queryByParentID\n        dat.items.forEach((item) => {\n            // update MultiBoard TTL\n            let inputDict = { id: item.id, ttl: ttl };\n            gqlOperationWithRetry(autoMutation.updateMultiBoard, { input: inputDict })\n        })\n        if (dat.nextToken) {\n            updateMultiBoardTTL(parentBoardID, ttl, dat.nextToken)\n        }\n    })\n}\n\nexport function updateUserTTL(sessionID, ttl, nextToken) {\n    const cmd = { limit: 100, nextToken: nextToken, sortDirection: \"ASC\", SessionID: sessionID }\n    gqlOperationWithRetry(autoQuery.byUsersSessionSorted, cmd).then(res => {\n        const dat = res.data.byUsersSessionSorted\n        dat.items.forEach((item) => {\n            // update user TTL\n            let inputDict = { id: item.id, ttl: ttl };\n            gqlOperationWithRetry(autoMutation.updateUser, { input: inputDict })\n        })\n        if (dat.nextToken) {\n            updateUserTTL(sessionID, ttl, dat.nextToken)\n        }\n    })\n}\n\nfunction getUrlFromMap(urlMap, fullUrl) {\n    const tUrl = fullUrl.split(\"?X-Amz\")[0];\n    return urlMap[tUrl];\n}\n\nfunction setUrlInMap(urlMap, fullUrl, newUrl) {\n    const tUrl = fullUrl.split(\"?X-Amz\")[0];\n    urlMap[tUrl] = newUrl;\n}\n\nfunction getMultiPageId(urlMap, oldUuid) {\n    var multiPageMap = getUrlFromMap(urlMap, 'multiPage');\n    if (!multiPageMap) {\n        multiPageMap = {};\n        setUrlInMap(urlMap, 'multiPage', multiPageMap);\n    }\n    return multiPageMap[oldUuid];\n}\n\nfunction setMultiPageId(urlMap, oldUuid, newUuid) {\n    var multiPageMap = getUrlFromMap(urlMap, 'multiPage');\n    multiPageMap[oldUuid] = newUuid;\n}\n\nasync function checkCopyUrl(urlMap, fullUrl, multiPage = false, inKey = null, xtn = null, noExpire = false) {\n    let checkUrl = getUrlFromMap(urlMap, fullUrl);\n    if (!checkUrl) {\n        // console.log(\"Did not find existing copy, making a new one\", fullUrl);\n        var o, oo, xx;\n        if (!multiPage && (fullUrl.indexOf('-pg-') > 0)) {\n            multiPage = true;\n        }\n        if (multiPage) {\n            o = fullUrl.split('/');\n            oo = o[o.length - 1].split('-pg-');\n            xx = oo[1].split('.');\n            xtn = xx[1];\n            var g = getMultiPageId(urlMap, oo[0]);\n            if (g) {\n                inKey = g + '-pg-' + xx[0];\n                // console.log(\"Found old uuid:\", oo, inKey);\n            } else {\n                g = uuid();\n                inKey = g + '-pg-' + xx[0];\n                // console.log(\"Setting old uuid:\", oo, g, inKey);\n                // Have to set the ID before the call to copyFile, since\n                // the 'await' keyword switches context to another item's processing\n                setMultiPageId(urlMap, oo[0], g);\n            }\n        }\n        checkUrl = await copyFile(fullUrl, inKey, xtn, noExpire);\n        setUrlInMap(urlMap, fullUrl, checkUrl);\n    } else {\n        // console.log(\"Found existing copy:\", fullUrl, checkUrl);\n    }\n\n    return checkUrl;\n}\n\nasync function handleImage(item, urlMap, noExpire = false) {\n    var tContent = item.content;\n    var content = null;\n    tContent = JSON.parse(tContent);\n    if (tContent.type === 'image') {\n        if (tContent.url) {\n            if (tContent.url.match(s3HostPattern)) {\n                // console.log(\"updateObjTTL: gotItem: image\", item, tContent);\n                tContent.url = await checkCopyUrl(urlMap, tContent.url, false, null, null, noExpire);\n                content = JSON.stringify(tContent);\n            } else {\n                // console.log(\"Ignoring non-s3 image url:\", tContent[1].source);\n            }\n        } else {\n            // console.log(\"updateObjTTL: gotItem: NO URL: image:\", item, tContent);\n        }\n    } else if (tContent.type === \"bingo\") {\n        if (tContent.url) {\n            if (tContent.url.match(s3HostPattern)) {\n                // console.log(\"updateObjTTL: gotItem: bingo\", item, tContent);\n                let entries = Object.keys(tContent.pageArray);\n                const tUrl = tContent.url.split(\"?X-Amz\")[0];\n                let uds = tUrl.split('.');\n                let xtn = uds[uds.length - 1];\n                let uss = tUrl.split('/');\n                let oldUuid = uss[uss.length - 1].split('-pg-')[0];\n                let prefix = uss.slice(0, uss.length - 1).join('/');\n                let found = false;\n                for (let ii = 0; ii < entries.length; ii++) {\n                    let fullUrl = prefix + '/' + oldUuid + '-pg-' + entries[ii] + '.' + xtn;\n                    let newUrl = await checkCopyUrl(urlMap, fullUrl, true, null, xtn, noExpire);\n                    if (!found && (fullUrl === tContent.url)) {\n                        tContent.url = newUrl;\n                        found = true;\n                    }\n                }\n                content = JSON.stringify(tContent);\n            } else {\n                // console.log(\"Ignoring non-s3 bingo url:\", tContent[1].source);\n            }\n        } else {\n            // console.log(\"updateObjTTL: gotItem: NO URL: bingo:\", item, tContent);\n        }\n    }\n\n    return content;\n}\n\nasync function handleDrawPaperRaster(item, urlMap, tContent2, t, noExpire = false) {\n    var content = null;\n    if (tContent2[1].source) {\n        if (tContent2[1].source.match(s3HostPattern)) {\n            // console.log(\"updateObjTTL: gotItem: drawPaper\", item, tContent2);\n            var b = (tContent2[1].data && tContent2[1].data.bingo) ? true : false;\n            tContent2[1].source = await checkCopyUrl(urlMap, tContent2[1].source, b, null, null, noExpire);\n            content = JSON.stringify(tContent2);\n            if (t && t.compressed) {\n                content = pako.deflate(content, { to: 'string' });\n            }\n        } else {\n            // console.log(\"Ignoring non-s3 drawPaper source url:\", tContent2[1].source);\n        }\n    } else {\n        // console.log(\"updateObjTTL: gotItem: NO SOURCE: drawPaper:\", item, tContent2);\n    }\n\n    return content;\n}\n\nfunction stringReplaceAll(origStr, whatToReplace, whatToReplaceWith) {\n    var b = new RegExp(whatToReplace, 'g');\n    return origStr.replace(b, whatToReplaceWith);\n}\n\nasync function handleDrawPaperGroup(urlMap, tContent, t, noExpire = false, refresh) {\n    // console.log(\"Found Group\", tContent.match(s3UrlPattern));\n    var files = tContent.match(s3UrlPattern);\n    var files2 = [...new Set(files)];\n    var copied = false;\n    var content;\n\n    // console.log(\"found files in Group\", files, files2);\n    for (let idx in files2) {\n        let process = false\n        if (!refresh) process = true\n        else if (noExpire && (files2[idx] && !files2[idx].includes('/paidImages'))) {\n            process = true;\n        } else if (!noExpire && (files2[idx] && files2[idx].includes('/paidImages'))) {\n            process = true;\n        }\n        if (!process) continue\n        let newUrl = await checkCopyUrl(urlMap, files2[idx], false, null, null, noExpire);\n        // console.log(\"copied url:\", newUrl, files2[idx]);\n        tContent = stringReplaceAll(tContent, files2[idx], newUrl);\n        copied = true;\n    }\n    if (copied) {\n        if (t && t.compressed) {\n            content = pako.deflate(tContent, { to: 'string' });\n        } else {\n            content = tContent;\n        }\n    }\n\n    return content;\n}\n\nexport async function updateObjsContentInternal(item, ttl, urlMap, refresh = false, noExpire = false) {\n    var content = null;\n    if (item.objType === 'drawPaper') {\n        var tContent = item.content;\n        var t = null;\n        if (item.type) {\n            t = JSON.parse(item.type);\n            if (t.compressed) {\n                tContent = pako.inflate(tContent, { to: 'string' });\n            }\n        }\n        var tContent2 = JSON.parse(tContent);\n        // console.log(\"drawPaper:\", tContent2, tContent, s3UrlPattern);\n        if (tContent2[0] === \"Raster\") {\n            // console.log(\"Found Raster\");\n            if (!refresh) {\n                content = await handleDrawPaperRaster(item, urlMap, tContent2, t, noExpire);\n            } else if (noExpire && !tContent2[1].source.includes('/paidImages')) {\n                content = await handleDrawPaperRaster(item, urlMap, tContent2, t, noExpire);\n            } else if (!noExpire && tContent2[1].source.includes('/paidImages')) {\n                content = await handleDrawPaperRaster(item, urlMap, tContent2, t, noExpire);\n            }\n        } else if (tContent2[0] === \"Group\" || tContent2[0] === \"Path\") {\n            content = await handleDrawPaperGroup(urlMap, tContent, t, noExpire, refresh);\n            // var mediaUrl = tContent2[1].data.linkData && tContent2[1].data.linkData.file\n        }\n\n    } else if (item.objType === 'image') {\n        var tContent3 = JSON.parse(item.content);\n        if (!refresh) {\n            content = await handleImage(item, urlMap, noExpire);\n        } else if (noExpire && !tContent3.url.includes('/paidImages')) {\n            content = await handleImage(item, urlMap, noExpire);\n        } else if (!noExpire && tContent3.url.includes('/paidImages')) {\n            content = await handleImage(item, urlMap, noExpire);\n        }\n    }\n    return content\n}\n\nexport async function updateObjsContent(item, ttl, urlMap, refresh = false, noExpire = false) {\n    let content = await updateObjsContentInternal(item, ttl, urlMap, refresh, noExpire)\n    // update Object TTL\n    let inputDict = { id: item.id, ttl: ttl };\n    if (content) {\n        // console.log(\"updateObj: updating content:\", content);\n        inputDict['content'] = content;\n    }\n    return updateObjPlain(inputDict);\n}\n\nexport async function updateObjTTL(sessionID, ttl, nextToken, urlMap, noExpire = false) {\n    const cmd = { limit: 100, nextToken: nextToken, sortDirection: \"ASC\", SessionID: sessionID, filter: { deleted: { ne: true } } }\n    var res = await gqlOperationWithRetry(autoQuery.sessionSorted, cmd);\n    const dat = res.data.sessionSorted\n    for (let idx3 in dat.items) {\n        let item = dat.items[idx3];\n        updateObjsContent(item, ttl, urlMap, true, noExpire)\n    }\n    if (dat.nextToken) {\n        updateObjTTL(sessionID, ttl, dat.nextToken, urlMap, noExpire);\n    }\n}\n\nexport function updateGamePlayTTL(sessionID, ttl, nextToken) {\n    const cmd = { limit: 100, nextToken: nextToken, sortDirection: \"ASC\", Session: sessionID }\n    gqlOperationWithRetry(autoQuery.queryGamePlayBySession, cmd).then(res => {\n        const dat = res.data.queryGamePlayBySession\n        dat.items.forEach((item) => {\n            // update GamePlay TTL\n            let inputDict = { id: item.id, _version: item._version, ttl: ttl };\n            gqlOperationWithRetry(autoMutation.updateGamePlay, { input: inputDict })\n        })\n        if (dat.nextToken) {\n            updateGamePlayTTL(sessionID, ttl, dat.nextToken)\n        }\n    })\n}\n\nfunction adjustContentForMove(obj) {\n    if (obj.objType !== \"drawPaper\") {\n        return obj\n    }\n    try {\n        var type = JSON.parse(obj.type)\n    } catch { }\n    if (type && type.compressed) {\n        var content = pako.inflate(obj.content, { to: 'string' });\n        var data = JSON.parse(content)\n        if (Array.isArray(data) && data[0] === \"Group\") {\n            const paperInfo = data[1]\n            if (paperInfo) {\n                if (paperInfo.data && paperInfo.data.spinner === true) {\n                    paperInfo.data.spinnerId = uuid() // Generate a new spinnerId for the new copy\n                    obj.content = JSON.stringify(data)\n                    return prepObj(obj, true)\n                }\n            }\n        }\n    }\n    return obj\n}\n\nexport function moveObj(sessionID, newSessionID, nextToken, ttl) {\n    if (!ttl) ttl = getTTL();\n    const cmd = { limit: 100, nextToken: nextToken, sortDirection: \"ASC\", SessionID: sessionID, filter: { deleted: { ne: true } } }\n    gqlOperationWithRetry(autoQuery.sessionSorted, cmd).then(res => {\n        const dat = res.data.sessionSorted\n\n        for (let i = 0; i < dat.items.length; i++) {\n\n            let item = dat.items[i]\n            // create new obj in new session\n            item = adjustContentForMove(item)\n            item.SessionID = newSessionID\n            item.ttl = ttl\n\n            // let content = await updateObjsContentInternal(item, ttl, urlMap) too slow to load \n            delete item['id']\n            delete item['Session']\n            // if (content) item.content = content;\n            createObjPlain(item);\n        }\n        if (dat.nextToken) {\n            moveObj(sessionID, newSessionID, dat.nextToken, ttl)\n        }\n    })\n}\n\nexport function undo() {\n    LocalDB.undo()\n}\n\nexport function redo() {\n    LocalDB.redo()\n}\nexport function updateObjPlain(item) {\n    let arg = {\n        ...item,\n        'localDB_table': 'Object',\n        'localDB_opertaion': 'update',\n        // 'localDB_mutation': autoMutation.updateObject\n    }\n    if (!window.mydb) {\n        return gqlOperationWithRetry(autoMutation.updateObject, { input: item });\n    }\n    return LocalDB.createObj(arg)\n}\n\n\nexport function createObjPlain(item) {\n    let sss = mylocalStorage.getItem('syncDisabled')\n    if (sss) item['DisableSync'] = 'disabled'\n    let arg = {\n        ...item,\n        'localDB_table': 'Object',\n        'localDB_opertaion': 'create',\n        // 'localDB_mutation': autoMutation.createObject\n    }\n    if (!window.mydb || !item.id) {\n        return gqlOperationWithRetry(autoMutation.createObject, { input: item })\n    }\n    return LocalDB.createObj(arg)\n}\n\nexport function listObjectLocal(sessionID, nextToken, cb) {\n    const cmd = { limit: 100, nextToken: nextToken, sortDirection: \"ASC\", SessionID: sessionID, filter: { deleted: { ne: true } } }\n    gqlOperationWithRetry(autoQuery.sessionSorted, cmd).then(res => {\n        const dat = res.data.sessionSorted\n\n\n        LocalDB.gotObjs(JSON.parse(JSON.stringify(dat.items)))\n        cb(dat.items)\n        if (dat.nextToken) {\n            listObject(sessionID, dat.nextToken, cb)\n        }\n    })\n}\n\nexport function localObjCB(dat, cb) {\n\n}\n\nexport function validateObjContent(obj, str) {\n    let newobj = {}\n    function printErr() {\n        console.log(\"=================================\")\n        console.log(\"==============\", str, \"=================\")\n\n        console.log(\"=================================\")\n    }\n    try {\n        if ('type' in obj && obj['type']) {\n            if (obj['type'].length <= 1) {\n                printErr()\n                console.error(\"OBJ TOO SHORT\", obj)\n            } else {\n                try {\n                    newobj['type'] = JSON.parse(obj['type'])\n                } catch {\n                }\n                if (obj.type && obj.type.compressed) {\n                    newobj.content = pako.inflate(obj.content, { to: 'string' });\n                }\n            }\n        }\n    } catch (e) {\n        printErr()\n        console.error(\"cannot decode\", e, obj, typeof obj['type'])\n        // return\n    }\n}\n// context args: sessionID, cb, delCB, subCB, doList, retryCount=SUB_MAX_RETRY_COUNT\nexport function ObjectSubscribeLocal(context) {\n    LocalDB.registerCB(context.cb, context.delCB, callDispatch, context)\n\n    if (context.retryCount === undefined) context.retryCount = SUB_MAX_RETRY_COUNT;\n    if (context.doList) listObjectLocal(context.sessionID, null, context.cb)\n    const s1 = API.graphql(graphqlOperation(autoSub.subscribeToSessionObjects, { SessionID: context.sessionID }))\n    var s2, s4;\n    let retried = false;\n    s2 = trySubscribe(s1, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.subscribeToSessionObjects\n            LocalDB.gotObjs([data])\n\n            if (!data.deleted) {\n                context.cb([data])\n            } else {\n                context.delCB(data)\n            }\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(retried, \"ObjectSubscribeLocal:subscribeToSessionObjects\",\n                error, s4, ObjectSubscribe, context);\n            retried = true;\n        }\n    }, \"ObjectSubscribeLocal:subscribeToSessionObjects\");\n    context.subCB([s2, s4])\n}\n\nexport function createObj(sessionID, item, cb, sessTtl) {\n    // const dat = obj //jsonobjt\n    // create new obj with new sessionID\n    item.SessionID = sessionID\n    item.ttl = sessTtl\n    item.name = 'import'\n    delete item['id']\n    delete item['Session']\n    delete item['createdAt']\n    delete item['updatedAt']\n    delete item['imgB64']\n    // console.log('obj item',item)\n    createObjPlain(item).then(res => {\n        // console.log('success res', res)\n        cb(res)\n    })\n}\n\nexport function getAllBoards(parentID, nextToken, cb) {\n    const cmd = { limit: 100, nextToken: nextToken, sortDirection: \"ASC\", parentID: parentID }\n\n    gqlOperationWithRetry(autoQuery.queryByParent, cmd).then(res => {\n        const dat = res.data.queryByParent\n        cb(dat.items)\n        if (dat.nextToken) {\n            getboardsbyparent(parentID, dat.nextToken, cb)\n        }\n    })\n}\n\nexport function getboardsbyparent(parentID, nextToken, cb) {\n    const cmd = { limit: 100, nextToken: nextToken, sortDirection: \"ASC\", parentID: parentID, filter: { deleted: { ne: true } } }\n\n    gqlOperationWithRetry(autoQuery.queryByParent, cmd).then(res => {\n        const dat = res.data.queryByParent\n        cb(dat.items)\n        if (dat.nextToken) {\n            getboardsbyparent(parentID, dat.nextToken, cb)\n        } else {\n            cb(null)\n        }\n    })\n}\nexport async function refreshBoard(id, urlMap, noExpire = false, oldExpiry) {\n    var ttl = 0\n    var paidUserPlan = userPaidPlan();\n    if (noExpire || uUtils.userHasNoBoardExpiry()) {\n        ttl = NO_EXPIRY_TTL\n    } else if (!paidUserPlan || paidUserPlan === 'educator-free') {\n        ttl = getTTLForDays(7)\n    } else {\n        ttl = getTTLForDays(7 * 4) //4weeks\n    }\n    const pgSplit = id.split(\"-pgNum-\")\n    // getboardsbyparent(pgSplit[0], null, gotPages)\n    let pages = await getboardsbyparentSync(pgSplit[0]);\n    if (ttl !== NO_EXPIRY_TTL && oldExpiry !== undefined && (ttl * 1000) < oldExpiry) {\n        return\n    }\n    await gotPages(pages);\n    // Since we have just the ID, just make a call to\n    // getClassroom. If there is no such classroom, we\n    // will get a null in the callback function\n    let classroom = await getClassroomSync(pgSplit[0]);\n\n    if (classroom) {\n        updateMultiBoardTTL(classroom.id + \"-pgNum-1\", ttl, null);\n        updateLocalUsersTTL(classroom.id, ttl, null);\n        updateClassroomEventsTTL(classroom.id, ttl, null);\n        updateClassGroupTTL(classroom.id, ttl, null);\n        await updateClassroom({ id: classroom.id, ttl: ttl });\n    }\n\n    async function gotPages(items) {\n        if (!items) return\n        for (let ii = 0; ii < items.length; ii++) {\n            let item = items[ii];\n            // console.log(\"Updating session:\", item.id);\n            await updateObjTTL(item.id, ttl, null, urlMap, noExpire);\n            updateUserTTL(item.id, ttl, null)\n            updateGamePlayTTL(item.id, ttl, null)\n            let updateDict = { id: item.id, ttl: ttl };\n\n            // If the session has an empty string folderID\n            // then the updateSession will fail. We have to\n            // remove the folderID column in that case. To do this,\n            // we update with the field set to null to remove it from\n            // the session object in DynamoDB.\n            if (item.folderID === \"\") {\n                updateDict['folderID'] = null;\n            }\n\n            await updateSession(updateDict);\n        }\n    }\n\n    return ttl;\n}\n\nexport function saveBoard(name, user, id, cb) {\n    const pgSplit = id.split(\"-pgNum-\")\n    const ids = uuid()\n\n    //find all the pages\n    getboardsbyparent(pgSplit[0], null, gotPages)\n\n    function gotPages(items) {\n        if (!items) return\n        items.forEach((item) => {\n            const ipgSplit = item.id.split(\"-pgNum-\")\n            const pg1 = ids + \"-pgNum-\" + ipgSplit[1]\n            var pbid = pg1\n\n            if (item.id !== item.parentBoardID) {\n                //complext? copy the object from the parents too\n                //pbid = item.parentBoardID\n            }\n            createSessionSave(pg1, name, user, ids, ipgSplit[1], pbid, item.boardConfig,\n                item.Classroom).then((res) => {\n                    const back = res.data.createSession\n                    moveObj(item.id, back.id, null, back.ttl)\n                    if (item.id !== item.parentBoardID) {\n                        moveObj(item.parentBoardID, back.id, null, back.ttl)\n\n                    }\n                    if (ipgSplit[1] === \"1\" && cb) {\n                        updateEvents(back, item)\n                        cb(pg1)\n                    }\n                    //move all old objects\n                })\n        })\n    }\n    function updateEvents(sess, item) {\n        function gotEvent(events) {\n            for (let i = 0; i < events.length; i++) {\n                var e = events[i]\n                if (e.For === e.Classroom) {\n                    //copy only classroom events \n                    e.For = sess.Classroom\n                    e.Classroom = sess.Classroom\n                    var rep = e.event.replace(item.Classroom, sess.Classroom)\n                    rep = rep.replace(item.Classroom, sess.Classroom)\n                    e.event = rep\n                    e.id = rep\n                    e.ttl = sess.ttl\n                    createClassroomEvent(e)\n                }\n            }\n        }\n        function gotClass(classes) {\n            for (let i = 0; i < classes.length; i++) {\n                var e = classes[i]\n                var cc = JSON.parse(e.content)\n                if (e.content.includes(\"precog\")) {\n                    createGroupForClass(e.name, cc.members, sess, null, null)\n                }\n            }\n        }\n        if (item.Classroom) {\n            listClassroomEventByClass(item.Classroom, gotEvent, null)\n            listClassGroupByClass(item.Classroom, gotClass, null)\n        }\n    }\n}\n\n\nexport function importBoard(user, sessions, objects, cb) {\n    const ids = uuid()\n    //get all sessions\n    //todo check with sid and add logic to fetch and check whether already session is there or not?\n    if (!sessions) return\n    sessions.forEach((item) => {\n        const ipgSplit = item.id.split(\"-pgNum-\")\n        const pg1 = ids + \"-pgNum-\" + ipgSplit[1]\n        var pbid = pg1\n\n        createSessionSave(pg1, item.name, user, ids, ipgSplit[1], pbid, item.boardConfig,\n            item.Classroom).then((res) => {\n                const back = res.data.createSession\n                //filter out the objects which has pgSplit[0] - old sessionId\n                // console.log('response', back)\n                if (!objects || objects.length === 0) {\n                    cb(back)\n                    return\n                }\n                var filteredObjs = objects.filter(o => o.SessionID === item.id)\n                // todo: need  to tweak in the code for the case co-teacher as co-teachers board will have sessionId and objects relate but in case of coteacher those object will be having the teacher's board id and the objectes are not imported for co-teacher\n                if (!filteredObjs || filteredObjs.length === 0) {\n                    cb(back)\n                    return\n                }\n                // console.log('filterobj', filteredObjs)\n                var objCount = 0\n                for (var ob of filteredObjs) {\n                    createObj(back.id, ob, cdDoneObj, back.ttl)\n                }\n\n                function cdDoneObj(item) {\n                    objCount++\n                    if (objCount === filteredObjs.length) {\n                        cb(back)\n                    }\n                }\n            })\n    })\n}\n\nexport function makePageCopy(id, sess, cb) {\n    const pgSplit = id.split(\"-pgNum-\")\n\n    getboardsbyparent(pgSplit[0], null, gotPages)\n    function gotPages(items) {\n        if (!items) return\n        var allItems = []\n        var lastpage = 0\n        for (let i = 0; i < items.length; i++) {\n            const item = items[i]\n            const ipgSplit = item.id.split(\"-pgNum-\")\n            const pggg = parseInt(ipgSplit[1])\n            allItems[pggg] = item\n            if (lastpage < pggg) lastpage = pggg\n        }\n        var last = lastpage + 1\n\n        for (let i = 1; i <= lastpage; i++) {\n            if (!allItems[i]) {\n                last = i\n                break\n            }\n        }\n\n        if (last === 0) last = items.length\n        var np = last\n        const pg1 = pgSplit[0] + \"-pgNum-\" + np\n        var pbid = pg1\n        createSessionSave(pg1, sess.name, sess.savedOwner, pgSplit[0],\n            np, pbid, sess.boardConfig,\n            sess.Classroom, sess.joinCode).then((res) => {\n                const back = res.data.createSession\n                moveObj(sess.id, back.id, null, back.ttl)\n                if (sess.id !== sess.parentBoardID) {\n                    moveObj(sess.parentBoardID, back.id, null, back.ttl)\n                }\n                cb(np, true)\n                //move all old objects\n            })\n    }\n}\n\n// If null is passed for path, the result will be\n// that the folderID field will be removed from\n// the session object. Since there is a secondary index\n// on the folderID field, we cannot set it to an empty\n// string if we have to move anything to the root folder.\n// We need to delete the field from the object in that case.\n// To not update the path, pass the path as \"undefined\"\nexport function setName(row, path, passCurUpdatedAt) {\n    const newName = row.name\n    var pp = row.id.split(\"-pgNum-\")\n    getboardsbyparent(pp[0], null, renamePages)\n    function renamePages(items) {\n        if (!items) return\n        items.forEach((item) => {\n            let tmpItem = {\n                id: item.id,\n                name: newName\n            }\n            if (path !== undefined) tmpItem.folderID = path;\n            if (passCurUpdatedAt) tmpItem.updatedAt = item.updatedAt;\n            updateSession(tmpItem)\n        })\n    }\n}\n\nexport function listClassroomByTeacher(ownerid, cb, nextToken) {\n    const cmd = { limit: 100, nextToken: nextToken, TeacherID: ownerid, sortDirection: \"ASC\" }\n    gqlOperationWithRetry(autoQuery.queryByTeacher, cmd).then(res => {\n        const dat = res.data.queryByTeacher\n        if (dat) cb(dat.items)\n        if (dat.nextToken) {\n            listClassroomByTeacher(ownerid, cb, dat.nextToken)\n        }\n    })\n}\n\nexport function listSessionByOwner(ownerid, cb, nextToken) {\n    const cmd = { limit: 100, nextToken: nextToken, savedOwner: ownerid, sortDirection: \"ASC\", filter: { deleted: { ne: true } } }\n    cmd['filter'] = { and: { deleted: { ne: true }, pageNumber: { eq: 1 } } }\n\n    gqlOperationWithRetry(customops.queryBySavedOwner, cmd).then(res => {\n        const dat = res.data.queryBySavedOwner\n        if (dat) cb(dat.items, dat.nextToken)\n        if (dat.nextToken) {\n            listSessionByOwner(ownerid, cb, dat.nextToken)\n        }\n    })\n}\n\n// context args: ownerid, cb, delcb, doList, subCB, retryCount=SUB_MAX_RETRY_COUNT\nexport function SessionSubscribeByOwner(context) {\n    if (context.retryCount === undefined) context.retryCount = SUB_MAX_RETRY_COUNT;\n    if (context.doList) listSessionByOwner(context.ownerid, context.cb, null);\n    const s1 = API.graphql(graphqlOperation(autoSub.subscribeToSessionbyOwner, { savedOwner: context.ownerid }))\n    var s2, s4;\n    let retried = false;\n    s2 = trySubscribe(s1, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.subscribeToSessionbyOwner\n            if (!data.deleted) {\n                context.cb([data])\n            } else {\n                context.delcb(data)\n            }\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(retried, \"SessionSubscribeByOwner:subscribeToSessionbyOwner\",\n                error, s4, SessionSubscribeByOwner, context);\n            retried = true;\n        }\n    }, \"SessionSubscribeByOwner:subscribeToSessionbyOwner\");\n    const s3 = API.graphql(graphqlOperation(autoSub.subscribeToSessionDelbyOwner, { savedOwner: context.ownerid }))\n    s4 = trySubscribe(s3, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.subscribeToSessionDelbyOwner\n            context.delcb(data)\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(retried, \"SessionSubscribeByOwner:subscribeToSessionDelbyOwner\",\n                error, s2, SessionSubscribeByOwner, context);\n            retried = true;\n        }\n    }, \"SessionSubscribeByOwner:subscribeToSessionDelbyOwner\");\n    context.subCB([s2, s4]);\n}\n\nexport function listSessionByparentBoardID(parentBoardID, cb, nextToken) {\n    const cmd = { limit: 100, nextToken: nextToken, parentBoardID: parentBoardID, filter: { deleted: { ne: true } } }\n    gqlOperationWithRetry(autoQuery.queryByparentBoardID, cmd).then(res => {\n        const dat = res.data.queryByparentBoardID\n        if (dat) cb(dat.items)\n        if (dat.nextToken) {\n            listSessionByparentBoardID(parentBoardID, cb, dat.nextToken)\n        }\n    })\n}\n\n// context args: parentBoardID, cb, delcb, doList, subCB, retryCount=SUB_MAX_RETRY_COUNT\nexport function SessionSubscribeByparentBoardID(context) {\n    if (context.retryCount === undefined) context.retryCount = SUB_MAX_RETRY_COUNT;\n    if (context.doList) listSessionByparentBoardID(context.parentBoardID, context.cb, null);\n    const s1 = API.graphql(graphqlOperation(autoSub.subscribeToSessionbyparentBoardID, { parentBoardID: context.parentBoardID }))\n    var s2, s4;\n    let retried = false;\n    s2 = trySubscribe(s1, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.subscribeToSessionbyparentBoardID\n            if (!data.deleted) {\n                context.cb([data])\n            } else {\n                context.delcb(data)\n\n            }\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(retried, \"SessionSubscribeByparentBoardID:subscribeToSessionbyparentBoardID\",\n                error, s4, SessionSubscribeByparentBoardID, context);\n            retried = true;\n        }\n    }, \"parentBoardID:subscribeToSessionbyparentBoardID\");\n    const s3 = API.graphql(graphqlOperation(autoSub.subscribeToSessionDelbyparentBoardID, { parentBoardID: context.parentBoardID }))\n    s4 = trySubscribe(s3, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.subscribeToSessionDelbyparentBoardID\n            context.delcb(data)\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(retried, \"SessionSubscribeByparentBoardID:subscribeToSessionDelbyparentBoardID\",\n                error, s2, SessionSubscribeByparentBoardID, context);\n            retried = true;\n        }\n    }, \"SessionSubscribeByparentBoardID:subscribeToSessionDelbyparentBoardID\");\n    context.subCB([s2, s4]);\n}\n\nexport function createClassroom(cmd) {\n    if (!cmd.ttl) cmd.ttl = getTTL();\n    cmd['TeacherList'] = [cmd['TeacherID']]\n    return gqlOperationWithRetry(autoMutation.createClassroom, { input: cmd });\n}\n\nexport function updateClassroom(cmd) {\n    //here \n    sendClassEvent(\"SUBSCRIBE-CLASS\", true, cmd.id, cmd.id, cmd.id, cmd.ttl, true, null);\n\n    return gqlOperationWithRetry(autoMutation.updateClassroom, { input: cmd });\n}\n\nexport function getClassroom(id, cb) {\n    gqlOperationWithRetry(autoQuery.getClassroom, { id: id }).then(res => {\n        const dat = res.data.getClassroom\n        cb(dat)\n    })\n}\n\nexport async function getClassroomSync(id) {\n    let res = await gqlOperationWithRetry(autoQuery.getClassroom, { id: id });\n    return res.data.getClassroom;\n}\n\n// context args: id, cb, doList, subCB, retryCount=SUB_MAX_RETRY_COUNT\nexport function ClassroomSubscribe(context) {\n    if (context.retryCount === undefined) context.retryCount = SUB_MAX_RETRY_COUNT;\n    if (context.doList) getClassroom(context.id, context.cb);\n    const s1 = API.graphql(graphqlOperation(autoSub.subscribeToClassroomById, { id: context.id }))\n    var s2 = trySubscribe(s1, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.subscribeToClassroomById\n            context.cb(data)\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(false, \"ClassroomSubscribe\",\n                error, null, ClassroomSubscribe, context);\n        }\n    }, \"ClassroomSubscribe\");\n    context.subCB(s2);\n}\n\nexport function deleteLocalUsers(id) {\n    let cmd = { id: id }\n    setupdel(cmd)\n\n    return updateLocalUsers(cmd)\n    // return gqlOperationWithRetry(autoMutation.deleteLocalUsers, { input: { id: id } });\n}\nexport function getLocalUsers(id) {\n    return gqlOperationWithRetry(autoQuery.getLocalUsers, { id: id });\n}\n\nexport function createLocalUsers(cmd) {\n    if (!cmd.ttl) cmd.ttl = getTTL();\n    return gqlOperationWithRetry(autoMutation.createLocalUsers, { input: cmd });\n}\n\nexport function updateLocalUsers(cmd) {\n    return gqlOperationWithRetry(autoMutation.updateLocalUsers, { input: cmd });\n}\n\nexport function listLocalUsersByClass(ClassroomID, cb, nextToken) {\n    const cmd = { limit: 100, nextToken: nextToken, ClassroomID: ClassroomID, filter: { deleted: { ne: true } } }\n    gqlOperationWithRetry(autoQuery.queryLocalUserByClass, cmd).then(res => {\n        const dat = res.data.queryLocalUserByClass\n        if (dat) cb(dat.items)\n        if (dat.nextToken) {\n            listLocalUsersByClass(ClassroomID, cb, dat.nextToken)\n        }\n    })\n}\n\n// context args: ClassroomID, cb, delCB, doList, subCB, retryCount=SUB_MAX_RETRY_COUNT\nexport function SubscribeLocalUsersByClass(context) {\n    if (context.retryCount === undefined) context.retryCount = SUB_MAX_RETRY_COUNT;\n    if (context.doList) listLocalUsersByClass(context.ClassroomID, context.cb, null)\n    const s1 = API.graphql(graphqlOperation(autoSub.subscribeToLocalUsersByClass, { ClassroomID: context.ClassroomID }))\n    var s2, s4;\n    let retried = false;\n    s2 = trySubscribe(s1, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.subscribeToLocalUsersByClass\n            if (!data.deleted) {\n                context.cb([data])\n            } else {\n                context.delCB(data)\n            }\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(retried, \"SubscribeLocalUsersByClass:subscribeToLocalUsersByClass\",\n                error, s4, SubscribeLocalUsersByClass, context);\n            retried = true;\n        }\n    }, \"SubscribeLocalUsersByClass:subscribeToLocalUsersByClass\");\n\n    context.subCB([s2, s4]);\n}\n\nexport async function getSessionByClassroomSync(Classroom) {\n    var allList = []\n    var nt = null\n    do {\n        const cmd = { limit: 100, nextToken: nt, sortDirection: \"ASC\", Classroom: Classroom, filter: { deleted: { ne: true } } }\n\n        var res = await gqlOperationWithRetry(customops.queryByClassroom, cmd)\n        const dat = res.data.queryByClassroom\n        allList = [...allList, ...dat.items]\n        nt = dat.nextToken\n    } while (nt !== null)\n    return allList\n}\n\nexport function listSessionByClassroom(Classroom, cb, nextToken, custom, filter) {\n    let q = custom ? customops.queryByClassroom : autoQuery.queryByClassroom\n    var cmd = { limit: 100, nextToken: nextToken, Classroom: Classroom, sortDirection: \"ASC\" }\n    if (filter) {\n        cmd['filter'] = filter\n    } else {\n        cmd['filter'] = { deleted: { ne: true } }\n    }\n    gqlOperationWithRetry(q, cmd).then(res => {\n        const dat = res.data.queryByClassroom\n        if (dat) cb(dat.items, dat.nextToken)\n        if (dat.nextToken) {\n            listSessionByClassroom(Classroom, cb, dat.nextToken, custom, filter)\n        }\n    })\n}\n\n// context args: Classroom, cb, doList, subCB, retryCount=SUB_MAX_RETRY_COUNT\nexport function SessionSubscribeByClassroom(context) {\n    if (context.retryCount === undefined) context.retryCount = SUB_MAX_RETRY_COUNT;\n    if (context.doList) listSessionByClassroom(context.Classroom, context.cb, null, false, null);\n    const s1 = API.graphql(graphqlOperation(autoSub.subscribeToSessionbyClassroom, { Classroom: context.Classroom }))\n    var s2 = trySubscribe(s1, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.subscribeToSessionbyClassroom\n            context.cb([data])\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(false, \"SessionSubscribeByClassroom\",\n                error, null, SessionSubscribeByClassroom, context);\n        }\n    }, \"SessionSubscribeByClassroom\");\n    context.subCB(s2);\n}\n\n//  re-orders the pages and updates the board order\nexport async function addPageOrder(sess, req) {\n    var boardOrder = null\n    let max = 0\n    if (sess.boardConfig) {\n        const boardConf = await getSession(sess.parentID + \"-pgNum-1\");\n        var bc = JSON.parse(boardConf.data.getSession.boardConfig);\n        if (bc.boardOrder) {\n            boardOrder = bc.boardOrder.order\n            max = Math.max(...Object.keys(boardOrder));\n            // if(Object.values(boardOrder).includes(req)) return;\n            boardOrder[max + 1] = req\n        }\n    }\n    if (boardOrder) {\n        bc.boardOrder.order = boardOrder\n        bc.boardOrder.max = req\n        await updateClassBoardsOrderAll(sess, bc.boardOrder)\n    }\n    return req\n\n}\n\nexport async function addPage(sess, req) {\n    var boardOrder = null\n    let max = 0\n    var plusOne = 0\n    if (sess.boardConfig) {\n        var bc = JSON.parse(sess.boardConfig)\n        if (bc.boardOrder) {\n            boardOrder = bc.boardOrder.order\n            for (let i in boardOrder) {\n                let m = boardOrder[i]\n                if (m > max) {\n                    max = m;\n                }\n            }\n            plusOne = max + 1\n            boardOrder[req] = plusOne\n        }\n    }\n    if (boardOrder) {\n        bc.boardOrder.order = boardOrder\n        bc.boardOrder.max = plusOne\n        await updateClassBoardsOrderAll(sess, bc.boardOrder)\n        await duplicatePage(sess.id, plusOne, false)\n        return plusOne\n    }\n    return req\n}\n\nexport function clearAllBoards(sess, mode) {\n    function updateBoards(items) {\n        if (!items) return\n        items.forEach((item) => {\n            var teacherBoard = false\n            if (item.parentBoardID === item.id) teacherBoard = true\n            if (mode === \"all\" || !teacherBoard)\n                delAllObjSession(item.id)\n            if (mode === \"studentAndPages\" && !teacherBoard) {\n\n                deleteSessionPlain(item.id)\n            }\n        })\n    }\n    if (mode === \"all\") {\n        getboardsbyparent(sess.parentID, null, gotBoards)\n    }\n    function gotBoards(items) {\n        updateBoards(items)\n    }\n    if (sess.Classroom) {\n        listSessionByClassroom(sess.Classroom, gotBoards, null, false, null)\n        if (mode === \"studentAndPages\") {\n            listLocalUsersByClass(sess.Classroom, foundUser, null)\n        }\n    }\n    function foundUser(us) {\n        var luid = mylocalStorage.getItem('mystoreID');\n        us.forEach((u) => {\n            var vv = u.id.split(\"-CL-\")\n            var local = vv[0]\n            if (local === luid) {\n                return\n            }\n            if (u && u.CurrentUser) {\n                deleteUser(u.CurrentUser)\n            }\n            deleteLocalUsers(u.id)\n        })\n    }\n}\n\nexport function delOldUser(sess, timeMin) {\n    if (!sess || !sess.Users) return\n    var anydels = false\n    var now = new Date()\n    for (let i = 0; i < sess.Users.items.length; i++) {\n        let d = sess.Users.items[i]\n        let c = JSON.parse(d.content)\n        if (c.localID === sess.CreatorLocalID) {\n            continue\n        }\n        const dt1 = new Date(d.updatedAt)\n        var diff = (now - dt1) / 1000\n        if (diff > (parseInt(timeMin) * 60)) {\n            //more than an hour\n            deleteUser(d)\n            anydels = true\n        }\n    }\n    if (anydels) {\n        windowreload()\n    }\n}\n\nexport function pushURL(props, url) {\n    var u = url\n    if (url.includes(\"?\") && !(url.includes(\"apiaccess\"))) {\n        u = \"/apiaccess\" + url\n    }\n    props.history.push(u)\n}\n\nexport function CellPhoneCall(sess, enable, participantId = null, allVideo = false) {\n    var luid = mylocalStorage.getItem('mystoreID');\n    function updateBoards(items) {\n        if (!items) return\n        items.forEach((item) => {\n            if (item.CreatorLocalID === participantId || item.CreatorLocalID === luid || allVideo) {\n                let jj = item.boardConfig ? JSON.parse(item.boardConfig) : {}\n                jj['Video'] = enable\n                if (allVideo) {\n                    jj['allTVideo'] = enable\n                }\n\n                item.boardConfig = JSON.stringify(jj)\n                updateSession(item)\n            }\n        })\n    }\n    getboardsbyparent(sess.parentID, null, gotBoards)\n    function gotBoards(items) {\n        updateBoards(items)\n    }\n    if (sess.Classroom) {\n        listSessionByClassroom(sess.Classroom, gotBoards, null, false, null)\n    }\n}\nexport function VideoConferenceSet(sess, enable, participantId = null) {\n    // var jj = sess.boardConfig ? JSON.parse(sess.boardConfig) : {}\n    // jj['Video'] = true\n    // sess.boardConfig = JSON.stringify(jj)\n    // updateSession(sess)\n    function updateBoards(items) {\n        if (!items) return\n        let filteredItems = []\n        if (participantId) {\n            filteredItems = items.filter(i => i.CreatorLocalID === participantId)\n        } else {\n            filteredItems = items\n        }\n        filteredItems.forEach((item) => {\n            let jj = item.boardConfig ? JSON.parse(item.boardConfig) : {}\n            jj['Video'] = enable\n            item.boardConfig = JSON.stringify(jj)\n            updateSession(item)\n        })\n    }\n    getboardsbyparent(sess.parentID, null, gotBoards)\n    function gotBoards(items) {\n        updateBoards(items)\n    }\n    if (sess.Classroom) {\n        listSessionByClassroom(sess.Classroom, gotBoards, null, false, null)\n    }\n}\n\n\nexport function boardLabelSet(sess, labels) {\n    getboardsbyparent(sess.parentID, null, gotBoards)\n    function gotBoards(items) {\n        if (!items) return\n        items.forEach((item) => {\n            let jj = item.boardConfig ? JSON.parse(item.boardConfig) : {}\n            jj[\"Labels\"] = labels\n            item.boardConfig = JSON.stringify(jj)\n            updateSession(item)\n        })\n    }\n}\n\nexport function boardNameSet(sess, name) {\n    getboardsbyparent(sess.parentID, null, gotBoards)\n    function gotBoards(items) {\n        if (!items) return\n        items.forEach((item) => {\n            item.name = name\n            updateSession(item)\n        })\n    }\n}\n\nexport function boardConfigSet(sess, key, enable) {\n    // var jj = sess.boardConfig ? JSON.parse(sess.boardConfig) : {}\n    // jj['Video'] = true\n    // sess.boardConfig = JSON.stringify(jj)\n    // updateSession(sess)\n    function updateBoards(items) {\n        if (!items) return\n        items.forEach((item) => {\n            let jj = item.boardConfig ? JSON.parse(item.boardConfig) : {}\n            jj[key] = enable\n            item.boardConfig = JSON.stringify(jj)\n            updateSession(item)\n        })\n    }\n    getboardsbyparent(sess.parentID, null, gotBoards)\n    function gotBoards(items) {\n        updateBoards(items)\n    }\n    if (sess.Classroom) {\n        listSessionByClassroom(sess.Classroom, gotBoards, null, false, null)\n    }\n}\n\nexport function getUserInfo(u) {\n    var name = null;\n    var avatar = null;\n\n    if (!u || !u.username) return { \"name\": \"unknown\", \"avatar\": null }\n\n    if (u.username.startsWith(\"Facebook_\")) {\n        // This is a facebook user\n        const fbUserId = u.username.split(\"_\")[1];\n        avatar = `https://graph.facebook.com/${fbUserId}/picture?type=large`\n        if (u.attributes.name) {\n            name = u.attributes.name;\n        }\n    } else if (u.username.startsWith(\"Google_\")) {\n        if (u.attributes.picture) {\n            avatar = u.attributes.picture;\n            avatar = avatar.replace(/=s96-c$/, \"=s192-c\");\n        }\n\n        if (u.attributes.name) {\n            name = u.attributes.name;\n        }\n    }\n\n    return { \"name\": name, \"avatar\": avatar };\n}\n\n/**** groups */\n\nexport function getCurrentSession() {\n    const JOINURL = window.location.href.split(\"/board/\")\n    var sessID = JOINURL[1]\n    if (sessID.includes('?')) {\n        // Remove url parameters\n        sessID = sessID.split('?')[0]\n    }\n    return getSession(sessID)\n}\nexport function createClassGroup(cmd) {\n    if (!cmd.ttl) cmd.ttl = getTTL();\n    //enable subscriptions for stuff\n    sendClassEvent(\"SUBSCRIBE-GROUP\", true, cmd.Classroom, cmd.Classroom, cmd.id, cmd.ttl, true, null);\n    return gqlOperationWithRetry(autoMutation.createClassGroup, { input: cmd });\n}\n\nexport function updateClassGroup(cmd) {\n    return gqlOperationWithRetry(autoMutation.updateClassGroup, { input: cmd });\n}\nexport function deleteClassGroup(cmd) {\n    setupdel(cmd)\n    return updateClassGroup(cmd)\n    // return gqlOperationWithRetry(autoMutation.deleteClassGroup, { input: { id: cmd.id } });\n\n}\nexport function listClassGroupByClass(ClassroomID, cb, nextToken) {\n    const cmd = { limit: 100, nextToken: nextToken, Classroom: ClassroomID, filter: { deleted: { ne: true } } }\n    gqlOperationWithRetry(autoQuery.queryByGroupsClassroom, cmd).then(res => {\n        const dat = res.data.queryByGroupsClassroom\n        if (dat) cb(dat.items, false)\n        if (dat.nextToken) {\n            listClassGroupByClass(ClassroomID, cb, dat.nextToken)\n        }\n    })\n}\n\n// context args: ClassroomID, cb, delCB, doList, subCB, retryCount=SUB_MAX_RETRY_COUNT\nexport function SubscribeClassGroupByClass(context) {\n    if (context.retryCount === undefined) context.retryCount = SUB_MAX_RETRY_COUNT;\n    if (context.doList) listClassGroupByClass(context.ClassroomID, context.cb, null)\n    const s1 = API.graphql(graphqlOperation(autoSub.subscribeToClassGroup, { Classroom: context.ClassroomID }))\n    let retried = false;\n    var s2, s4;\n    s2 = trySubscribe(s1, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.subscribeToClassGroup\n            if (!data.deleted) {\n                context.cb([data], true)\n            } else {\n                context.delCB(data)\n\n            }\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(retried, \"SubscribeClassGroupByClass:subscribeToClassGroup\",\n                error, s4, SubscribeClassGroupByClass, context);\n            retried = true;\n        }\n    }, \"SubscribeClassGroupByClass:subscribeToClassGroup\");\n\n    context.subCB([s2, s4]);\n}\n\nexport function createGroupForClass(name, members, sess, cb, idPass, NoOfStuds) {\n    if (sess) {\n        const id = idPass ? idPass : uuid()\n        const pg1 = id + \"-pgNum-1\"\n        var foundPreCog = false\n        for (let i = 0; i < members.length; i++) {\n            if (members[i].type && members[i].type === \"precog\") {\n                foundPreCog = true\n            }\n        }\n        var bc = sess.boardConfig;\n        try {\n            bc = JSON.parse(sess.boardConfig)\n            if (!bc.hasPreCogs && foundPreCog) {\n                bc.hasPreCogs = true\n                sess.boardConfig = JSON.stringify(bc)\n                updateSession(sess)\n            }\n        } catch (e) {\n            console.log(\"ERROR IS \", e)\n        }\n\n        //parentBoard should ID 1 too incase teacher clicked on new board\n        const pgSplit = sess.parentBoardID.split(\"-pgNum-\")\n        const ppid = pgSplit[0] + \"-pgNum-1\"\n        createMultiBoard(ppid, id, sess.ttl)\n        createSession(pg1, \"group-\" + name, \"somecontent\",\n            id, 1, ppid, sess.boardConfig, sess.Classroom, true, sess.ttl).then((res2) => {\n                let content = JSON.stringify({ members: members })\n                if (NoOfStuds) {\n                    content = JSON.stringify({ members: members, count: NoOfStuds })\n                }\n                const cmd = {\n                    name: name, Classroom: sess.Classroom, content: content,\n                    SessionID: pg1, ttl: res2.ttl\n                }\n                createClassGroup(cmd).then((gp) => {\n                    const grp = gp.data.createClassGroup\n                    if (cb) cb(grp)\n                })\n            })\n    }\n}\nexport function createNewGroup(name, members, cb, NoOfStuds) {\n    getCurrentSession().then((res) => {\n        var sess = res.data.getSession\n        createGroupForClass(name, members, sess, cb, null, NoOfStuds)\n    })\n}\nexport function updateGroupForClass(old, members) {\n    var foundPreCog = false\n    for (let i = 0; i < members.length; i++) {\n        if (members[i].type && members[i].type === \"precog\") {\n            foundPreCog = true\n        }\n    }\n    if (!foundPreCog) {\n        updateClassGroup(old)\n        return\n    }\n    getCurrentSession().then((res) => {\n        var sess = res.data.getSession\n        var bc = sess.boardConfig;\n        try {\n            bc = JSON.parse(sess.boardConfig)\n            if (!bc.hasPreCogs && foundPreCog) {\n                bc.hasPreCogs = true\n                sess.boardConfig = JSON.stringify(bc)\n                updateSession(sess)\n            }\n        } catch (e) {\n            console.log(\"ERROR IS \", e)\n        }\n        updateClassGroup(old)\n    })\n}\n\n/// classroom events\n\nexport function getClassroomEvent(id) {\n    return gqlOperationWithRetry(autoQuery.getClassroomEvent, { 'id': id });\n}\n\nexport function createClassroomEvent(cmd) {\n    if (!cmd.ttl) cmd.ttl = getTTL();\n    return gqlOperationWithRetry(autoMutation.createClassroomEvent, { input: cmd });\n}\n\nexport function updateClassroomEvent(cmd) {\n    delete cmd['createdAt']\n    delete cmd['name']\n    delete cmd['Render']\n    delete cmd['RenderButtons']\n\n    return gqlOperationWithRetry(autoMutation.updateClassroomEvent, { input: cmd });\n}\nexport function deleteClassroomEvent(cmd) {\n    setupdel(cmd)\n\n    //return gqlOperationWithRetry(autoMutation.deleteClassroomEvent, { input: { id: cmd.id } });\n    return updateClassroomEvent(cmd)\n}\n\nexport function listClassroomEventByClass(ClassroomID, cb, nextToken) {\n    const cmd = { limit: 100, nextToken: nextToken, Classroom: ClassroomID, filter: { deleted: { ne: true } } }\n    gqlOperationWithRetry(autoQuery.queryByEventsClassroom, cmd).then(res => {\n        const dat = res.data.queryByEventsClassroom\n        if (dat) cb(dat.items, false)\n        if (dat.nextToken) {\n            listClassroomEventByClass(ClassroomID, cb, dat.nextToken)\n        }\n    })\n}\n\nexport async function listClassroomEventByClassSync(ClassroomID, filter) {\n    var allList = []\n    var nt = null\n    do {\n        var cmd = { limit: 100, nextToken: nt, Classroom: ClassroomID }\n        if (filter) {\n            cmd['filter'] = { and: { ...filter, deleted: { ne: true } } }\n        } else {\n            cmd['filter'] = { deleted: { ne: true } }\n        }\n        var res = await gqlOperationWithRetry(autoQuery.queryByEventsClassroom, cmd)\n        const dat = res.data.queryByEventsClassroom\n        allList = [...allList, ...dat.items]\n        nt = dat.nextToken\n    } while (nt !== null)\n    return allList\n}\n\nexport function delChat(sess) {\n    var ClassroomID = sess.Classroom ? sess.Classroom : sess.parentID\n    listClassroomEventByClass(ClassroomID, found, null)\n    function found(evs) {\n        evs.forEach((e) => {\n            if (e.type === \"Chat\") deleteClassroomEvent(e)\n        })\n    }\n}\n\n// context args: ClassroomID, cb, doList, subCB, retryCount=SUB_MAX_RETRY_COUNT\nexport function SubscribeClassroomEventByClass(context) {\n    if (context.retryCount === undefined) context.retryCount = SUB_MAX_RETRY_COUNT;\n    if (context.doList) listClassroomEventByClass(context.ClassroomID, context.cb, null)\n    var s2, s4;\n    const s1 = API.graphql(graphqlOperation(autoSub.subscribeToClassroomEvents, { Classroom: context.ClassroomID }))\n    let retried = false;\n    s2 = trySubscribe(s1, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.subscribeToClassroomEvents\n            if (!data.deleted) {\n                context.cb([data], true)\n            } else {\n                context.delCB(data)\n            }\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(retried, \"SubscribeClassroomEventByClass\",\n                error, s4, SubscribeClassroomEventByClass, context);\n            retried = true;\n        }\n    }, \"SubscribeClassroomEventByClass\");\n\n    context.subCB([s2, s4]);\n}\n\n/// classroom events\nexport function createErrorLog(cmd) {\n    cmd.ttl = getTTL2Week()\n    return gqlOperationWithRetry(autoMutation.createErrorLog, { input: cmd });\n}\n\nvar subs = {}\nvar timer = null\nexport function listObjectFilter(sessionID, nextToken, cb, uptime, errcb) {\n    const cmd = {\n        limit: 100, nextToken: nextToken,\n        sortDirection: \"ASC\", SessionID: sessionID,\n    }\n    if (uptime) {\n        cmd['filter'] = { createdAt: { gt: uptime } }\n    }\n    gqlOperationWithRetry(autoQuery.sessionSorted, cmd).then(res => {\n        const dat = res.data.sessionSorted\n        cb(dat.items)\n        if (dat.nextToken) {\n            listObjectFilter(sessionID, dat.nextToken, cb, uptime)\n        }\n    }).catch(e => {\n        if (errcb) errcb(e)\n    })\n}\n\nfunction MonitorCB() {\n    const dt2 = Date.now()\n    // if (window.performance && window.performance.memory) {\n    //     console.log(\"MEM\", window.performance.memory)\n    //     console.log(\"USED\", window.performance.memory.usedJSHeapSize/(1024*1024))\n    // }   \n    for (let ss in subs) {\n        const rr = subs[ss]\n        listObjectFilter(ss, null, objects, rr.lastObjTS, errCB)\n        function errCB(e) {\n            console.log(\"ERROR FETCH\", e)\n            if (rr.cb) rr.cb()\n            return\n        }\n        function objects(dats) {\n            for (var i = 0; i < dats.length; i++) {\n                const d = dats[i]\n                if (d.deleted) continue; //ignore deleted objects\n                const dt1 = new Date(d.createdAt)\n                const secs = (dt2 - dt1) / 1000\n                if (secs > 20) {\n                    if (rr.cb) {\n                        rr.cb()\n                        return\n                    }\n                }\n            }\n\n        }\n    }\n}\nexport function gotObjMonitor(obj) {\n    if (obj.localDB_opertaion) {\n        return\n    }\n    if (obj.SessionID in subs) {\n        if (subs[obj.SessionID].lastObjTS) {\n            const inDt = new Date(obj.createdAt)\n            const oldDt = new Date(subs[obj.SessionID].lastObjTS)\n            if (inDt < oldDt) {\n                return\n            }\n        }\n        subs[obj.SessionID].lastObj = obj\n        subs[obj.SessionID].lastObjTS = obj.createdAt\n    }\n}\nexport function AddSubMonitor(sessId, cb) {\n    if (!timer) {\n        timer = setInterval(MonitorCB, 30 * 1000);\n    }\n    if (sessId in subs) {\n        return\n    }\n    subs[sessId] = { lastObj: null, lastObjTS: null, cb: cb }\n}\n\nexport function RemoveSubMonitor(sessId) {\n    delete subs[sessId]\n    if (subs === {}) {\n        ResetSubsMonitor()\n    }\n}\n\nexport function ResetSubsMonitor() {\n    if (timer) {\n        clearInterval(timer)\n        timer = null\n    }\n    subs = {}\n}\n\nexport function runScript(scr, cb) {\n    const script = document.createElement(\"script\");\n    script.src = scr;\n    script.async = true;\n\n    document.body.appendChild(script);\n    script.onload = () => {\n        cb();\n    };\n}\n\nexport function sendClassEvent(msg, state, classID, board, value, ttl, update, createcb) {\n    var event = classID + \"-\" + board + msg\n    var jj = { action: msg, state: state, value: value }\n    var cmd = {\n        id: event, ttl: ttl,\n        event: event, Classroom: classID, deleted: false,\n        type: msg, State: state, Content: JSON.stringify(jj)\n    }\n    cmd['For'] = board\n    getClassroomEvent(event).then((r) => {\n        const f = r.data.getClassroomEvent\n        if (f) {\n            if (update) updateClassroomEvent(cmd)\n        } else {\n\n            createClassroomEvent(cmd).then((r) => {\n                if (createcb) {\n                    var obj = r.data.createClassroomEvent\n                    createcb(obj)\n                }\n            })\n        }\n    })\n}\n\nexport async function updateClassPolls(sess, question, close) {\n    var classID = sess.Classroom ? sess.Classroom : sess.parentID\n    let pollers = []\n    var events = await listClassroomEventByClassSync(classID, null)\n    events.forEach(c => {\n        if (c.type === \"CLASSPOLLER\") {\n            c.Content = JSON.parse(c.Content)\n            pollers.push(c)\n        }\n    })\n    pollers.forEach(p => {\n        if (!close && p.Content.question === question && !p.Content.teacher) {\n            p.Content = JSON.stringify(p.Content)\n            p.State = \"DONE\"\n            updateClassroomEvent(p)\n        }\n        if (close) {\n            p.Content = JSON.stringify(p.Content)\n            p.State = \"DONE\"\n            updateClassroomEvent(p)\n        }\n    })\n}\n\nexport function createClassPollEvent(sess, state,\n    value, question, teacher, cb = null) {\n    var classID = sess.Classroom ? sess.Classroom : sess.parentID\n    let ttl = sess.ttl\n    var luid = mylocalStorage.getItem('mystoreID');\n    var name = mylocalStorage.getItem('myname');\n\n    const msg = \"CLASSPOLLER\"\n    var event = classID + \"-\" + luid + question\n\n    var jj = {\n        action: msg, state: state,\n        value: value, teacher: teacher,\n        question: question,\n        luid: luid, name: name\n    }\n    var cmd = {\n        id: event, ttl: ttl,\n        event: event, Classroom: classID, deleted: false,\n        type: msg, State: state, Content: JSON.stringify(jj)\n    }\n    cmd['For'] = classID\n    getClassroomEvent(event).then((r) => {\n        const f = r.data.getClassroomEvent\n        if (f) {\n            updateClassroomEvent(cmd)\n        } else {\n\n            createClassroomEvent(cmd).then((r) => {\n                if (cb) cb()\n            })\n        }\n    })\n}\nexport function updateClassEvent(cmd) {\n    cmd.Content = JSON.stringify(cmd.Content)\n    updateClassroomEvent(cmd)\n}\n\nexport function GetFoldersByOwner(user, cb, nextToken) {\n    const cmd = { limit: 100, nextToken: nextToken, userProfileId: user }\n    gqlOperationWithRetry(autoQuery.foldersByOwner, cmd).then(res => {\n        const dat = res.data.foldersByOwner\n        if (dat) cb(dat.items, dat.nextToken)\n        if (dat.nextToken) {\n            GetFoldersByOwner(user, cb, dat.nextToken)\n        } else {\n            cb(null);\n        }\n    })\n}\n\n// context args: user, cb, delcb, subCB, doList=true, retryCount=SUB_MAX_RETRY_COUNT\nexport function SubscribeFoldersByOwner(context) {\n    if (context.retryCount === undefined) context.retryCount = SUB_MAX_RETRY_COUNT;\n    if (context.doList === undefined) context.doList = true;\n    if (context.doList) GetFoldersByOwner(context.user, context.cb, null)\n    const s1 = API.graphql(graphqlOperation(autoSub.subscribeToFoldersbyOwner, { userProfileId: context.user }))\n    var s2, s4;\n    let retried = false;\n    s2 = trySubscribe(s1, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.subscribeToFoldersbyOwner\n            context.cb([data])\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(retried, \"SubscribeFoldersByOwner:subscribeToFoldersbyOwner\",\n                error, s4, SubscribeFoldersByOwner, context);\n            retried = true;\n        }\n    }, \"SubscribeFoldersByOwner:subscribeToFoldersbyOwner\");\n    const s3 = API.graphql(graphqlOperation(autoSub.subscribeToDelFoldersbyOwner, { userProfileId: context.user }))\n    s4 = trySubscribe(s3, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.subscribeToDelFoldersbyOwner\n            context.delcb(data)\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(retried, \"SubscribeFoldersByOwner:subscribeToDelFoldersbyOwner\",\n                error, s2, SubscribeFoldersByOwner, context);\n            retried = true;\n        }\n    }, \"SubscribeFoldersByOwner:subscribeToDelFoldersbyOwner\");\n    context.subCB([s2, s4]);\n}\n\nexport function createFolder(name, user, path) {\n    const cmd = {\n        name: name,\n        userProfileId: user,\n        parentFolderPath: path\n    }\n    return gqlOperationWithRetry(autoMutation.createFolder, { input: cmd })\n}\n\nexport function updateFolder(obj) {\n    return gqlOperationWithRetry(autoMutation.updateFolder, { input: obj })\n}\n\nexport function deleteFolder(delId) {\n    return gqlOperationWithRetry(autoMutation.deleteFolder, { input: { id: delId } })\n}\n\nexport function checkStudentMove(parentObj, session) {\n    listObject(session, null, function (items) {\n        for (let i = 0; i < items.length; i++) {\n            const obj = items[i]\n            if (obj.objType !== \"drawPaper\") continue\n            if (!obj.content) continue\n            try {\n                if ('type' in obj) {\n                    obj['type'] = JSON.parse(obj['type'])\n                    if (obj.type && obj.type.compressed) {\n                        obj.content = pako.inflate(obj.content, { to: 'string' });\n                        delete obj['type']\n                    }\n                }\n            } catch (e) {\n                console.error(\"cannot decode\", e, obj)\n                continue\n            }\n\n            var rr\n            try {\n                rr = JSON.parse(obj.content)\n            } catch {\n                continue\n            }\n            if (!rr || rr.length <= 1) continue\n            if (rr[1] && rr[1].data && rr[1].data.studentMoveParent === parentObj.data.studentMoveParentID) {\n                parentObj.visible = false\n                parentObj.remove()\n                //remove the parent\n                return\n            }\n        }\n    })\n}\n\nexport function prepObj(obj, compressed) {\n    var copy = JSON.parse(JSON.stringify(obj))\n    if (!copy.content) return null\n\n    delete copy['created']\n    copy.type = JSON.stringify({ 'compressed': compressed })\n    if (compressed)\n        copy.content = pako.deflate(copy.content, { to: 'string' });\n    return copy\n}\n\nexport function createRaster(x, y, img, session, ttl = 0, cb) {\n    if (!ttl) ttl = getTTL()\n    var raster = [\"Raster\", {\n        \"applyMatrix\": false, \"matrix\": [1, 0, 0, 1, x, y], \"data\": { \"palette\": true }, \"crossOrigin\": \"anonymous\",\n        \"source\": img\n    }]\n    const id = uuid()\n    let content = JSON.stringify(raster)\n    let tobj = {\n        content: content,\n        type: null\n    }\n    var copy = prepObj(tobj, true)\n\n    createObject(id, \"name\", session, copy.content, \"drawPaper\", null, copy.type, ttl)\n}\n\n// export function getCommunityBoardbyGrade(cb, nextToken) {\n//     const cmd = { limit: 100, nextToken: nextToken}\n//     gqlOperationWithRetry(autoQuery.queryByGrade, cmd).then(res => {\n//         const dat = res.data.queryByGrade\n//         if (dat) cb(dat.items)\n//         if (dat.nextToken) {\n//             getCommunityBoardbyGrade(cb, dat.nextToken)\n//         } else {\n//             cb(null);\n//         }\n//     })\n// }\n\nexport async function listCommunityBoardsSync() {\n    var allList = []\n    var nt = null\n    do {\n        const cmd = { limit: 100, nextToken: nt }\n        var res = await gqlOperationWithRetry(autoQuery.listCommunityBoards, cmd)\n        const dat = res.data.listCommunityBoards\n        allList = [...allList, ...dat.items]\n        nt = dat.nextToken\n    } while (nt !== null)\n    allList = allList.filter((value) => value.deleted !== true)\n    return allList\n}\n\nexport function updateCommunityBoard(cmd) {\n    return gqlOperationWithRetry(autoMutation.updateCommunityBoard, { input: cmd })\n}\n\nexport function createCommunityBoard(cmd) {\n    return gqlOperationWithRetry(autoMutation.createCommunityBoard, { input: cmd })\n}\n\nexport function deleteCommunityBoard(delId) {\n    return gqlOperationWithRetry(autoMutation.deleteCommunityBoard, { input: { id: delId } })\n}\n\nexport function findUserProfile(email, cb) {\n    const cmd = {\n        filter: { email: { eq: email } },\n        limit: 10,\n        nextToken: null\n    }\n    gqlOperationWithRetry(autoQuery.listUserProfiles, cmd).then(res => {\n        const dat = res.data.listUserProfiles\n        if (dat.items) {\n            cb(dat.items)\n        }\n    })\n\n}\n\nexport function createPersonalPalette(cmd) {\n    return gqlOperationWithRetry(autoMutation.createPersonalPalette, { input: cmd })\n}\n\nexport function updatePersonalPalette(obj) {\n    return gqlOperationWithRetry(autoMutation.updatePersonalPalette, { input: obj })\n}\n\nexport function deletePersonalPalette(delId) {\n    return gqlOperationWithRetry(autoMutation.deletePersonalPalette, { input: { id: delId } })\n}\n\nexport function ListPersonalPalette(user, cb, nextToken) {\n    const cmd = { limit: 100, nextToken: nextToken, owner: user }\n    gqlOperationWithRetry(autoQuery.byPOwnerSorted, cmd).then(res => {\n        const dat = res.data.byPOwnerSorted\n        if (dat) cb(dat.items)\n        if (dat.nextToken) {\n            ListPersonalPalette(user, cb, dat.nextToken)\n        } else {\n            cb(null);\n        }\n    })\n}\n\n// context args: user, cb, delcb, subCB, doList=true, retryCount=SUB_MAX_RETRY_COUNT\nexport function SubscribePersonalPalettesByOwner(context) {\n    if (context.retryCount === undefined) context.retryCount = SUB_MAX_RETRY_COUNT;\n    if (context.doList === undefined) context.doList = true;\n    if (context.doList) ListPersonalPalette(context.user, context.cb, null)\n    const s1 = API.graphql(graphqlOperation(autoSub.subscribeToPalette, { owner: context.user }))\n    var s2, s4;\n    let retried = false;\n    s2 = trySubscribe(s1, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.subscribeToPalette\n            context.cb([data])\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(retried, \"subscribeToPalette:subscribeToPalette\",\n                error, s4, SubscribePersonalPalettesByOwner, context);\n            retried = true;\n        }\n    }, \"SubscribePersonalPalettesByOwner:subscribeToPalette\");\n    const s3 = API.graphql(graphqlOperation(autoSub.subscribeToDelPalette, { owner: context.user }))\n    s4 = trySubscribe(s3, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.subscribeToDelPalette\n            context.delcb(data)\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(retried, \"SubscribePersonalPalettesByOwner:subscribeToDelPalette\",\n                error, s2, SubscribePersonalPalettesByOwner, context);\n            retried = true;\n        }\n    }, \"SubscribePersonalPalettesByOwner:subscribeToDelPalette\");\n    context.subCB([s2, s4]);\n}\n\n\nexport function createCommunityPalette(cmd) {\n    return gqlOperationWithRetry(autoMutation.createCommunityPalette, { input: cmd })\n}\n\nexport function updateCommunityPalette(obj) {\n    return gqlOperationWithRetry(autoMutation.updateCommunityPalette, { input: obj })\n}\n\nexport function deleteCommunityPalette(delId) {\n    return gqlOperationWithRetry(autoMutation.deleteCommunityPalette, { input: { id: delId } })\n}\n\nexport function ListCommunityPalette(cb, nextToken) {\n    const cmd = { limit: 100, nextToken: nextToken }\n    gqlOperationWithRetry(autoQuery.listCommunityPalettes, cmd).then(res => {\n        const dat = res.data.listCommunityPalettes\n        if (dat) cb(dat.items)\n        if (dat.nextToken) {\n            ListCommunityPalette(cb, dat.nextToken)\n        } else {\n            cb(null);\n        }\n    })\n}\n\n// context args: user, cb, delcb, subCB, doList=true, retryCount=SUB_MAX_RETRY_COUNT\nexport function SubscribeCommunityPalettes(context) {\n    if (context.retryCount === undefined) context.retryCount = SUB_MAX_RETRY_COUNT;\n    if (context.doList === undefined) context.doList = true;\n    if (context.doList) ListCommunityPalette(context.cb, null)\n    const s1 = API.graphql(graphqlOperation(autoSub.onCreateCommunityPalette, { owner: context.user }))\n    var s2, s4;\n    let retried = false;\n    s2 = trySubscribe(s1, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.onCreateCommunityPalette\n            context.cb([data])\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(retried, \"subscribeToPalette:onCreateCommunityPalette\",\n                error, s4, SubscribeCommunityPalettes, context);\n            retried = true;\n        }\n    }, \"SubscribeCommunityPalettes:onCreateCommunityPalette\");\n    const s3 = API.graphql(graphqlOperation(autoSub.onDeleteCommunityPalette, { owner: context.user }))\n    s4 = trySubscribe(s3, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.onDeleteCommunityPalette\n            context.delcb(data)\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(retried, \"SubscribeCommunityPalettesByOwner:onDeleteCommunityPalette\",\n                error, s2, SubscribeCommunityPalettes, context);\n            retried = true;\n        }\n    }, \"SubscribeCommunityPalettesByOwner:onDeleteCommunityPalette\");\n    context.subCB([s2, s4]);\n}\n\nexport function createGamePlay(obj, sessionTTL) {\n    const ttl = (sessionTTL) ? sessionTTL : getTTL()\n    obj.ttl = ttl\n\n    return API.graphql(graphqlOperation(autoMutation.createGamePlay, { input: obj }))\n}\n\nexport function updateGamePlay(obj) {\n    obj.expectedVersion = obj.version\n    return API.graphql(graphqlOperation(autoMutation.updateGamePlay, { input: obj }))\n}\n\nexport function findGamePlay(id) {\n    return API.graphql(graphqlOperation(autoQuery.getGamePlay, { 'id': id }));\n}\n\n// context args: user, cb, delcb, subCB, doList=true, retryCount=SUB_MAX_RETRY_COUNT\nexport function SubscribeGamePlay(context) {\n    if (context.retryCount === undefined) context.retryCount = SUB_MAX_RETRY_COUNT;\n    const s1 = API.graphql(graphqlOperation(autoSub.subscribeToGamePlay, { id: context.id }))\n    var s2\n    let retried = false;\n    s2 = trySubscribe(s1, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.subscribeToGamePlay\n            context.cb([data])\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(retried, \"subscribeToGamePlay\",\n                error, s2, SubscribeGamePlay, context);\n            retried = true;\n        }\n    }, \"subscribeToGamePlay:subscribeToGamePlay\");\n\n    context.subCB([s2]);\n}\n\nexport async function getLanguages() {\n    var translateURL = \"https://www.googleapis.com/language/translate/v2/languages\" +\n        \"?key=AIzaSyAo_Srf7D6PODgjHD3bPOjab-jDzwK9FvU\"\n\n    const response = await fetch(translateURL, {\n        method: 'GET',\n        headers: {\n            'Content-Type': 'application/json',\n        },\n    })\n    var r = await response.json();\n    if (r && r.data) return r.data.languages\n    return null\n}\nexport async function gTranslate(text, lang) {\n\n    // Example POST method implementation:\n    async function postData(url = '', data = {}) {\n\n        var translateURL = \"https://www.googleapis.com/language/translate/v2/\" +\n            \"?key=\" + data.key +\n            \"&target=\" + data.target +\n            \"&q=\" + data.q\n\n        const response = await fetch(translateURL, {\n            method: 'GET',\n            headers: {\n                'Content-Type': 'application/json',\n            },\n        })\n        return response.json();\n        // // Default options are marked with *\n        // const response = await fetch(url, {\n        //     method: 'POST', // *GET, POST, PUT, DELETE, etc.\n        //     headers: {\n        //         'Content-Type': 'application/json',\n        //         \"X-HTTP-Method-Override\": \"GET\",\n        //         key: data.key \n        //     },\n        //     redirect: 'follow', // manual, *follow, error\n        //     body: JSON.stringify(data) // body data type must match \"Content-Type\" header\n        // });\n        // return response.json(); // parses JSON response into native JavaScript objects\n    }\n\n    const params = {\n        \"key\": \"AIzaSyAo_Srf7D6PODgjHD3bPOjab-jDzwK9FvU\",\n        \"q\": text,\n        \"target\": lang,\n        \"alt\": \"json\",\n    }\n\n    var ret = await postData('https://translation.googleapis.com/language/translate/v2', params)\n    if (ret && ret.data && ret.data.translations) {\n        return ret.data.translations[0].translatedText\n    }\n    return null\n}\n\nexport function lockClass(sess, msg, state, classLevel, timer) {\n\n    var event = classLevel ? sess.Classroom + \"-\" + msg : sess.parentID + \"-\" + msg\n    var jj = { action: msg, state: state, bytimer: timer, creator: sess.CreatorLocalID }\n    var cmd = {\n        id: event, ttl: sess.ttl,\n        event: event, Classroom: sess.Classroom, deleted: false,\n        type: msg, State: \"Sent\", Content: JSON.stringify(jj)\n    }\n    if (!state) {\n        cmd.State = \"Done\"\n    }\n    if (classLevel) {\n        cmd['For'] = sess.Classroom\n    } else {\n        cmd['For'] = sess.parentID\n    }\n    getClassroomEvent(event).then((r) => {\n        const f = r.data.getClassroomEvent\n        if (f) {\n            updateClassroomEvent(cmd)\n        } else {\n            createClassroomEvent(cmd)\n        }\n    })\n}\n\nexport function dateConvert(date) {\n    var lang = window.navigator.userLanguage || window.navigator.language;\n    var options = {\n        weekday: \"short\",\n        month: \"2-digit\",\n        day: \"numeric\",\n        hour: \"2-digit\",\n        minute: \"2-digit\",\n    };\n\n    return date.toLocaleString(lang, options);\n}\n\nexport function gamePlayGarbage(obj, classR) {\n    var now = new Date()\n    var rightLoc = {}\n    function gotObjects(items) {\n        items.forEach((obj) => {\n            if (obj.objType === \"drawPaper\") {\n                if ('type' in obj) {\n                    obj['type'] = JSON.parse(obj['type'])\n                    if (obj.type && obj.type.compressed) {\n                        obj.content = pako.inflate(obj.content, { to: 'string' });\n                    }\n                }\n                var rr = null\n                if (obj.content) {\n                    try {\n                        rr = JSON.parse(obj.content)\n                    } catch {\n\n                    }\n                }\n                if (rr && rr[0] === \"Group\" && rr[1] && rr[1].data && rr[1].data.gamePlayAvatar) {\n                    var url = rr[1].data.gamePlayAv.url\n                    var sess = obj.SessionID\n                    var create = new Date(obj.createdAt)\n                    var diff = now - create\n                    if (diff < 1000) {\n                        //too receent \n                        return\n                    }\n                    if (rightLoc[url]) {\n                        if (rightLoc[url] !== sess) {\n                            delObject(obj)\n                        }\n                    } else {\n                        delObject(obj)\n                    }\n                }\n\n            }\n        })\n    }\n    function updateBoards(items) {\n        if (!items) return\n        items.forEach((item) => {\n            listObject(item.id, null, gotObjects)\n        })\n    }\n    function gotBoards(items) {\n        updateBoards(items)\n    }\n    for (let i in obj.content.location) {\n        var lu = obj.content.location[i]\n        for (let l in lu) {\n            var r = lu[l]\n            if (r.url) {\n                rightLoc[r.url] = i\n            }\n        }\n    }\n    if (classR) {\n        listSessionByClassroom(classR, gotBoards, null, false, null)\n    }\n}\n\nexport function debounceClick(ctx) {\n    let timeout = ctx.timeout ? ctx.timeout : 200\n    if (ctx.timer !== null) {\n        clearTimeout(ctx.timer);\n        ctx.timer = null;\n    }\n    ctx.timer = setTimeout(function () {\n        ctx.function(ctx.args)\n        clearTimeout(ctx.timer);\n        ctx.timer = null\n    }, timeout)\n}\n\nexport function copyToClipboard(e, text) {\n    navigator.clipboard.writeText(text)\n    return\n    // var dummy = document.createElement(\"textarea\");\n    // // to avoid breaking orgain page when copying more words\n    // // cant copy when adding below this code\n    // // dummy.style.display = 'none'\n    // document.body.appendChild(dummy);\n    // //Be careful if you use texarea. setAttribute('value', value), which works with \"input\" does not work with \"textarea\". – Eduard\n    // dummy.value = text;\n    // console.log(\"COPY\",text) \n    // dummy.select();\n    // document.execCommand(\"copy\");\n    // document.body.removeChild(dummy);\n}\n\nexport function copyObjtoClipBoard(obj) {\n    obj.selected = false\n    return JSON.stringify({\n        name: \"WBC_OBJ\", type: \"image\",\n        obj: obj.exportJSON()\n    })\n}\n\nexport function copyObjstoClipBoard(selectedObjs) {\n    let arr = []\n    selectedObjs.forEach(o => {\n        let jj = o.exportJSON()\n        o.selected = false\n        arr.push(jj)\n    })\n    return JSON.stringify({\n        name: \"WBC_SOBJ\", type: \"image\",\n        objs: arr\n    })\n}\n\nexport function boardGradeSet(id, gradType, value) {\n    getSession(id).then(async (res) => {\n        var item = res.data.getSession\n        let valtoset\n        let jj = item.boardConfig ? JSON.parse(item.boardConfig) : {}\n        if (value === \"true\") {\n            valtoset = true\n        }\n        if (value === \"false\") {\n            valtoset = false\n        }\n        if (value === \"check\") {\n            let items = await listObjectSync(id)\n            let found = false\n            items.forEach((item) => {\n                if (item.objType === \"drawPaper\") {\n                    expandObj(item)\n                    let d = item.content[1].data\n                    if (d.manualScore) found = true\n                }\n            })\n            valtoset = found ? true : false\n            //loop through items to check the type\n        }\n\n        if (jj[gradType] === valtoset) return //no change\n\n        jj[gradType] = valtoset\n        item.boardConfig = JSON.stringify(jj)\n        updateSession(item)\n    })\n}\n\nexport function createTextItem(color, x, y, text, sz, sessid, font, pointObj) {\n    var lastItem = {\n        id: uuid(),\n        objType: \"text\",\n        ended: true,\n        SessionID: sessid\n    }\n    var content = {\n        \"type\": \"text\", \"points\": { \"x\": x, \"y\": y }, \"text\": text, \"ended\": true, pointObj: pointObj,\n        \"color\": color, \"brushRadius\": sz, \"font\": font, \"size\": { \"w\": 231, \"h\": 152 }\n    }\n\n    lastItem.content = JSON.stringify(content)\n    createObjPlain(lastItem)\n}\n\nexport async function updateScore(sess, percent) {\n    let items = await listObjectSync(sess.id)\n    var pgScoreCount = 1\n\n    items.forEach((item) => {\n        if (item.objType === \"text\") {\n            expandObj(item)\n            if (checkObjisPointObj(item)) {\n                if (item.objType === \"text\" && item.content.text.includes(\"Score\")) {\n                    var f22 = item.content.text.split(\"] Correction Count:\")[1]\n                    if (f22) {\n                        pgScoreCount = parseInt(f22) + 1\n                    }\n                }\n                delObject(item)\n            }\n        }\n    })\n\n    let finalScore = \"Score: \" + percent + \"% [\" + percent + \"/100] Correction Count:\" + pgScoreCount;\n    createTextItem(\"green\", 200, 8, finalScore, \"3\", sess.id, \"Roboto\", true)\n    boardGradeSet(sess.id, \"autoGrade\", \"true\")\n}\n\nexport async function processBoardCorrections(sess, answerKey) {\n    let items = await listObjectSync(sess.id)\n    var points = 0\n    var found = {}\n    var foundDZ = {}\n    var pgScoreCount = 1\n    items.forEach((item) => {\n        if (item.objType === \"drawPaper\") {\n            expandObj(item)\n            if (item.content && item.content.length > 1 && item.content[1]) {\n                let d = item.content[1].data\n                if (d && d['DropZoneID']) {\n                    if (!foundDZ[d['DropZoneID']]) foundDZ[d['DropZoneID']] = []\n                    foundDZ[d['DropZoneID']] = foundDZ[d['DropZoneID']].concat(d['DropZoneMeat'])\n                }\n            }\n        }\n\n        if (item.objType === \"text\" || item.objType === \"drawPaper\") {\n            expandObj(item)\n            if (item.objType === \"text\" && item.content && item.content.textBoxID) {\n                let ans = answerKey[item.content.textBoxID]\n                if (ans) {\n\n                    // check answer here \n                    let got = item.content.text ? item.content.text.trim() : \"\"\n                    let up1 = got.toUpperCase();\n                    let up2 = ans.answer.toUpperCase();\n                    var vals = [up2]\n\n                    if (up2.includes(\";\")) {\n                        vals = up2.split(';')\n                    }\n                    var correct = false\n                    for (let i in vals) {\n                        let v = vals[i].trim()\n                        up1 = up1.replace(/\\n/g, '');\n                        if (ans.ignoreSpecial) {\n                            up1 = up1.replace(/[^a-zA-Z0-9]/g, '');\n                            v = v.replace(/[^a-zA-Z0-9]/g, '');\n                        }\n                        if (up1 === v) {\n                            correct = true\n                            break\n                        }\n                    }\n                    if (correct) {\n                        item.content.color = \"green\"\n                        points = points + ans.points\n                        found[item.content.textBoxID] = \"\" + ans.points\n                    } else {\n                        item.content.color = \"red\"\n                        found[item.content.textBoxID] = \"0\"\n                    }\n                    item.content = JSON.stringify(item.content)\n                    delete item['type']\n                    delete item['Session']\n                    delete item['updatedAt']\n                    updateObject(item)\n                    return\n                }\n            }\n            if (checkObjisPointObj(item)) {\n                if (item.objType === \"text\" && item.content.text.includes(\"Score\")) {\n                    var f22 = item.content.text.split(\"] Correction Count:\")[1]\n                    if (f22) {\n                        pgScoreCount = parseInt(f22) + 1\n                    }\n                }\n                delObject(item)\n            }\n        }\n    })\n    var pg = sess.id.split(\"-pgNum-\")[1]\n    var total = 0\n    if (answerKey.pages[pg]) {\n        for (let i in answerKey.pages[pg]) {\n            var a = answerKey.pages[pg][i]\n            if (a.dropZone) {\n                if (a.dropZone.id in foundDZ) {\n                    let same = compA(foundDZ[a.dropZone.id], a.dropZone.answers)\n                    if (same) {\n                        let pts = a.ansKey.points ? a.ansKey.points : 0\n                        found[i] = \"\" + pts\n                        if (found[i] === \"0\") found[i] = \"1\"\n                        points = points + pts\n                    } else {\n                        found[i] = \"0\"\n                    }\n                }\n            }\n            let pts = answerKey.pages[pg][i].ansKey.points ? answerKey.pages[pg][i].ansKey.points : 0\n            total = total + answerKey.pages[pg][i].ansKey.points\n            if (found[i]) {\n                if (pts > 0)\n                    createItem(found[i] === \"0\" ? \"red\" : \"green\", answerKey.pages[pg][i].location.x + 10,\n                        answerKey.pages[pg][i].location.y + 20, \"[\" + found[i] + \"/\" + pts\n                    + \"]\", \"2\")\n                creatCheck(found[i] === \"0\" ? \"wrong\" : \"right\", answerKey.pages[pg][i].location.x + 10, answerKey.pages[pg][i].location.y - 20)\n            } else {\n                if (pts > 0)\n                    createItem(\"red\", answerKey.pages[pg][i].location.x + 10,\n                        answerKey.pages[pg][i].location.y + 20, \"[0/\" +\n                        pts + \"]\", \"2\")\n                creatCheck(\"wrong\", answerKey.pages[pg][i].location.x + 10, answerKey.pages[pg][i].location.y - 20)\n\n            }\n        }\n\n        //final score\n        var finalScore = \"Score: \" + points\n        if (total > 0) {\n            var percent = (100.0 * points / total).toFixed(2);\n            finalScore = \"Score: \" + percent + \"% [\" + points + \"/\" + total + \"] Correction Count:\" + pgScoreCount;\n            createItem(\"green\", 80, 28, finalScore, \"3\")\n        }\n        boardGradeSet(sess.id, \"autoGrade\", \"true\")\n    }\n    function compA(a, b) {\n        if (a.length !== b.length) return false\n        a.sort()\n        b.sort()\n        for (let i = 0; i < a.length; i++) {\n            if (a[i] !== b[i]) return false\n        }\n        return true\n    }\n    function createItem(color, x, y, text, sz) {\n        var lastItem = {\n            id: uuid(),\n            objType: \"text\",\n            ended: true,\n            SessionID: sess.id\n        }\n        var content = {\n            \"type\": \"text\", \"points\": { \"x\": x, \"y\": y }, \"text\": text, \"ended\": true, pointObj: true,\n            \"color\": color, \"brushRadius\": sz, \"font\": \"Roboto\", \"size\": { \"w\": 231, \"h\": 152 }\n        }\n\n        lastItem.content = JSON.stringify(content)\n        createObjPlain(lastItem)\n    }\n\n    function creatCheck(type, x, y) {\n        var lastItem = {\n            id: uuid(),\n            objType: \"drawPaper\",\n            ended: true,\n            SessionID: sess.id,\n            type: \"{\\\"compressed\\\":false}\"\n        }\n        var c = [\"Raster\",\n            {\n                \"applyMatrix\": false,\n                \"matrix\": [1, 0, 0, 1, x, y],\n                \"opacity\": 0.5,\n                \"data\": { \"drawPaper\": true, \"pointObj\": true },\n                \"crossOrigin\": \"anonymous\", \"source\": \"/engagement/\" + type + \".png\"\n            }]\n        var content = JSON.stringify(c)\n        lastItem.content = content\n        createObjPlain(lastItem)\n    }\n}\n\nexport function expandObj(obj) {\n    try {\n        if ('type' in obj && obj['type']) {\n            obj['type'] = JSON.parse(obj['type'])\n            if (obj.type && obj.type.compressed) {\n                obj.content = pako.inflate(obj.content, { to: 'string' });\n            }\n        }\n    } catch (e) {\n    }\n    try {\n        obj.content = JSON.parse(obj.content)\n    } catch {\n        return false\n    }\n}\n\nexport async function lockSingle(classR, single, state) {\n    var pages = await getSessionByClassroomSync(classR)\n    var found = null\n    for (let i = 0; i < pages.length; i++) {\n        var page = pages[i]\n        if (single && single === page.CreatorLocalID) {\n            found = page\n            break\n        }\n    }\n    if (found) lockClass(found, \"LockClass\", state, false, false)\n}\n\nexport function autoCorrect(classR, single, pageNum) {\n    return new Promise(async (resolve, reject) => {\n        var pages = await getSessionByClassroomSync(classR)\n        var answerKey = { pages: {} }\n\n        for (let i = 0; i < pages.length; i++) {\n            var page = pages[i]\n            if (page.id === page.parentBoardID) {\n                let ff2 = page.id.split(\"-pgNum-\")[1]\n                if (pageNum && parseInt(ff2) !== parseInt(pageNum)) {\n                    continue\n                }\n                let items = await listObjectSync(page.id)\n                items.forEach((item) => {\n                    if (item.objType === \"drawPaper\") {\n                        expandObj(item)\n                        if (item.content && item.content.length > 1 && item.content[1]) {\n                            let d = item.content[1].data\n                            if (!d.linkData || !d.linkData.id) {\n                                return\n                            }\n                            if (d && d[\"answerKey\"]) {\n                                answerKey[d.linkData.id] = d[\"answerKey\"]\n                                if (!answerKey.pages[ff2]) {\n                                    answerKey.pages[ff2] = {}\n                                }\n                                let mx = 0\n                                let my = 2000\n                                if (item.content[1].segments) {\n                                    for (let r in item.content[1].segments) {\n                                        let rr2 = item.content[1].segments[r]\n                                        let x = rr2[0]\n                                        let y = rr2[1]\n                                        if (x > mx) mx = x\n                                        if (y < my) my = y\n                                    }\n                                }\n                                answerKey.pages[ff2][d.linkData.id] = { ansKey: d[\"answerKey\"], dropZone: d['DropZone'] }\n                                if (mx > 0) {\n                                    answerKey.pages[ff2][d.linkData.id][\"location\"] = { x: mx, y: my }\n                                }\n                            }\n                        }\n                    }\n                })\n            }\n        }\n        // console.log(\"ANSWER KEY\", answerKey)\n        for (let i = 0; i < pages.length; i++) {\n            page = pages[i]\n            let ff2 = page.id.split(\"-pgNum-\")[1]\n            if (pageNum && parseInt(ff2) !== parseInt(pageNum)) {\n                continue\n            }\n\n            if (single && single !== page.CreatorLocalID) {\n                continue\n            }\n            if (page.id !== page.parentBoardID) await processBoardCorrections(page, answerKey)\n        }\n        resolve()\n    })\n}\n\nfunction checkObjisPointObj(item) {\n    if (item.objType === \"text\") {\n        expandObj(item)\n        if (item.content && item.content.pointObj) {\n            return true\n        }\n    }\n    if (item.objType === \"drawPaper\") {\n        expandObj(item)\n        if (item.content && item.content[0] === \"Raster\" && item.content[1] && item.content[1].data.pointObj) {\n            return true\n        }\n    }\n    if (item.content && item.content[0] === \"Raster\" && item.content[1] && item.content[1].source.includes(\"engagement\")) {\n        return true\n    }\n    return false\n}\nasync function removeBoardCorrection(sess, answerKey) {\n    let items = await listObjectSync(sess.id)\n    boardGradeSet(sess.id, \"autoGrade\", \"false\")\n    items.forEach((item) => {\n        if (item.name === \"AICorrect\") {\n            delObject(item)\n            return\n        }\n        if (checkObjisPointObj(item)) {\n            delObject(item)\n        }\n    })\n}\n\nexport function autoCorrectRemove(classR, single, pageNum) {\n    return new Promise(async (resolve, reject) => {\n        var pages = await getSessionByClassroomSync(classR)\n        var answerKey = { pages: {} }\n        for (let i = 0; i < pages.length; i++) {\n            let page = pages[i]\n            await removeBoardCorrection(page, answerKey)\n        }\n    })\n}\nexport function listServiceNotices(cb, nextToken) {\n    const cmd = { limit: 100, nextToken: nextToken }\n    gqlOperationWithRetry(autoQuery.listServiceNotices, cmd).then(res => {\n        const dat = res.data.listServiceNotices\n        if (dat) cb(dat.items)\n        if (dat.nextToken) {\n            listServiceNotices(cb, dat.nextToken)\n        } else {\n            cb(null);\n        }\n    })\n}\n\nexport function truncateString(str, num) {\n    // If the length of str is less than or equal to num\n    // just return str--don't truncate it.\n    if (str.length <= num) {\n        return str\n    }\n    // Return str truncated with '...' concatenated to the end of str.\n    return str.slice(0, num) + '...'\n}\n\nexport function createLatencyCalc(obj) {\n    return API.graphql(graphqlOperation(autoMutation.createLatencyCalculation, { input: obj }))\n}\n\nexport function createLatencyConfig(obj) {\n    return API.graphql(graphqlOperation(autoMutation.createLatencyEndPoints, { input: obj }))\n}\n\nexport function getLantencyConfig(cb) {\n    const id = \"LATENCY_CONFIG\"\n    API.graphql(graphqlOperation(autoQuery.getLatencyEndPoints, { 'id': id })).then((r) => {\n        var c = r.data.getLatencyEndPoints\n        if (!c) {\n            createLatencyConfig({ id: id, content: JSON.stringify({ disabled: true }) }).then((p) => {\n                c = p.data.createLatencyEndPoints\n                if (c) {\n                    c.content = JSON.parse(c.content)\n                    cb(c)\n                }\n            })\n        } else {\n            c.content = JSON.parse(c.content)\n            cb(c)\n        }\n    })\n}\n\nexport const boardResoltionType = {\n    'small': { w: 1280, h: 800 },\n    'chromebook': { w: 1366, h: 625 },\n    'ipad': { w: 1024, h: 700 },\n    'a4': { w: 750, h: 900 },\n    'medium': { w: 1440, h: 900 },\n    'default': { w: 2000, h: 1024 },\n    'tiny': { w: 1024, h: 550 },\n    '4k': { w: 3840, h: 2160 },\n\n}\n\nexport function windowreload() {\n    window.location.reload()\n}\nexport function deepCompare() {\n    var i, l, leftChain, rightChain;\n\n    function compare2Objects(x, y) {\n        var p;\n\n        // remember that NaN === NaN returns false\n        // and isNaN(undefined) returns true\n        if (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') {\n            return true;\n        }\n\n        // Compare primitives and functions.\n        // Check if both arguments link to the same object.\n        // Especially useful on the step where we compare prototypes\n        if (x === y) {\n            return true;\n        }\n\n        // Works in case when functions are created in constructor.\n        // Comparing dates is a common scenario. Another built-ins?\n        // We can even handle functions passed across iframes\n        if ((typeof x === 'function' && typeof y === 'function') ||\n            (x instanceof Date && y instanceof Date) ||\n            (x instanceof RegExp && y instanceof RegExp) ||\n            (x instanceof String && y instanceof String) ||\n            (x instanceof Number && y instanceof Number)) {\n            return x.toString() === y.toString();\n        }\n\n        // At last checking prototypes as good as we can\n        if (!(x instanceof Object && y instanceof Object)) {\n            return false;\n        }\n\n        if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) {\n            return false;\n        }\n\n        if (x.constructor !== y.constructor) {\n            return false;\n        }\n\n        if (x.prototype !== y.prototype) {\n            return false;\n        }\n\n        // Check for infinitive linking loops\n        if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) {\n            return false;\n        }\n\n        // Quick checking of one object being a subset of another.\n        // todo: cache the structure of arguments[0] for performance\n        for (p in y) {\n            if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {\n                return false;\n            }\n            else if (typeof y[p] !== typeof x[p]) {\n                return false;\n            }\n        }\n\n        for (p in x) {\n            if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {\n                return false;\n            }\n            else if (typeof y[p] !== typeof x[p]) {\n                return false;\n            }\n\n            switch (typeof (x[p])) {\n                case 'object':\n                case 'function':\n\n                    leftChain.push(x);\n                    rightChain.push(y);\n\n                    if (!compare2Objects(x[p], y[p])) {\n                        return false;\n                    }\n\n                    leftChain.pop();\n                    rightChain.pop();\n                    break;\n\n                default:\n                    if (x[p] !== y[p]) {\n                        return false;\n                    }\n                    break;\n            }\n        }\n\n        return true;\n    }\n\n    if (arguments.length < 1) {\n        return true; //Die silently? Don't know how to handle such case, please help...\n        // throw \"Need two or more arguments to compare\";\n    }\n\n    for (i = 1, l = arguments.length; i < l; i++) {\n\n        leftChain = []; //Todo: this can be cached\n        rightChain = [];\n\n        if (!compare2Objects(arguments[0], arguments[i])) {\n            return false;\n        }\n    }\n\n    return true;\n}\n\nexport function sendShowCaseEvent(studentID, state, sess) {\n    var msg = \"SHOWCASE\"\n    var event = sess.Classroom + \"-\" + msg + \"-\" + studentID\n    var jj = { action: msg, state: state, student: studentID }\n    var cmd = {\n        id: event, ttl: sess.ttl, deleted: false,\n        event: event, Classroom: sess.Classroom,\n        type: msg, State: \"Sent\", Content: JSON.stringify(jj)\n    }\n    if (!state) {\n        cmd.State = \"Done\"\n    }\n    cmd['For'] = sess.Classroom\n    getClassroomEvent(event).then((r) => {\n        const f = r.data.getClassroomEvent\n        if (f) {\n            updateClassroomEvent(cmd)\n        } else {\n            createClassroomEvent(cmd)\n        }\n    })\n}\n\nexport function sendFormSubmit(formID, sess, name, form) {\n    var msg = \"FORMSUBMIT\"\n    var luid = mylocalStorage.getItem('mystoreID');\n\n    var event = sess.Classroom + \"-\" + msg + \"@\" + formID + \"#\" + luid\n    var jj = {\n        action: msg, state: \"Sent\", student: luid, name: name,\n        form: form\n    }\n    var cmd = {\n        id: event, ttl: sess.ttl, deleted: false,\n        event: event, Classroom: sess.Classroom,\n        type: msg, State: \"Sent\", Content: JSON.stringify(jj)\n    }\n\n    cmd['For'] = sess.Classroom\n    getClassroomEvent(event).then((r) => {\n        const f = r.data.getClassroomEvent\n        if (f) {\n            updateClassroomEvent(cmd)\n        } else {\n            createClassroomEvent(cmd)\n        }\n    })\n}\n\nexport function clearUndefined(c) {\n    var x = { ...c }\n    var keys = Object.keys(x)\n    for (let k in keys) {\n        var key = keys[k]\n        var o = x[key]\n        if (typeof (o) === 'undefined') {\n            delete x[key]\n        }\n    }\n    delete x['Video'] // dont compare video option\n    return x\n}\n\nexport async function getService() {\n    const items = await API.get('serviceApi', '/service', {\n        // 'queryStringParameters': {\n        //   'order': 'byPrice'\n        // }\n    });\n    // console.log(\"Got response items = \", items)\n    return items\n}\n\n\nexport async function getMSMktpAccToken() {\n    const items = await API.get('serviceApi', '/service/msMktpAccToken', {\n    });\n    return items\n}\n\nexport async function postData(data) {\n    const response = await fetch(\"http://localhost:8080/\", {\n        method: 'POST',\n        headers: {\n            'Content-Type': 'application/json',\n        },\n        body: data\n    })\n    var r = await response.json();\n    return r\n}\n\nexport function updateOembedLink() {\n    var link = document.getElementById('oembed-link');\n    var encStr = encodeURIComponent(window.location.href);\n\n    if (link) {\n        link.type = \"application/json+oembed\"\n        link.href = `https://oembed.whiteboard.chat/oembed?url=${encStr}&format=json`\n    }\n}\n\n\nexport async function copyBoard(boardData, instanceObj, userEmailId, cb, errCb) {\n    var dict = { 'boardData': boardData, 'instanceObj': instanceObj, 'userEmailId': userEmailId }\n    API.post('serviceApi', '/copyboard', {\n        'body': dict\n    }).then((res) => {\n        cb(res.message)\n    }).catch(error => errCb(\"Export board failed. Please try again later.\"))\n}\n\nfunction exportCSV(data, boardName) {\n    const filename = boardName + '.csv';\n    let element = document.createElement('a');\n    element.setAttribute('href', 'data:text/csv;charset=utf-8,' + encodeURI(data));\n    element.setAttribute('download', filename);\n    element.style.display = 'none';\n    document.body.appendChild(element);\n    element.click();\n    document.body.removeChild(element);\n    try {\n        WBCReactGA.event({\n            category: 'User',\n            action: 'BoardExported'\n        });\n    } catch { }\n}\n\nexport function doReport(classR) {\n    return new Promise(async (resolve, reject) => {\n        var pages = await getSessionByClassroomSync(classR)\n        var report = {}\n        var evt = {}\n        var rh = {}\n        var chat = {}\n        var poll = {}\n        var enScore = {}\n        var name = \"WBC\"\n        var events = await listClassroomEventByClassSync(classR, null)\n        var engagement = await ListEngagementEventSync(classR, null)\n\n        for (let i = 0; i < engagement.length; i++) {\n            let ee = engagement[i]\n            let e = JSON.parse(ee.Content)\n            if (!(ee.luid in enScore)) {\n                enScore[ee.luid] = 0\n            }\n            enScore[ee.luid] += parseInt(e.engagementScore.calculated)\n        }\n        for (let i = 0; i < events.length; i++) {\n\n            var e = events[i]\n            let f = e.For.split(\":\")\n            if (e.type === \"RaiseHand\") {\n                if (f.length <= 1) continue\n                let nm = f[1]\n                try {\n                    let ct = JSON.parse(e.Content)\n                    if (!(nm in rh)) {\n                        rh[nm] = \"\"\n                    }\n                    var tt = ct.kind\n                    rh[nm] = tt\n                } catch { }\n            }\n            if (e.type === \"FORMSUBMIT\") {\n                try {\n                    let ct = JSON.parse(e.Content)\n                    let nm = ct.name\n                    if (!(nm in poll)) {\n                        poll[nm] = \"\"\n                    }\n                    let tt = \"\"\n                    for (let i = 0; i < ct.form.length; i++) {\n                        let f = ct.form[i]\n                        tt = tt + f.val + \":\" + f.set + \";\"\n                    }\n                    poll[nm] = poll[nm] + \"  \" + tt\n                } catch { }\n            }\n            if (e.type === \"Chat\") {\n                try {\n                    let ct = JSON.parse(e.Content)\n                    let nm = ct.from ? ct.from.name : null\n                    if (!nm) continue\n                    if (!(nm in chat)) {\n                        chat[nm] = 0\n                    }\n                    chat[nm]++\n                } catch { }\n            }\n            if (e.type === \"Poll\") {\n                if (f.length <= 1) continue\n                let nm = f[1]\n                try {\n                    let ct = JSON.parse(e.Content)\n                    if (!(nm in evt)) {\n                        evt[nm] = \"\"\n                    }\n                    let tt = ct.text\n                    tt = tt.replace(/,/g, ';')\n                    evt[nm] += \" \" + tt + \",\"\n                } catch { }\n            }\n        }\n        for (let i = 0; i < pages.length; i++) {\n            var page = pages[i]\n            if (page.id !== page.parentBoardID) {\n                var r = await processPage(page)\n                if (!r) continue\n                report[r.name + '-' + r.pgNum] = r.name + ',' + r.pgNum + \",\" + r.pageCreated + \",\" + r.objectCount + \",\" + r.stickers.join(\"; \") + \",\" + r.lastObj + \",\" + r.timeSpent + \",\" + r.Score + \",\" + r.manualGrade\n                if (r.pgNum === \"1\") {\n                    if (evt[r.name]) {\n                        report[r.name + '-' + r.pgNum] += \",\" + evt[r.name]\n                    } else {\n                        report[r.name + '-' + r.pgNum] += \",\"\n                    }\n                    if (poll[r.name]) {\n                        report[r.name + '-' + r.pgNum] += \",\" + poll[r.name]\n                    } else {\n                        report[r.name + '-' + r.pgNum] += \",\"\n                    }\n                    if (rh[r.name]) {\n                        report[r.name + '-' + r.pgNum] += \",\" + rh[r.name]\n                    } else {\n                        report[r.name + '-' + r.pgNum] += \",\"\n                    }\n                    if (chat[r.name]) {\n                        report[r.name + '-' + r.pgNum] += \",\" + chat[r.name]\n                    } else {\n                        report[r.name + '-' + r.pgNum] += \",\"\n                    }\n                    if (enScore[r.luid]) {\n                        report[r.name + '-' + r.pgNum] += \",\" + enScore[r.luid]\n                    } else {\n                        report[r.name + '-' + r.pgNum] += \",\"\n                    }\n                }\n            } else {\n                name = page.name\n            }\n        }\n        var final = \"Name, Page Number, Page Created, Number of Objects, Awarded Stickers, Last Annotation, Time Spent, Auto Grade, Manual Grade, Poll Responses, Forms, Last Raise Hand, Chat count, Engagement Score\\n\"\n        var k = Object.keys(report).sort()\n        for (let i = 0; i < k.length; i++) {\n            let rr = report[k[i]]\n            final += rr + \"\\n\"\n        }\n        exportCSV(final, name)\n        async function processPage(page) {\n            var r = {}\n            var savedUser\n            r['pageCreated'] = dateConvert(new Date(page.createdAt)).replace(/,/g, \";\");\n            page.Users.items.forEach(u => {\n                var xx = JSON.parse(u.content)\n                if (xx.localID === page.CreatorLocalID) {\n                    u.content = xx\n                    savedUser = u\n                    savedUser['luid'] = xx.localID\n                }\n            })\n            if (!savedUser) {\n                return null\n            }\n            let items = await listObjectSync(page.id)\n            var count = 0\n            r['Score'] = \"\"\n            r['manualGrade'] = \"\"\n            r['Stickers'] = {}\n            for (let i = 0; i < items.length; i++) {\n                const item = items[i]\n                if (item.CreatedBy !== savedUser.id) {\n                    if (item.objType === \"text\") {\n                        expandObj(item)\n                        if (item.content && item.content.pointObj && item.content.text.includes(\"Score\")) {\n                            r['Score'] = item.content.text\n                        }\n                    }\n                    if (item.objType === \"drawPaper\") {\n                        expandObj(item)\n                        if (item && item.content && item.content.length > 1) {\n                            if (item.content[0] === \"Raster\" && item.content[1].data && item.content[1].data.palette) {\n                                /* eslint-disable no-useless-escape  */\n                                var filename = item.content[1].source.split(/[\\\\\\/]/).pop();\n                                filename = filename.replace(\".png\", \"\")\n                                if (!(filename in r['Stickers'])) {\n                                    r['Stickers'][filename] = { 'type': filename, 'count': 0 }\n                                }\n                                r['Stickers'][filename].count += 1\n\n                            }\n                            if (item.content[0] === \"Group\" && item.content[1].data && item.content[1].data.manualScore) {\n                                r['manualGrade'] += item.content[1].data.manualScore.text + \";\"\n                            }\n                        }\n                    }\n\n                    continue\n                }\n                if (!r.firstObj) {\n                    r.firstObj = new Date(item.updatedAt)\n                }\n                r.lastObj = new Date(item.updatedAt)\n                count++\n            }\n            if (count === 0) { // user didnt do anything \n                r['firstObj'] = \"NA\"\n                r['lastObj'] = \"NA\"\n                r['timeSpent'] = \"0\"\n            } else {\n                var diff = r.lastObj - new Date(page.createdAt)\n                r['firstObj'] = dateConvert(r.firstObj).replace(/,/g, \";\");\n                r['lastObj'] = dateConvert(r.lastObj).replace(/,/g, \";\");\n                r['timeSpent'] = Math.floor((diff / 1000) / 60);\n            }\n            r['stickers'] = []\n            Object.keys(r['Stickers']).map(k => {\n                let s = r['Stickers'][k]\n                r['stickers'].push(k + \":\" + s['count'])\n                return null\n            })\n            r['objectCount'] = count\n            r['luid'] = savedUser.luid\n            r['name'] = savedUser.name\n            r['pgNum'] = page.id.split('-pgNum-')[1]\n            return r\n        }\n        resolve()\n    })\n}\n\nexport function getCorsURL(url, cb) {\n    var createCORSRequest = function (method, url) {\n        var xhr = new XMLHttpRequest();\n        if (\"withCredentials\" in xhr) {\n            // Most browsers.\n            xhr.open(method, url, true);\n        } else {\n            // CORS not supported.\n            xhr = null;\n        }\n        return xhr;\n    };\n    console.log(\"FETCH URL\", url)\n    var method = 'GET';\n    var xhr = createCORSRequest(method, url);\n\n    xhr.onload = function () {\n        // Success code goes here.\n        cb(xhr)\n    };\n\n    xhr.onerror = function () {\n        // Error code goes here.\n        console.log(\"ERROR=======\")\n    };\n\n    xhr.send();\n}\n\nconst ESCROOMNAME = \"escapeRoom\"\nexport function getEscapeRoomPage(sess, pgnum) {\n    var lu = mylocalStorage.getItem(ESCROOMNAME)\n    if (!lu) return null\n    lu = JSON.parse(lu)\n    if (lu.board !== sess.Classroom) {\n        mylocalStorage.removeItem(ESCROOMNAME)\n        return null\n    }\n    return lu.pages[pgnum]\n}\n\nexport function setEscapeRoomPage(sess, pgnum, val) {\n    var lu = mylocalStorage.getItem(ESCROOMNAME)\n    if (lu) {\n        lu = JSON.parse(lu)\n        if (lu.board !== sess.Classroom) {\n            mylocalStorage.removeItem(ESCROOMNAME)\n            lu = null\n        }\n    }\n    if (!lu) {\n        lu = {\n            board: sess.Classroom,\n            pages: {}\n        }\n    }\n    var oldpg = lu.pages[pgnum]\n    lu.pages[pgnum] = {\n        ...oldpg,\n        ...val\n    }\n    mylocalStorage.setItem(ESCROOMNAME, JSON.stringify(lu))\n}\n/*****/\nexport function createEngagementEvent(cmd) {\n    cmd.ttl = getTTL3Days()\n    return gqlOperationWithRetry(autoMutation.createEngagementEvent, { input: cmd })\n}\n\nexport function updateEngagementEvent(obj) {\n    return gqlOperationWithRetry(autoMutation.updateEngagementEvent, { input: obj })\n}\n\nexport function deleteEngagementEvent(delId) {\n    return gqlOperationWithRetry(autoMutation.deleteEngagementEvent, { input: { id: delId } })\n}\n\nexport function ListEngagementEvent(user, cb, nextToken, Classroom) {\n    const cmd = { limit: 100, nextToken: nextToken, owner: user, Classroom: Classroom }\n    gqlOperationWithRetry(autoQuery.querybyEngagementClass, cmd).then(res => {\n        const dat = res.data.querybyEngagementClass\n        if (dat) cb(dat.items)\n        if (dat.nextToken) {\n            ListEngagementEvent(user, cb, dat.nextToken, Classroom)\n        } else {\n            cb(null);\n        }\n    })\n}\n\nexport async function ListEngagementEventSync(Classroom) {\n    var allList = []\n    var nt = null\n    do {\n        const cmd = { limit: 100, nextToken: nt, sortDirection: \"ASC\", Classroom: Classroom }\n\n        var res = await gqlOperationWithRetry(autoQuery.querybyEngagementClass, cmd)\n        const dat = res.data.querybyEngagementClass\n        allList = [...allList, ...dat.items]\n        nt = dat.nextToken\n    } while (nt !== null)\n    return allList\n}\n\n// context args: user, cb, delcb, subCB, doList=true, retryCount=SUB_MAX_RETRY_COUNT\nexport function SubscribeEngagementEventsByOwner(context) {\n    if (context.retryCount === undefined) context.retryCount = SUB_MAX_RETRY_COUNT;\n    if (context.doList === undefined) context.doList = true;\n    if (context.doList) ListEngagementEvent(context.user, context.cb, null, context.Classroom)\n    const s1 = API.graphql(graphqlOperation(autoSub.subscribeToEngagementEvent, { Classroom: context.Classroom }))\n    var s2;\n    let retried = false;\n    s2 = trySubscribe(s1, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.subscribeToEngagementEvent\n            context.cb([data])\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(retried, \"subscribeToEngagementEvent:subscribeToEngagementEvent\",\n                error, null, SubscribeEngagementEventsByOwner, context);\n            retried = true;\n        }\n    }, \"SubscribeEngagementEventsByOwner:subscribeToEngagementEvent\");\n    context.subCB([s2]);\n}\n\nfunction gotTopDomain() {\n    let docref = document.referrer\n    if (document.referrer === '') {\n        // this could be because of iframing and referrer is not available yet\n        docref = document.location.href\n    }\n    docref = docref.replace('@', '__') // In case URL has some email addr argument\n    var url = (window.location !== window.parent.location)\n        ? docref\n        : document.location.href;\n    return url\n}\nexport const getQueryStringParams = query => {\n    return query\n        ? (/^[?#]/.test(query) ? query.slice(1) : query)\n            .split('&')\n            .reduce((params, param) => {\n                let [key, value] = param.split('=');\n                params[key] = value ? decodeURIComponent(value.replace(/\\+/g, ' ')) : '';\n                return params;\n            }, {}\n            )\n        : {}\n};\nexport function getStoreApiMode(loc, cb, firstcall) {\n    let q = getQueryStringParams(loc)\n    if (q.key) {\n        if (q.resetStore && firstcall) {\n            mylocalStorage.clear();\n        }\n        if (q.userid) {\n            mylocalStorage.setItem('mystoreID', q.userid);\n        }\n        if (q.username) {\n            mylocalStorage.setItem('myname', q.username);\n        }\n        listApiKey(q.key, done)\n        function done(k) {\n            if (k) {\n                //good key\n                let dom = gotTopDomain()\n                WBCReactGA.event({\n                    category: 'B2B',\n                    action: dom,\n                });\n                var newobj = { ...q, obj: k }\n                mylocalStorage.setItem('apiArgs', JSON.stringify(newobj))\n                if (k.content) {\n                    let sp = k.content.split(\",\")\n                    sp.forEach(i => {\n                        if (i.includes('paidPlan')) {\n                            let c2 = i.split(':')\n                            if (c2[1]) {\n                                mylocalStorage.setItem('paidPlan', c2[1])\n                            }\n                        }\n                        if (i.includes('domainVerify')) {\n                            let c2 = i.split(':')\n                            if (c2[1]) {\n                                if (!dom.includes(c2[1])) {\n                                    alert(\"Sorry this key is not valid for this domain\")\n                                    cb(null)\n                                    return\n                                }\n                            }\n                        }\n                    })\n                    mylocalStorage.setItem('apiSetting', k.content)\n                }\n                if (q.userEmail && q.userEmail.length > 0) {\n                    findUserProfileByEmail(q.userEmail).then(res => {\n                        const dat = res.data.byEmamilUP\n                        if (dat && dat.items && dat.items.length > 0) {\n                            let u = dat.items[0]; //first for now\n                            mylocalStorage.setItem('mystoreID', u.id);\n                            if (!q.username && u.name) {\n                                mylocalStorage.setItem('myname', u.name);\n                            }\n                        } else {\n                            let iduse = window.btoa(q.userEmail) // generate random id based on email\n                            mylocalStorage.setItem('mystoreID', iduse);\n                            const cmd = {\n                                id: iduse,\n                                'name': q.username ? q.username : q.userEmail,\n                                'email': q.userEmail,\n                                'emailOptIn': false\n                            }\n                            gqlOperationWithRetry(autoMutation.createUserProfile, { input: cmd })\n                        }\n                        cb(newobj)\n                    })\n                } else {\n                    cb(newobj)\n                }\n            } else {\n                alert(\"BAD API KEY\");\n                cb(null)\n            }\n        }\n    } else {\n        cb(null)\n    }\n}\nexport function createAPIKey(obj) {\n    return API.graphql(graphqlOperation(autoMutation.createApiInfo, { input: obj }))\n}\nexport function listApiKey(key, done) {\n    API.graphql(graphqlOperation(autoQuery.byApiKey, { key: key })).then(res => {\n        let dat = res.data.byApiKey\n        if (dat && dat.items[0]) {\n            done(dat.items[0])\n        } else {\n            done(null);\n        }\n    })\n    return\n}\nexport function getAPIKey(id, cb) {\n    return API.graphql(graphqlOperation(autoQuery.getApiInfo, { id: id }))\n}\nexport function findCreateApiKey(cb) {\n    if (!Auth) return null\n    let id = Auth.user.username\n    getAPIKey(id).then(res => {\n        let dat = res.data.getApiInfo\n        if (!dat) {\n            let obj = { id: id, key: uuid() }\n            createAPIKey(obj).then(r2 => {\n                let d2 = r2.data.createApiInfo\n                cb(d2)\n            })\n        } else {\n            cb(dat)\n        }\n    })\n}\n\nexport async function dummyPost(url, data) {\n    const response = await fetch(url, {\n        method: 'POST',\n        headers: {\n            'Content-Type': 'application/json',\n        },\n        body: data\n    })\n    var r = await response.json();\n    return r\n}\n\n//types are GETIMAGE, LIVEWORKSHEET, GETTWILIOTOKEN, OPENAIIMG\n\nexport async function makeOpenAIImg(value) {\n    let v = {\n        prompt: value,\n        n: 1,\n        size: \"256x256\",\n    }\n    return getImage(\"OPENAIIMG\", v, null)\n    // var data = { \"type\": \"OPENAIIMG\", \"value\":  v}\n    // var res = await dummyPost(\"http://localhost:5001/voiceToText\", JSON.stringify(data))\n    // return res\n}\n\nexport async function makeOpenAChat(value) {\n    let messages = [{ \"role\": \"user\", \"content\": \"Say this is a test!\" }]\n    messages[0].content = value\n    let v = {\n        model: \"gpt-3.5-turbo\",\n        messages: messages,\n        temperature: 0.7\n    }\n    return getImage(\"OPENAICHAT\", v, null)\n    // var data = { \"type\": \"OPENAICHAT\", \"value\":  v}\n    // var res = await dummyPost(\"http://localhost:5001/voiceToText\", JSON.stringify(data))\n    // return res\n}\n\nexport async function getImage(type, img, value2) {\n    var data = { \"type\": type, \"value\": img, 'value2': value2 }\n    // var res = dummyPost(\"http://localhost:5000/voiceToText\", JSON.stringify(data))\n    let res = await API.post('serviceApi', '/voiceToText', {\n        method: 'POST',\n        headers: {\n            'Content-Type': 'application/json',\n        },\n        body: data\n    })\n    return res\n}\n\nexport async function findUserToMove(oldEmail, newEmail) {\n    var old = await findUserProfileByEmail(oldEmail)\n    var newU = await findUserProfileByEmail(newEmail)\n    let r1 = old.data.byEmamilUP.items\n    let r2 = newU.data.byEmamilUP.items\n    let ret = { old: r1, new: r2 }\n    return ret\n}\n\nexport function updateUserSessions(oldUser, newUser) {\n    // oldUser = \"Google_103551648094941245966\"\n    // newUser = \"Google_110645326004672122267\"\n    // var once1 = false\n    // var once2 = false\n    function oldFolder(items) {\n        if (!items) return\n        console.log(\"GOT ITEMS\", items)\n        items.forEach(i => {\n            // if (once1) return\n            // once1 = true\n            delete i['user']\n            delete i['createdAt']\n            delete i['updatedAt']\n\n            i.userProfileId = newUser\n            console.log(\"UPDATING\", i)\n            updateFolder(i)\n        })\n    }\n\n    function oldSession(items) {\n        console.log(\"GOT Session ITEMS\", items)\n        items.forEach(async i => {\n            // if (once2) return\n            // once2 = true\n            delete i['MultiBoard']\n            delete i['Objects']\n            delete i['Users']\n            delete i['createdAt']\n            delete i['updatedAt']\n            i.CreatorLocalID = newUser\n            i.savedOwner = newUser\n            console.log(\"UPDATE SESSION\", i)\n            const cmd = { id: i.Classroom, TeacherID: newUser }\n            console.log(\"UPdate class\", cmd)\n            await new Promise(r => setTimeout(r, 500));\n\n            updateClassroom(cmd)\n            updateSession(i)\n        })\n\n    }\n\n    function oldClass(items) {\n        items.forEach(i => {\n            const cmd = { id: i.id, TeacherID: newUser }\n            console.log(\"UPdate class\", cmd)\n\n            updateClassroom(cmd)\n        })\n    }\n    GetFoldersByOwner(oldUser, oldFolder, null)\n    listSessionByOwner(oldUser, oldSession, null)\n\n    listClassroomByTeacher(oldUser, oldClass, null)\n}\n\nexport function userPaidPlan() {\n    var paidPlan = mylocalStorage.getItem('paidPlan');\n    if (paidPlan === null || paidPlan === \"educator-free\") {\n        return \"educator-free\";\n    } else return paidPlan;\n}\n\nvar wobotDisabled = true\n\nexport function wobotDisable() {\n    wobotDisabled = true\n\n    if (window.kommunicate && window.kommunicate.displayKommunicateWidget) {\n        window.kommunicate.displayKommunicateWidget(false);\n    }\n    console.log(\"DS WOBOT\")\n}\nvar isBotLoaded = false\nvar rcSession = null\nvar isChatOpen = false\nlet rcSub = null\nexport function unsubscribeRC() {\n    if (rcSub) rcSub.unsubscribe()\n    rcSub = null\n}\nexport function subscribeRC(sess, cb) {\n    rcSession = { sess: sess, cb: cb }\n    let lu = mylocalStorage.getItem(\"kommunicate\")\n\n    if (!isChatOpen && !(lu && lu.includes(\"mckActiveConversationInfo\"))) {\n        return\n    }\n    unsubscribeRC()\n    setWobotContext()\n    console.log(\"SUBSCRIBE)\")\n    const s1 = API.graphql(graphqlOperation(autoSub.subscribeToRemoteControl, { parentID: sess.parentID }))\n    rcSub = s1.subscribe({\n        next: value => {\n            console.log(\"SUBSCRIBE)\", value)\n            const data = value.value.data.subscribeToRemoteControl\n            cb(data)\n        }\n    })\n}\n\nfunction setWobotContext() {\n    if (!window.kommunicate || !window.kommunicate.updateChatContext) return\n    let lu = mylocalStorage.getItem('mystoreID');\n    let parent = rcSession ? rcSession.sess.parentID : null\n    var chatContext = {\n        \"url\": window.location.href,\n        \"parentID\": parent,\n        \"lu\": lu\n    }\n    window.kommunicate.updateChatContext(chatContext);\n}\nfunction wobotLoaded(e) {\n    if (wobotDisabled) {\n        wobotDisable()\n        return\n    }\n    setWobotContext()\n    var events = {\n        'onMessageReceived': function (resp) {\n            //called when a new message is received\n        },\n        'onChatWidgetOpen': function (r) {\n            isChatOpen = true\n            if (rcSession) {\n                subscribeRC(rcSession.sess, rcSession.cb)\n            }\n        },\n        'onChatWidgetClose': function (r) {\n            isChatOpen = false\n            unsubscribeRC()\n        }\n\n    }\n    window.kommunicate.subscribeToEvents(events);\n}\nexport function wobotEnable(u) {\n    let lu = mylocalStorage.getItem(\"disableWobot\")\n    if (lu) return\n    const mobile = (typeof window.orientation !== 'undefined' && (window.screen.width < 1100))\n    if (mobile) return\n    if (isBotLoaded) {\n        if (window.kommunicate && window.kommunicate.displayKommunicateWidget) {\n            window.kommunicate.displayKommunicateWidget(true);\n        }\n        return\n    }\n    isBotLoaded = true;\n    var kommunicateSettings = {\n        \"appId\": \"35fc90786629d1baaf7eb3f5bd123c993\",\n        \"popupWidget\": true, \"automaticChatOpenOnNavigation\": true,\n        \"voiceInput\": true, voiceOutput: false,\n        voiceName: \"Google UK English Female\"\n    };\n    kommunicateSettings.restartConversationByUser = true;\n    wobotDisabled = false //reset once after disabled\n    kommunicateSettings.onInit = wobotLoaded\n    if (u && u.username) {\n        kommunicateSettings.userId = u.username\n        kommunicateSettings.userName = u.attributes && u.attributes.name ? u.attributes.name : u.attributes.email\n        kommunicateSettings.email = u.attributes.email\n    }\n    (function (d, m) {\n        var s = document.createElement(\"script\"); s.type = \"text/javascript\"; s.async = true;\n        s.src = \"https://widget.kommunicate.io/v2/kommunicate.app\";\n        var h = document.getElementsByTagName(\"head\")[0]; h.appendChild(s);\n        window.kommunicate = m; m._globals = kommunicateSettings;\n    })(document, window.kommunicate || {});\n\n}\n\nexport function getPlanDisplayName(planName) {\n    var paidPlan = mylocalStorage.getItem('paidPlan');\n    if (!planName) {\n        if (paidPlan === null || paidPlan === \"educator-free\") {\n            return \"Educator-Free\";\n        }\n    }\n    let name = planName ? planName : paidPlan;\n    switch (name) {\n        case 'gold':\n            return 'Gold Monthly'\n        case 'goldannual':\n            return 'Gold Annual'\n        case 'starter':\n            return 'Starter Monthly'\n        case 'starterannual':\n            return 'Starter Annual'\n        case 'basic':\n            return 'Basic Monthly'\n        case 'basicannual':\n            return 'Basic Annual'\n        default:\n            return \"Educator-Free\";\n    }\n}\n\nexport function createTeam(cmd) {\n    return gqlOperationWithRetry(autoMutation.createTeam, { input: cmd })\n}\n\nexport function getTeam(id) {\n    return gqlOperationWithRetry(autoQuery.getTeam, { id: id })\n}\n\nexport function updateTeam(cmd) {\n    return gqlOperationWithRetry(autoMutation.updateTeam, { input: cmd })\n}\n\nexport function deleteTeam(cmd) {\n    return gqlOperationWithRetry(autoMutation.deleteTeam, { input: { id: cmd.id } })\n}\n\nexport async function listTeamSync(tenantID) {\n    var allList = []\n    var nt = null\n    do {\n        const cmd = { limit: 100, nextToken: nt, TenantID: tenantID }\n        var res = await gqlOperationWithRetry(autoQuery.byTeamTenant, cmd)\n        const dat = res.data.byTeamTenant\n        allList = [...allList, ...dat.items]\n        nt = dat.nextToken\n    } while (nt !== null)\n    return allList\n}\n\nexport function findUserProfileByEmail(email) {\n    const cmd = {\n        email: email,\n        limit: 100,\n        nextToken: null\n    }\n    return gqlOperationWithRetry(autoQuery.byEmamilUP, cmd)\n}\n\nexport function listSessionByClassroomForTTL(Classroom, cb, nextToken, filter) {\n    var cmd = { limit: 100, nextToken: nextToken, Classroom: Classroom, sortDirection: \"ASC\", filter: { deleted: { ne: true } } }\n    cmd['filter'] = { and: { ttl: { ne: 950000000 }, deleted: { ne: true } } }\n\n    gqlOperationWithRetry(customops.queryByClassroom, cmd).then(res => {\n        const dat = res.data.queryByClassroom\n        if (dat) cb(dat.items)\n        if (dat.nextToken) {\n            listSessionByClassroomForTTL(Classroom, cb, dat.nextToken)\n        }\n    })\n}\n\n\nexport function listSessionByOwnerWithExpireDate(ownerid, cb, nextToken) {\n    const cmd = { limit: 100, nextToken: nextToken, savedOwner: ownerid, sortDirection: \"ASC\", filter: { deleted: { ne: true } } }\n    cmd['filter'] = {  deleted: { ne: true } }\n    // cmd['filter'] = { name: { eq: 'hello' } } //for testing\n    gqlOperationWithRetry(customops.queryBySavedOwner, cmd).then(res => {\n        const dat = res.data.queryBySavedOwner\n        if (dat) cb(dat.items)\n        if (dat.nextToken) {\n            listSessionByOwner(ownerid, cb, dat.nextToken)\n        }\n    })\n}\n\nexport function assignLicense(userProfiles, tenant) {\n    let entitlement = JSON.parse(tenant.entitlements)\n    userProfiles.forEach(element => {\n        const cmd = { id: element, TenantID: tenant.id, paidPlan: entitlement.planType }\n        return gqlOperationWithRetry(autoMutation.updateUserProfile, { input: cmd });\n    });\n}\n\nexport function revokeLicense(userProfiles, cb, all) {\n    userProfiles.forEach(element => {\n        const cmd = { id: element, TenantID: null, paidPlan: 'starter' }\n        gqlOperationWithRetry(autoMutation.updateUserProfile, { input: cmd }).then((res) => {\n            let data = res.data.updateUserProfile\n            if (data && !all) {\n                //callback\n                cb(data)\n            }\n        })\n    });\n    if (all) cb()\n}\n\nasync function getAllTenantUsers(id, nt, d, cb) {\n    while (nt) {\n        const cmd = {\n            TenantID: id,\n            limit: 100,\n            nextToken: nt\n        }\n        let res = await gqlOperationWithRetry(autoQuery.UPByTenant, cmd)\n        const dat = res.data.UPByTenant\n        nt = dat.nextToken\n        d.licensedUsers.items = [\n            ...d.licensedUsers.items,\n            ...dat.items\n        ]\n    }\n    cb(d)\n}\nexport function listTenant(id, cb) {\n    // let prox = \"6a00ed50-1f34-4b30-84b5-1e7767ee90f5\"\n    gqlOperationWithRetry(autoQuery.getTenant, { 'id': id }).then(res => {\n        //    console.log('list tenant', res.data.getTenant)\n        let d = res.data.getTenant\n        if (d && d.licensedUsers && d.licensedUsers.nextToken) {\n            let nt = d.licensedUsers.nextToken\n            getAllTenantUsers(id, nt, d, cb)\n        } else {\n            cb(res.data.getTenant)\n        }\n    })\n}\n\nexport function getTenantById(id) {\n    return gqlOperationWithRetry(autoQuery.getTenant, { 'id': id })\n}\n\nexport function listTenantByDomain(tenant) {\n    return gqlOperationWithRetry(autoQuery.queryByDomainName, { 'domainName': tenant })\n}\n\nexport function updateTenant(cmd) {\n    return gqlOperationWithRetry(autoMutation.updateTenant, { input: cmd })\n}\n\n/*\n * IN Master, put:\n  \"secondaryDomainConfig\": {\n    \"M\": {\n      \"allowedDomains\": {\n        \"S\": \"epiphani.io,epiphani.ai,whiteboard.chat\"\n      }\n    }\n  },\n  \n  ****** In others where you want to assign license put, e.g teacher domain\n\n\"secondaryDomainConfig\": {\n    \"M\": {\n      \"mainDomain\": {\n        \"S\": \"3491feb9-42df-428d-8574-951670c859d1\"\n        }\n    }\n  },\n  */\n\nexport function createTenant(t, cb) {\n    const cmd = { name: t.name, domainName: t.domainName, entitlements: JSON.stringify(t.entitlements), adminUsers: t.adminUsers }\n    if (t.id) cmd.id = t.id\n    gqlOperationWithRetry(autoMutation.createTenant, { input: cmd }).then(res => {\n        cb(res.data.createTenant)\n    })\n}\n\n\nexport function getFEM(id) {\n    return gqlOperationWithRetry(autoQuery.getFrequentEngagementMin, { 'id': id })\n}\n\nexport function listFEMByAvatar(Avatar) {\n    return gqlOperationWithRetry(autoQuery.byAvatar, { 'AvatarName': Avatar })\n}\nexport async function listFEM() {\n    let nt = null\n    let arr = []\n    do {\n        const cmd = {\n            limit: 100, nextToken: nt, sortDirection: \"ASC\", filter: { Public: { eq: true } }\n        };\n        var res = await gqlOperationWithRetry(autoQuery.listFrequentEngagementMins, cmd)\n\n        const dat = res.data.listFrequentEngagementMins\n        if (dat && dat.items && dat.items.length > 0) {\n            const d = dat.items\n            arr = [...arr, ...d]\n        }\n        nt = dat.nextToken\n    } while (nt !== null)\n\n    return arr\n}\n\nexport function listFEMByRanking(id) {\n    return gqlOperationWithRetry(autoQuery.ByFEMRanking, { 'Ranking': id })\n}\nexport function createFEM(cmd) {\n    if (isRestricted()) {\n        return\n    }\n    return gqlOperationWithRetry(autoMutation.createFrequentEngagementMin, { input: cmd })\n}\n\nexport function updateFEM(cmd) {\n    if (isRestricted()) {\n        return\n    }\n    return gqlOperationWithRetry(autoMutation.updateFrequentEngagementMin, { input: cmd })\n}\n\nexport function updateUserProfileForTenant(obj) {\n    delete obj['Tenant']\n    delete obj['TenantID']\n    delete obj['isChecked']\n    return gqlOperationWithRetry(autoMutation.updateUserProfile, { input: obj });\n}\n\nexport function checkTenantExists(name, cb, nextToken) {\n    const cmd = { name: name, limit: 100, nextToken: nextToken }\n    gqlOperationWithRetry(customops.queryByTenantName, cmd).then(res => {\n        const dat = res.data.queryByTenantName\n        if (dat && dat.items.length > 0) {\n            cb(true)\n        } else {\n            cb(false)\n        }\n        if (dat.nextToken) {\n            checkTenantExists(name, cb, dat.nextToken)\n        }\n    })\n}\n\nexport function getMyName() {\n    let name = mylocalStorage.getItem('myname');\n    return name ? name : \"none\"\n}\n\nexport function isSiteAdmin() {\n    let siteAdmin = false\n    let authUser = Auth && Auth.user ? Auth.user : null\n    if (authUser && authUser.attributes && authUser.attributes.email) {\n        if (authUser.attributes.email === \"feedback@whiteboard.chat\") siteAdmin = true\n        if (authUser.attributes.email.includes(\"epiphani.io\")) siteAdmin = true\n    }\n    return siteAdmin\n}\n\nexport function updateBoard(cmd) {\n    return gqlOperationWithRetry(autoMutation.updateSession, { input: cmd });\n}\n\nexport function postBoardMessage(name) {\n    let g = mylocalStorage.getItem('apiArgs')\n    if (g) {\n        window.parent.postMessage({ changedBoardName: name }, \"*\")\n    }\n}\n\nexport function createTutorGroup(cmd) {\n    return gqlOperationWithRetry(autoMutation.createTutorGroup, { input: cmd });\n}\n\nexport function updateTutorGroup(cmd) {\n    return gqlOperationWithRetry(autoMutation.updateTutorGroup, { input: cmd });\n}\n\nexport function getTutorGroup(id) {\n    return gqlOperationWithRetry(autoQuery.getTutorGroup, { 'id': id })\n}\n\nexport function createTutorClass(cmd) {\n    return gqlOperationWithRetry(autoMutation.createTutorClass, { input: cmd });\n}\n\nexport function updateTutorClass(cmd) {\n    return gqlOperationWithRetry(autoMutation.updateTutorClass, { input: cmd });\n}\n\nexport function getTutorClass(id) {\n    return gqlOperationWithRetry(autoQuery.getTutorClass, { 'id': id })\n}\n\n\nexport function deleteTutorClass(id) {\n    return gqlOperationWithRetry(autoMutation.deleteTutorClass, { input: { 'id': id } })\n}\n\nexport async function listClassByTutorGroup(id) {\n    var allList = []\n    var nt = null\n    do {\n        const cmd = { limit: 100, nextToken: nt, TutorGroupID: id }\n        var res = await gqlOperationWithRetry(autoQuery.queryClassByTutorGroup, cmd)\n        const dat = res.data.queryClassByTutorGroup\n        allList = [...allList, ...dat.items]\n        nt = dat.nextToken\n    } while (nt !== null)\n    return allList\n}\n\nexport function updateSessionBoards(sess, cb, args) {\n    function updateBoards(items) {\n        if (!items) return\n        items.forEach((item) => {\n            cb(item, args)\n            updateSession(item)\n        })\n    }\n    getboardsbyparent(sess.parentID, null, gotBoards)\n    function gotBoards(items) {\n        updateBoards(items)\n    }\n    if (sess.Classroom) {\n        listSessionByClassroom(sess.Classroom, gotBoards, null, false, null)\n    }\n}\n\nexport async function checkTutorClass(user, sess, userProfile) {\n    let em = user.attributes.email.toLowerCase()\n    let email = removeMSTeamsEmail(em)\n\n    let dat = await getTutorClass(sess.TutorClass)\n    let tc = dat.data.getTutorClass\n    let jj = []\n    try {\n        jj = JSON.parse(tc.roster)\n    } catch (e) {\n        console.error(\"CHECK \", e, tc)\n    }\n    for (let i in jj) {\n        let c = jj[i]\n        if (c.email === email) {\n            //found user\n            mylocalStorage.setItem('myname', c.name)\n            return c\n        }\n    }\n    if(userProfile) {\n        if (userProfile.TutorGroupID === tc.TutorGroupID) return \"admin\"\n    }\n    return null\n\n}\n\n\nexport function createTutorClassEvent(cmd) {\n    return gqlOperationWithRetry(autoMutation.createTutorClassEvent, { input: cmd });\n}\n\nexport function updateTutorClassEvent(cmd) {\n    return gqlOperationWithRetry(autoMutation.updateTutorClassEvent, { input: cmd });\n}\n\nexport function deleteTutorClassEvent(id) {\n    return gqlOperationWithRetry(autoMutation.deleteTutorClassEvent, { input: { 'id': id } })\n}\n\nexport function createVideoRoom(cmd) {\n    return gqlOperationWithRetry(autoMutation.createVideoRoom, { input: cmd });\n}\n\nexport function updateVideoRoom(cmd) {\n    return gqlOperationWithRetry(autoMutation.updateVideoRoom, { input: cmd });\n}\n\nexport function deleteVideoRoom(id) {\n    return gqlOperationWithRetry(autoMutation.deleteVideoRoom, { input: { 'id': id } })\n}\nexport async function listVideoRoomBySessionSync(id) {\n    var allList = []\n    var nt = null\n    do {\n        const cmd = { limit: 100, nextToken: nt, SessionID: id }\n        var res = await gqlOperationWithRetry(autoQuery.videoRoomBySession, cmd)\n        const dat = res.data.videoRoomBySession\n        allList = [...allList, ...dat.items]\n        nt = dat.nextToken\n    } while (nt !== null)\n    return allList\n}\n\nexport async function listVideoRoomBySID(id) {\n    var allList = []\n    var nt = null\n    do {\n        const cmd = { limit: 100, nextToken: nt, SID: id }\n        var res = await gqlOperationWithRetry(autoQuery.videoRoomBySID, cmd)\n        const dat = res.data.videoRoomBySID\n        allList = [...allList, ...dat.items]\n        nt = dat.nextToken\n    } while (nt !== null)\n    return allList\n}\n\nexport async function findCreateRoomBySid(cmd) {\n    let x = await listVideoRoomBySID(cmd.SID)\n    if (x && x.length > 0) return; //found room\n    createVideoRoom(cmd)\n}\n\nexport async function setRecordingOnRoomBySid(SID) {\n    let x = await listVideoRoomBySID(SID)\n    if (x && x.length > 0) {\n        let rm = x[0]\n        rm.recordingTurnedOn = true\n        delete rm[\"Session\"]\n        updateVideoRoom(rm)\n    }\n}\n\nexport async function getRecordings(sessId) {\n    // id = \"9ed453f1-720e-4344-959f-3306c68b12a3\"\n    let ses = await getSession(sessId)\n    let session = ses.data.getSession\n    if (!session) return []\n    let id = session.Classroom ? session.Classroom : session.parentID\n    let rec = []\n    let x = await listVideoRoomBySessionSync(id)\n    if (!x || x.length === 0) return null; //found room\n    for (let i in x) {\n        let rm = x[i]\n        if (rm.recordingTurnedOn) {\n            rec.push(rm)\n        }\n    }\n    return rec\n}\n\nexport async function listTutorClassEventSync(id) {\n    var allList = []\n    var nt = null\n    do {\n        const cmd = { limit: 100, nextToken: nt, TutorClassID: id }\n        var res = await gqlOperationWithRetry(autoQuery.eventByTutorClass, cmd)\n        const dat = res.data.eventByTutorClass\n        allList = [...allList, ...dat.items]\n        nt = dat.nextToken\n    } while (nt !== null)\n    return allList\n}\n\nexport function listTutorClassEvent(classId, cb, nextToken) {\n    const cmd = { limit: 100, nextToken: nextToken, TutorClassID: classId }\n    gqlOperationWithRetry(autoQuery.eventByTutorClass, cmd).then(c => {\n        let dat = c.data.eventByTutorClass\n        cb(dat.items)\n        if (dat.nextToken) {\n            listTutorClassEvent(classId, cb, nextToken)\n        } else {\n            cb(null)\n        }\n    })\n}\n\n// context args: user, cb, delcb, subCB, doList=true, retryCount=SUB_MAX_RETRY_COUNT\nexport function SubscribeToTutorClassEvent(context) {\n    if (context.retryCount === undefined) context.retryCount = SUB_MAX_RETRY_COUNT;\n    if (context.doList === undefined) context.doList = true;\n    if (context.doList) listTutorClassEvent(context.classId, context.cb, null)\n    const s1 = API.graphql(graphqlOperation(autoSub.subscribeToTutorClassEvent, { TutorClassID: context.classId }))\n    var s2, s4;\n    let retried = false;\n    s2 = trySubscribe(s1, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.subscribeToTutorClassEvent\n            context.cb([data])\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(retried, \"subscribeToTutorClassEvent:subscribeToTutorClassEvent\",\n                error, s4, SubscribeToTutorClassEvent, context);\n            retried = true;\n        }\n    }, \"SubscribeToTutorClassEvent:subscribeToTutorClassEvent\");\n    const s3 = API.graphql(graphqlOperation(autoSub.subscribeToTutorClassEventDel, { TutorClassID: context.classId }))\n    s4 = trySubscribe(s3, {\n        next: (value) => {\n            if (context.retryCount < SUB_MAX_RETRY_COUNT) context.retryCount = SUB_MAX_RETRY_COUNT;\n            const data = value.value.data.subscribeToTutorClassEventDel\n            context.delcb(data)\n        },\n        error: (error) => {\n            console.log(JSON.stringify(error));\n            checkAndReSubscribe(retried, \"subscribeToTutorClassEventDel:subscribeToTutorClassEventDel\",\n                error, s2, SubscribePersonalPalettesByOwner, context);\n            retried = true;\n        }\n    }, \"subscribeToTutorClassEventDel:subscribeToTutorClassEventDel\");\n    context.subCB([s2, s4]);\n}\n\nfunction downloadJsonFile(data, filename){\n    // Creating a blob object from non-blob data using the Blob constructor\n    const blob = new Blob([data], { type: 'application/json' });\n    const url = URL.createObjectURL(blob);\n    // Create a new anchor element\n    const a = document.createElement('a');\n    a.href = url;\n    a.download = filename || 'download';\n    a.click();\n    a.remove();\n  }\n\nexport async function exportObjectsJson(boardId) {\n    let items = await listObjectSync(boardId)\n    let finalData = []\n    for (let i = 0; i < items.length; i++) {\n        let item = items[i]\n        expandObj(item)\n        delete item['Session']\n        finalData.push(item)\n    }\n    let data = JSON.stringify(finalData, null, 4)\n    // console.log(\"DATA === \", finalData, data)\n    const filename = boardId + '.json';\n    downloadJsonFile(data, filename)\n}\nexport function isExternalApi() {\n    return window.location.href.includes(\"apiModeLoad\")\n}\n\nexport async function chatGPTAPI(data)  {\n    // return await postData(data)\n\n    const response = await fetch(\"https://api.epiphani.ai/\", {\n        method: 'POST',\n        headers: {\n            'Content-Type': 'application/json',\n        },\n        body: data\n    })\n    var r = await response.json();\n    return r\n\n}\n\n","import config from './aws-exports'\nimport { Storage } from 'aws-amplify'\nimport { v4 as uuid } from \"uuid\";\n\nimport * as ib from './ibdata'\nimport * as WBCReactGA from './WBCReactGA';\nimport * as uUtils from './UsersUtils'\nimport * as mylocalStorage from \"./mylocalStorage\"\n\nconst {\n    aws_user_files_s3_bucket_region: region,\n    aws_user_files_s3_bucket: bucket\n} = config\n\n// function readFileAsync(file) {\n//     return new Promise((resolve, reject) => {\n//         let reader = new FileReader();\n\n//         reader.onload = () => {\n//             resolve(reader.result);\n//         };\n\n//         reader.onerror = reject;\n\n//         reader.readAsArrayBuffer(file);\n//     })\n// }\n\nexport function dataURLtoFile(dataurl, filename) {\n\n    var arr = dataurl.split(','),\n        mime = arr[0].match(/:(.*?);/)[1],\n        bstr = atob(arr[1]),\n        n = bstr.length,\n        u8arr = new Uint8Array(n);\n\n    while (n--) {\n        u8arr[n] = bstr.charCodeAt(n);\n    }\n\n    return new File([u8arr], filename, { type: mime });\n}\n\n\nexport var dataURItoBlob = function (dataURI) {\n    var bytes = dataURI.split(',')[0].indexOf('base64') >= 0 ?\n        atob(dataURI.split(',')[1]) :\n        unescape(dataURI.split(',')[1]);\n    var mime = dataURI.split(',')[0].split(':')[1].split(';')[0];\n    var max = bytes.length;\n    var ia = new Uint8Array(max);\n    for (var i = 0; i < max; i++)\n        ia[i] = bytes.charCodeAt(i);\n    return new Blob([ia], { type: mime });\n};\n\nasync function resizeImage(settings) {\n    var file = settings.file;\n    var maxSize = settings.maxSize;\n    var reader = new FileReader();\n    var image = new Image();\n    var canvas = document.createElement('canvas');\n    canvas.style.background = \"#ffffff\"\n    var resize = function () {\n        var width = image.width;\n        var height = image.height;\n        var resize = false\n        if (width > height) {\n            if (width > maxSize) {\n                height *= maxSize / width;\n                width = maxSize;\n                resize = true\n            }\n        } else {\n            if (height > maxSize) {\n                width *= maxSize / height;\n                height = maxSize;\n                resize = true\n            }\n        }\n        canvas.width = width;\n        canvas.height = height;\n        var ctx = canvas.getContext('2d')\n        if (settings.ext !== \"png\" || resize) {\n            ctx.fillStyle = \"#FFFFFF\";\n            ctx.fillRect(0, 0, width, height);\n        }\n        ctx.drawImage(image, 0, 0, width, height);\n        var img = \"jpeg\"\n        if (settings.ext === \"png\" && !resize) img = \"png\"\n        var dataUrl = canvas.toDataURL('image/' + img);\n        var imgR = resize ? \"jpg\" : settings.ext\n        return ({ file: dataURItoBlob(dataUrl), ext: imgR })\n    };\n\n    return new Promise(function (ok, no) {\n        if (!file.type.match(/image.*/)) {\n            no(new Error(\"Not an image\"));\n            return;\n        }\n        reader.onload = function (readerEvent) {\n            image.onload = function () {\n                return ok(resize());\n            };\n\n            image.onerror = function (ev) {\n                console.log('Image on error', ev)\n            }\n            image.src = readerEvent.target.result;\n        };\n        reader.readAsDataURL(file);\n    });\n};\n\nexport function createImageRaster(url, pgNum, randompages, numPages, ttl = 0, text, w, h, ratio) {\n    let x = 20 + w / 2;\n    let y = 20 + h / 2;\n    let scale = ratio;\n    var raster = [\"Raster\", {\n        \"applyMatrix\": false, \"matrix\": [scale, 0, 0, scale, x, y], \"data\": { \"drawPaper\": true, pdfText: text }, \"crossOrigin\": \"anonymous\",\n        \"source\": url\n    }]\n    const id = uuid()\n    const splitstring = window.location.href.includes(\"phonescan\") ? \"/phonescan/\" : \"/board/\"\n    const JOINURL = window.location.href.split(splitstring)\n    var local = JOINURL[1].split(\"?\")[0]\n    var fd = local.split(\"-pgNum-\")\n    var finalPage = Number(fd[1]) + (pgNum - 1)\n    var finalSession = fd[0] + \"-pgNum-\" + finalPage\n\n    let content = JSON.stringify(raster)\n    let tobj = {\n        content: content,\n        type: null\n    }\n    var copy = ib.prepObj(tobj, true)\n\n    ib.createObject(id, \"name\", finalSession, copy.content, \"drawPaper\", null, copy.type, ttl).then(res => {\n        // var obj = res.data.createObject\n        // // if finshed by now we should update \n\n        // obj.content = JSON.stringify(raster)\n        // var copy = ib.prepObj(obj, true)\n        // if (copy) {\n        //     copy.id = obj.id\n        //     delete copy['Session']\n        //     ib.updateObject(copy)\n        // }\n    })\n\n    ib.createSessionIfNotThere(finalSession)\n}\n\nexport function createImage(url, pgNum, randompages, numPages, ttl = 0, text) {\n    var id = uuid()\n    const splitstring = window.location.href.includes(\"phonescan\") ? \"/phonescan/\" : \"/board/\"\n    const JOINURL = window.location.href.split(splitstring)\n    var local = JOINURL[1].split(\"?\")[0]\n    var fd = local.split(\"-pgNum-\")\n    var finalPage = Number(fd[1]) + (pgNum - 1)\n    if (window.location.href.includes(\"phonescan\")) {\n        finalPage = pgNum\n    }\n    var finalSession = fd[0] + \"-pgNum-\" + finalPage\n    var content = {\n        type: \"image\", points: { x: 20, y: 20 }, url: url, newPoints: { x: 20, y: 20 },\n        ended: true, pdfText: text\n    }\n    if (randompages !== \"none\") {\n        var ff = {}\n        for (let i = 1; i <= numPages; i++) {\n            ff[i] = \"\"\n        }\n        content.type = randompages\n        content.id = id\n        content.pageArray = ff\n        content['pages'] = numPages\n    }\n    let lu = mylocalStorage.getItem(\"localuserid\")\n    const userid = lu ? lu : null //needs to come from somehwere \n\n    ib.createObject(id, \"name\", finalSession, JSON.stringify(content), \"image\", userid, null, ttl).then(res => {\n        const robj = res.data.createObject\n        delete robj[\"Session\"]\n        ib.updateObject(robj); //used to trigger subs\n    })\n    ib.createSessionIfNotThere(finalSession)\n    if (randompages === \"amongUs\") {\n        // create objects on all pages\n        var ct = JSON.stringify(content)\n        for (let count = 2; count < 10; count++) {\n            id = uuid()\n            finalSession = fd[0] + \"-pgNum-\" + count\n            ib.createObject(id, \"name\", finalSession, ct, \"image\", userid, null, ttl)\n            ib.createSessionIfNotThere(finalSession)\n        }\n    }\n\n}\nasync function loadPDF(file, randompages, ttl = 0, maxSize, sess) {\n    const SCALEPDF = 2.0\n    import(\"pdfjs-dist/build/pdf\").then(p => {\n        let pdfjsLib = p\n        import(\"pdfjs-dist/build/pdf.worker.entry\").then(p2 => {\n            let pdfjsWorker = p2\n            pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker;\n\n            pdfjsLib.getDocument(file).promise.then((pdf) => {\n                //\n                // Fetch the first page\n                //\n                WBCReactGA.event({\n                    category: 'Teacher',\n                    action: \"LoadPDF-\" + pdf.numPages\n                });\n                let maxPages = 50\n                if (randompages === \"bingo\") {\n                    maxPages = 150\n                }\n                if (pdf.numPages > maxPages) {\n                    alert(\"You can only have upto 50 pages per book. Not loading\")\n                    return null\n                }\n                var kk = uuid()\n                for (let pg = 1; pg <= pdf.numPages; pg++) {\n                    // ib.checkBoards(sess).then((pages) => {\n                    //     (pages.length < pg) && ib.duplicatePage(sess.id, pg, false);\n                    // })\n                    pdf.getPage(pg).then(async (page) => {\n                        var scale = SCALEPDF;\n                        var viewport = page.getViewport({ scale: scale, });\n                        var h = viewport.height\n                        var w = viewport.width\n                        var hscale = 1.0\n                        var wscale = 1.0\n                        const maxSize2 = maxSize * SCALEPDF\n                        if (h > maxSize2) hscale = maxSize2 / h\n                        if (w > maxSize2) wscale = maxSize2 / w\n                        if (hscale !== 1 || wscale !== 1) {\n                            scale = hscale < wscale ? hscale : wscale\n                            scale = scale * SCALEPDF\n                            viewport = page.getViewport({ scale: scale, });\n                        }\n                        //\n                        // Prepare canvas using PDF page dimensions\n                        //\n                        var canvas = document.createElement('canvas');\n                        var context = canvas.getContext('2d');\n                        canvas.height = viewport.height;\n                        canvas.width = viewport.width;\n                        var allText = \"\"\n                        var textContent = await page.getTextContent();\n                        if (textContent) {\n                            allText = textContent.items.map(function (s) { return s.str; }).join('\\n'); // value page text \n                        }\n                        //\n                        // Render PDF page into canvas context\n                        //\n                        var task = page.render({ canvasContext: context, viewport: viewport, intent: \"print\" })\n                        task.promise.then(async function () {\n                            // console.log(canvas.toDataURL('image/jpeg'));\n                            var dataUrl = canvas.toDataURL('image/jpeg', 1);\n                            if (randompages === \"amongUs\") {\n                                var avatar = context.getImageData(0, 0, 100, 100);\n                                var c2 = document.createElement('canvas');\n                                c2.height = 100\n                                c2.width = 100\n                                var ctx2 = c2.getContext('2d');\n                                ctx2.fillStyle = \"#FFFFFF\";\n                                ctx2.fillRect(0, 0, 200, 200);\n                                ctx2.putImageData(avatar, 0, 0)\n                                var dataUrl2 = c2.toDataURL('image/jpeg');\n                                // downloadImage(dataUrl2, 'my-canvas.jpeg');\n\n                                var f1 = dataURItoBlob(dataUrl2);\n                                let kb = kk + \"-pg-\" + pg + \"-avatar\"\n                                await wroteFile(f1, kb, null, null)\n                                var rest = context.getImageData(viewport.width / 2, 0, viewport.width, viewport.height);\n                                canvas.width = viewport.width / 2;\n                                context.putImageData(rest, 0, 0)\n                                dataUrl = canvas.toDataURL('image/jpeg');\n                            } else {\n                                let c2 = document.createElement('canvas');\n                                let w = viewport.width / SCALEPDF\n                                let h = viewport.height / SCALEPDF\n\n                                c2.height = h\n                                c2.width = w\n                                // console.log(\"SET H AND W\", h, w)\n                                let ctx2 = c2.getContext('2d');\n                                ctx2.drawImage(canvas, 0, 0, w, h)\n                                if (randompages !== \"none\")\n                                    dataUrl = c2.toDataURL('image/jpeg', 1);\n                            }\n                            var file = dataURItoBlob(dataUrl);\n                            var kb = kk + \"-pg-\" + pg\n                            wroteFile(file, kb, function (url) {\n                                if (randompages === \"none\") {\n                                    createImageRaster(url, pg, randompages, pdf.numPages, ttl, allText, viewport.width / SCALEPDF,\n                                        viewport.height / SCALEPDF, 1 / SCALEPDF)\n                                } else {\n                                    if (pg === 1) {\n                                        createImage(url, pg, randompages, pdf.numPages, ttl, allText)\n                                    }\n                                }\n                            }, null)\n                        });\n                    });\n                }\n            }).catch((error) => {\n                console.log('pdf load ', error)\n            })\n\n        })\n    })\n\n}\n// Save | Download image\n// function downloadImage(data, filename = 'untitled.jpeg') {\n//     var a = document.createElement('a');\n//     a.href = data;\n//     a.download = filename;\n//     document.body.appendChild(a);\n//     a.click();\n// }\n\nexport function generateVideoThumbnail(file) {\n    return new Promise((resolve) => {\n        const canvas = document.createElement(\"canvas\");\n        const video = document.createElement(\"video\");\n\n        // this is important\n        video.autoplay = true;\n        video.muted = true;\n        video.crossOrigin = \"anonymous\"\n        video.src = file; //URL.createObjectURL(file);\n\n        video.onloadeddata = () => {\n            let ctx = canvas.getContext(\"2d\");\n\n            canvas.width = video.videoWidth;\n            canvas.height = video.videoHeight;\n\n            ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);\n            video.pause();\n            return resolve(canvas.toDataURL(\"image/jpg\", 0.8));\n        };\n    });\n}\nfunction processPDF(file, randompages, ttl = 0, maxSize, sess) {\n    return new Promise(function (ok, no) {\n\n        var fileReader = new FileReader();\n        fileReader.onload = function (ev) {\n            loadPDF(ev.target.result, randompages, ttl, maxSize, sess)\n            return ok(ev.target.result);\n        };\n        fileReader.readAsArrayBuffer(file);\n    })\n}\n\nasync function readPNG(file) {\n    var reader = new FileReader();\n    return new Promise(function (ok, no) {\n        if (!file.type.match(/image.*/)) {\n            no(new Error(\"Not an image\"));\n            return;\n        }\n        reader.readAsDataURL(file);\n        reader.onload = function (readerEvent) {\n            return ok(dataURItoBlob(readerEvent.target.result));\n        };\n    });\n}\nexport async function wroteFile(file, inKey, cb, xtn = null, noExpire = false) {\n    var subFolderName = (noExpire || uUtils.userHasNoBoardExpiry()) ? 'paidImages' : 'images'\n    const extension = xtn ? xtn : \"jpg\"\n    const { type: mimeType } = file\n    var kk = inKey ? inKey : uuid()\n    const key = `${subFolderName}/${kk}.${extension}`\n    const url = `https://${bucket}.s3.${region}.amazonaws.com/public/${key}`\n\n    await Storage.put(key, file, {\n        contentType: mimeType,\n        // progressCallback(progress) {\n        //     console.log(`Uploaded: ${progress.loaded}/${progress.total}`);\n        // },\n    }).then(result => {\n        if (cb) cb(url)\n        // deleteS3image(user.data.photoURL)\n    })\n        .catch(err => {\n            console.error(\"changeAvatar error \", err);\n            alert(\"file cannot be uploaded, please check the time on your computer:\", err.message)\n        });\n    return url\n}\n\nasync function fetchSignedUrl(fullUrl) {\n    var fUrl = await GetS3ProfileImage(fullUrl);\n    var readFile;\n    try {\n        // console.log(\"Fetching signed URL\", fUrl);\n        readFile = await fetch(fUrl);\n    } catch (ee) {\n        // console.log(\"Signed URL fetch failed\", ee);\n        return null;\n    }\n    return readFile;\n}\n\nexport async function copyFile(fullUrl, inKey = null, xtn = null, noExpire = false) {\n    // consoleerror(\"copyFile:\", fullUrl, inKey, xtn);\n    const tUrl = fullUrl.split(\"?X-Amz\")[0];\n    var url = (' ' + tUrl).slice(1);\n    if (!inKey) {\n        var ts = url.split('-pg-');\n        var fileExtArr = url.split('.');\n        if (!xtn) xtn = fileExtArr[fileExtArr.length - 1];\n        if (ts.length > 1) {\n            let ext = ts[1].split('.');\n            inKey = uuid() + '-pg-' + ext[0];\n        }\n    }\n\n    // console.log(\"copyFile:\", fullUrl, url);\n    var readFile;\n    try {\n        readFile = await fetch(url);\n        if (readFile.status === 403) {\n            // console.log(\"Fetch un-auth error\", fullUrl, readFile.status, readFile);\n            readFile = await fetchSignedUrl(fullUrl);\n        }\n    } catch (e) {\n        // console.log(\"Fetch failed:\", fullUrl, e);\n        readFile = await fetchSignedUrl(fullUrl);\n    }\n    var readBlob = await readFile.blob();\n    // console.log(\"readBlob:\", readBlob);\n    var newUrl = await wroteFile(readBlob, inKey, null, xtn, noExpire);\n    // console.log(\"copied url:\", newUrl);\n    return newUrl;\n}\n\nexport function getImageURL(name) {\n    const key = `images/${name}`\n    const url = `https://${bucket}.s3.${region}.amazonaws.com/public/${key}`\n\n    return url\n}\n\nexport async function writeBlob(blob, name, mimeType) {\n    const key = `images/${name}`\n\n    const url = getImageURL(name);\n    await Storage.put(key, blob, {\n        contentType: mimeType,\n        // progressCallback(progress) {\n        //     console.log(`Uploaded: ${progress.loaded}/${progress.total}`);\n        // },\n    }).then(result => {\n        // deleteS3image(user.data.photoURL)\n    })\n        .catch(err => {\n            console.error(\"upload error \", err);\n            alert(\"file cannot be uploaded, please check the time on your computer:\", err.message)\n        });\n    return url\n\n}\nexport async function WritePalette(img, cb) {\n\n    const extension = \"png\";\n    var file = dataURItoBlob(img)\n    const { type: mimeType } = file\n    var kk = uuid()\n    const key = `palette/${kk}.${extension}`\n    const url = `https://${bucket}.s3.${region}.amazonaws.com/public/${key}`\n\n    await Storage.put(key, file, {\n        contentType: mimeType,\n        // progressCallback(progress) {\n        //     console.log(`Uploaded: ${progress.loaded}/${progress.total}`);\n        // },\n    }).then(result => {\n        if (cb) cb(url)\n        // deleteS3image(user.data.photoURL)\n    })\n        .catch(err => {\n            console.error(\"changeAvatar error \", err);\n            alert(\"cannot save palette, check the time on your computer\", err)\n        });\n    return url\n}\n\nexport async function UploadSmartFile(infile, sess) {\n    import(\"./SmartImport.js\").then(sj => {\n        sj.SmartImport().importFile(infile, sess)\n    })\n}\n\nexport async function UploadIwbFile(infile, sess, cb) {\n    import(\"./IwbImport.js\").then(sj => {\n        sj.IwbImport().importFile(infile, sess, cb)\n    })\n}\n\nexport async function UploadFile(infile, randompages, ttl = 0, sess, maxSize = 1150) {\n    try {\n        if (infile.type.indexOf(\"application/pdf\") !== -1) {\n            processPDF(infile, randompages, ttl, maxSize, sess)\n\n            return null\n        }\n        var ext = \"jpg\"\n        if (infile.type.indexOf(\"image/png\") !== -1) {\n            ext = \"png\"\n        }\n        if (infile.type.indexOf(\"image/gif\") !== -1) {\n            ext = \"gif\"\n        }\n        WBCReactGA.event({\n            category: 'Teacher',\n            action: \"Load-Image\"\n        });\n        var file\n        if (ext === \"gif\") {\n            file = await readPNG(infile)\n        } else {\n            var fileR = await resizeImage({\n                file: infile,\n                ext: ext,\n                maxSize: maxSize\n            })\n            file = fileR.file\n            ext = fileR.ext\n        }\n\n        var url = await wroteFile(file, null, null, ext)\n        var loadImage = await GetS3ProfileImage(url)\n        return { img: loadImage, url: url }\n    } catch (e) {\n        console.error(\"Something went wrong\", e)\n        alert(\"Could not upload file\", e)\n\n    }\n    return null\n}\n\nexport async function UploadIWBObjects(infile, randompages, ttl = 0, sess, maxSize = 1150) {\n    try {\n        var ext = \"png\"\n        if (infile.type.indexOf(\"image/png\") !== -1) {\n            ext = \"png\"\n        }\n    \n        var url = await wroteFile(infile, null, null, ext)\n        var loadImage = await GetS3ProfileImage(url)\n        return { img: loadImage, url: url }\n\n    } catch (e) {\n        console.error(\"Something went wrong\", e)\n        alert(\"Could not upload file\", e)\n    }\n    return null\n}\n\nexport async function UploadImportedFile(infile, randompages, ttl = 0, maxSize = 1150) {\n    try {\n        if (infile.type.indexOf(\"application/pdf\") !== -1) {\n            processPDF(infile, randompages, ttl, maxSize)\n            return null\n        }\n        var ext = \"jpg\"\n        if (infile.type.indexOf(\"image/png\") !== -1) {\n            ext = \"png\"\n        }\n        if (infile.type.indexOf(\"image/gif\") !== -1) {\n            ext = \"gif\"\n        }\n        if (infile.type === 'mp4') {\n            ext = 'mp4'\n        }\n        WBCReactGA.event({\n            category: 'Teacher',\n            action: \"Load-Image\" + ext\n        });\n        var file\n        var url\n        if (ext === \"gif\") {\n            file = await readPNG(infile)\n        } else {\n            if (ext !== 'mp4') {\n                var fileR = await resizeImage({\n                    file: infile,\n                    ext: ext,\n                    maxSize: maxSize\n                })\n                file = fileR.file\n                ext = fileR.ext\n                url = await wroteFile(file, null, null, ext)\n            }\n        }\n        if (ext === 'mp4') {\n            url = await wroteFile(infile, null, null, \"mp4\")\n        }\n        var loadImage = await GetS3ProfileImage(url)\n        return { img: loadImage, url: url }\n    } catch (e) {\n        console.error(\"Something went wrong\", e)\n        alert(\"Could not upload file\", e)\n\n    }\n    return null\n}\n\n\nexport async function writeFileReturn(b, name) {\n    const file = dataURItoBlob(b)\n    var url = await wroteFile(file, name, null, null)\n    var loadImage = await GetS3ProfileImage(url)\n    return { img: loadImage, url: url }\n}\n\nexport async function GetImage(url) {\n    var loadImage = await GetS3ProfileImage(url)\n    return { img: loadImage, url: url }\n}\nexport function GetS3ProfileImage(url) {\n    if (url) {\n        // console.log(url)\n        if (url.includes('googleusercontent')) {\n            return url;\n        }\n        if (!url.includes('/assets/images/') && !url.includes('/assets/paidImages/')) {\n            var file = url.split('public/').pop();\n            return Storage.get(file, { expires: 604800 })\n                .then(result => {\n                    return result\n                })\n                .catch(err => console.log(err));\n\n        } else {\n            return url\n        }\n    }\n}\n\nexport function GetS3File(url) {\n    if (url) {\n        if (url.includes('googleusercontent')) {\n            return url;\n        }\n        if (!url.includes('/assets/images/') && !url.includes('/assets/paidImages/')) {\n            var file = url.split('public/').pop();\n            return Storage.get(file, { expires: 604800, download: true })\n                .then(result => {\n                    return { img: result, url: url }\n                })\n                .catch(err => console.log(err));\n\n        } else {\n            return url\n        }\n    }\n}\n\nasync function ReadFile(file) {\n    var reader = new FileReader();\n    return new Promise(function (ok, no) {\n        reader.readAsDataURL(file);\n        reader.onload = function (readerEvent) {\n            return ok(dataURItoBlob(readerEvent.target.result));\n        };\n    });\n}\n\nexport async function uploadMediaFile(infile) {\n    var name = infile.name.split(\".\")\n    let ext = name[name.length - 1]\n    let file = await ReadFile(infile)\n    var url = await wroteFile(file, null, null, ext)\n    return url\n}","import {Auth} from 'aws-amplify'\nimport * as mylocalStorage from \"./mylocalStorage\";\n\nexport function userHasNoBoardExpiry() {\n    if (Auth && Auth.user) {\n        if (Auth.user.attributes && Auth.user.attributes.email === \"feedback@whiteboard.chat\") {\n            return true;\n        }\n\n        var paidUserPlan = mylocalStorage.getItem('paidPlan');\n\n        if (paidUserPlan && paidUserPlan.startsWith('gold')) {\n            return true;\n        }\n    }\n    return false;\n}\n\nexport function getUserEmail() {\n    if (Auth && Auth.user) {\n        if (Auth.user.attributes && Auth.user.attributes.email) {\n            return Auth.user.attributes.email;\n        }\n    }\n    return null;\n}\n\n// Takes a UserProfile object from DynamoDB as argument.\nexport function getChargeBeeId(userProfile) {\n    var userId = userProfile.id;\n\n    if (userId.startsWith(\"Microsoft\")) {\n        userId = userId.replace(\"Microsoft\", \"MS\");\n    }\n\n    return userId;\n}\n\n\nexport function validateEmail (email) {\n    const regexp = /^(([^<>()[\\]\\\\.,;:\\s@\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/;\n    return regexp.test(email);\n}","import {Amplify} from \"aws-amplify\";\nimport awsExports from \"./aws-exports\";\n\nvar initDone = false \nexport function AmpInit() {\n    // Setup SocialAuth Redirect URLs\n    if (initDone) return\n    initDone = true\n    if (awsExports.oauth) {\n        awsExports.oauth.redirectSignIn = window.location.origin + \"/login/\";\n        awsExports.oauth.redirectSignOut = window.location.origin + \"/logout/\";\n        awsExports.aws_appsync_authenticationType = \"AWS_IAM\"\n    }\n\n    Amplify.configure(awsExports);\n}"],"sourceRoot":""}