From 141382c4996598d2325c888904083ec0dc8a812a Mon Sep 17 00:00:00 2001 From: Deon George Date: Thu, 9 Jul 2020 23:12:17 +1000 Subject: [PATCH] Complete user registration, added idle inactivity timeout --- load/defs.js | 2 + load/register.js | 194 +++++++++++++++++++++++++++++++++-------------- main.js | 112 ++++++++++++++++++++++----- save.js | 4 +- text/11a.tex | 2 +- text/981a.tex | 2 +- text/98a.tex | 2 +- 7 files changed, 235 insertions(+), 83 deletions(-) diff --git a/load/defs.js b/load/defs.js index 0bd3d5e..6f72cdb 100644 --- a/load/defs.js +++ b/load/defs.js @@ -41,6 +41,8 @@ var ERR_NOT_IMPLEMENTED ='\1n\1h\1RNOT IMPLEMENTED YET?'; var ERR_ROUTE ='\1n\1h\1WMISTAKE? \1GTRY AGAIN OR TELL US ON *08'; var ERR_METHOD_NOT_EXIST ='\1n\1h\1WMISTAKE? \1GTRY AGAIN OR TELL US ON *08'; var ACCESS_DENIED ='\1n\1h\1RACCESS DENIED. \1RMISTAKE? TRY AGAIN OR TELL US *08'; +var INACTIVITY ='\1n\1h\1RINACTIVITY ALERT'; +var INACTIVE ='\1n\1h\1RINACTIVITY DISCONNECT'; var NO_HISTORY_FRAMES =['980a','98b','981a']; diff --git a/load/register.js b/load/register.js index 39efdb7..debf697 100644 --- a/load/register.js +++ b/load/register.js @@ -1,96 +1,176 @@ +/** + * This handles user registration. + * + * The form must have the following fields: + * + UID The user's user id to login + * + EMAIL The users's email address - to receive tokens + * + FULLNAME The user's full name + * + PASS The users's preferred password + * + CITY The user's city + * + COUNTRY The user's country - 3 letter ISO code + * + PCODE THe user's postal code + */ + var CONTROL_REGISTER ='1'; var EMAIL_REGEX = /^(([^<>()[\]\\.,;:\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,}))$/; -var cValChars='ACDEFHJKLMNPQRTUVWXY23456789!@#$%&*'; +var cValChars='ACDEFHJKLMNPQRTUVWXY23456789!@$%&'; -log(LOG_DEBUG,'Control REGISTER loaded'); +log(LOG_DEBUG,'+ Control REGISTER loaded'); function register() { var code = ''; + var complete = false; this.handle=function(read) { log(LOG_DEBUG,'Control REGISTER handle() start. ('+read+')'); - log(LOG_DEBUG,'Field '+cf.fname+'('+JSON.stringify(cf)+')'); + log(LOG_DEBUG,'- Field '+cf.fname+'('+JSON.stringify(cf)+')'); if ((cf.fname == 'TOKEN') && (read == '#' || read == '\r')) { - if (cf.fvalue !== code) { + if (cf.fvalue == code) { + complete = true; + + } else { sendBaseline('\1n\1h\1RINVAID CODE, PLEASE TRY AGAIN *00',false); console.write(KEY_ESC+'['+cf.attribute.i+';'+cf.attribute.f+';'+cf.attribute.b+'m'); read = ''; } } - log(LOG_DEBUG,'Field Value '+cf.fvalue+'('+JSON.stringify(code)+')'); + log(LOG_DEBUG,'- Field Value ['+cf.fvalue+'] ('+code+')'); return read; } // Called before processing for a field this.prefield=function() { - log(LOG_DEBUG,'Field '+cf.fname+'('+JSON.stringify(cf)+')'); + log(LOG_DEBUG,'- Field '+cf.fname+'('+JSON.stringify(cf)+')'); if (cf.fname == 'TOKEN') { - log(LOG_DEBUG,'BASELINE '+cf.fname+'('+JSON.stringify(cf)+')'); - sendBaseline('\1n\1h\1RPlease wait, while a token is emailed to you...',false); + if (! code.length) { + log(LOG_DEBUG,'- BASELINE '+cf.fname+'('+JSON.stringify(cf)+')'); + sendBaseline('\1n\1h\1RPlease wait, while a token is emailed to you...',false); - var email = fo.fieldValue('EMAIL'); - var user = fo.fieldValue('UID'); - var name = fo.fieldValue('FULLNAME'); + var email = fo.fieldValue('EMAIL'); + var user = fo.fieldValue('UID'); + var name = fo.fieldValue('FULLNAME'); - log(LOG_DEBUG,'VALIDATE EMAIL TO ('+system.matchuserdata(U_NETMAIL,email)+')'); - // Make sure we got an email - // Validate Email hasnt been used - if ((email.indexOf('@') === -1) || ! EMAIL_REGEX.test(email) || (system.matchuserdata(U_NETMAIL,email) !== 0)) { - sendBaseline('\1n\1h\1RINVAID EMAIL, PLEASE TRY AGAIN *00',false); - return; - } + log(LOG_DEBUG,'- VALIDATE EMAIL TO ('+system.matchuserdata(U_NETMAIL,email)+')'); + // Make sure we got an email + // Validate Email hasnt been used + if ((email.indexOf('@') === -1) || ! EMAIL_REGEX.test(email) || (system.matchuserdata(U_NETMAIL,email) !== 0)) { + sendBaseline('\1n\1h\1RINVAID EMAIL, PLEASE TRY AGAIN *00',false); + return; + } - // Validate USER_ID hasnt been used - if (! system.check_name(user)) { - log(LOG_DEBUG,'Cannot use user_id: ('+user+')'); - sendBaseline('\1n\1h\1RINVAID USER ID, PLEASE TRY AGAIN *00',false); - } + // Validate USER_ID hasnt been used + if (! system.check_name(user)) { + log(LOG_DEBUG,'Cannot use user_id: ('+user+')'); + sendBaseline('\1n\1h\1RINVAID USER ID, PLEASE TRY AGAIN *00',false); + return; + } - var msgbase = new MsgBase('mail'); - for (var i=0;i<6;i++) - code+=cValChars.substr(parseInt(Math.random() * cValChars.length), 1); + var msgbase = new MsgBase('mail'); + for (var i=0;i<6;i++) + code+=cValChars.substr(parseInt(Math.random() * cValChars.length), 1); - var hdrs = new Object(); - hdrs.to=name; - hdrs.to_net_type=netaddr_type(email); - if (hdrs.to_net_type != NET_NONE) { - hdrs.to_net_addr = email; - } else { - sendBaseline('\1n\1h\1RCANNOT SEND VALIDATION CODE, PLEASE TRY AGAIN *00',false); - return; - } - hdrs.from=system.name; - hdrs.from_net_addr='sysop@'+system.inet_addr; - hdrs.from_net_type=NET_INTERNET; - hdrs.subject='Registration TOKEN for '+system.name; + var hdrs = new Object(); + hdrs.to=name; + hdrs.to_net_type=netaddr_type(email); + if (hdrs.to_net_type != NET_NONE) { + hdrs.to_net_addr = email; + } else { + sendBaseline('\1n\1h\1RCANNOT SEND VALIDATION CODE, PLEASE TRY AGAIN *00',false); + return; + } + hdrs.from=system.name; + hdrs.from_net_addr='sysop@'+system.inet_addr; + hdrs.from_net_type=NET_INTERNET; + hdrs.subject='Registration TOKEN for '+system.name; - if (msgbase.open != undefined && msgbase.open() == false) { - console.print("\r\n\1n\1h\1rERROR: \1y" + msgbase.last_error + "\1n \r\n"); - console.pause(); + if (msgbase.open != undefined && msgbase.open() == false) { + console.print("\r\n\1n\1h\1rERROR: \1y" + msgbase.last_error + "\1n \r\n"); + console.pause(); + msgbase.close(); + bbs.hangup(); + return; + } + + var msg="CODE: " + code + "\n\n"; + msg += 'Please use the above code to validate your login to '+system.name+'.'; + + if (! msgbase.save_msg(hdrs,msg)) { + console.print("\r\n\1n\1h\1rERROR: \1y" + msgbase.last_error + "\1n \r\n"); + console.pause(); + msgbase.close(); + bbs.hangup(); + return; + } msgbase.close(); - bbs.hangup(); - return; } - var msg="CODE: " + code + "\n\n"; - msg += 'Please use the above code to validate your login to '+system.name+'.'; - - if (! msgbase.save_msg(hdrs,msg)) { - console.print("\r\n\1n\1h\1rERROR: \1y" + msgbase.last_error + "\1n \r\n"); - console.pause(); - msgbase.close(); - bbs.hangup(); - return; - } - msgbase.close(); - - log(LOG_DEBUG,'SEND EMAIL TO ('+x+')'); + sendBaseline('\1n\1h\1RTOKEN SENT, PLEASE ENTER TOKEN',false); + log(LOG_DEBUG,'SENT EMAIL TOKEN ('+code+') ['+JSON.stringify(hdrs)+']'); } } + + this.process=function() { + log(LOG_DEBUG,'Creating user: '+fo.fieldValue('EMAIL')); + + try { + var newuser = system.new_user(fo.fieldValue('UID')); + + } catch (e) { + sendBaseline('\1n\1h\1RERROR USER EXISTS, PLEASE TRY AGAIN *00',false); + log(LOG_ERROR,"New user couldn't be created (user created while signing up)"); + log(LOG_ERROR,JSON.stringify(e)); + return; + } + + if (typeof newuser === 'number') { + sendBaseline('\1n\1h\1RERROR CREATING USER, PLEASE TRY AGAIN *00',false); + log(LOG_ERROR,"New user couldn't be created (error code "+newuser+")"); + return; + } + + newuser.security.password = ''; + if (bbs.login(newuser.alias,null)) { + user.number = newuser.number; + user.security.password = fo.fieldValue('PASS'); + user.name = fo.fieldValue('FULLNAME'); + user.handle = fo.fieldValue('UID'); + user.location = fo.fieldValue('CITY')+', '+fo.fieldValue('COUNTRY'); + user.zipcode = fo.fieldValue('PCODE'); + user.netmail = fo.fieldValue('EMAIL'); + bbs.user_sync(); + bbs.logon(); + log(LOG_INFO,"Created user record #"+user.number+": "+user.alias); + + action = ACTION_EXIT; + return; + + } else { + sendBaseline('\1n\1h\1RERROR LOGGING IN, PLEASE TRY AGAIN *00',false); + log(LOG_INFO,"bbs.login() failed"); + user.comment = 'Initial login failed!'; + newuser.settings |= USER_DELETED; + delete newuser; + return; + } + + return 'processed'; + } + + Object.defineProperty(this,'getName', { + get: function() { + return 'Control-Registration'; + } + }); + + Object.defineProperty(this,'isComplete', { + get: function() { + return complete; + } + }); } this; \ No newline at end of file diff --git a/main.js b/main.js index b8490ba..8912527 100644 --- a/main.js +++ b/main.js @@ -26,7 +26,7 @@ while(bbs.online) { var next_page = user.number ? { frame: 98,index: 'b' } : { frame: 980,index: 'a' }; // Start Frame var action = ACTION_GOTO; // Initial action - var inkey_timeout = 10000; // Timeout waiting for input @todo required? check if idle timeout occurs + var inkey_timeout = 60000; // Timeout waiting for input var fo = null; // Current Frame var fn = null; // Current Field Number for an Input Frame var history = []; // Page history @@ -34,6 +34,7 @@ while(bbs.online) { var cf = null; // Current Input Field var cc = null; // Current Control Method + var timeout = 0; // Track our inactivity timeout var control = []; // Methods that need to process input ansi.send('ext_mode','clear','cursor'); @@ -47,19 +48,46 @@ while(bbs.online) { read = console.inkey(K_NONE,inkey_timeout); } log(LOG_DEBUG,'READ: ['+read+'] ('+read.charCodeAt(0)+')'); - inkey_timeout = 60000; // Set our key timeout to 60s + + if (read == '' && ! (user.security.exemptions&UFLAG_H) ) { + if (timeout++ > 1) { + sendBaseline(INACTIVE,false); + bbs.hangup(); + + } else { + sendBaseline(INACTIVITY,false); + if (cf) + console.write(KEY_ESC+'['+cf.attribute.i+';'+cf.attribute.f+';'+cf.attribute.b+'m'); + } + + } else { + if (timeout) { + sendBaseline('',false); + + if (cf) + console.write(KEY_ESC+'['+cf.attribute.i+';'+cf.attribute.f+';'+cf.attribute.b+'m'); + } + + timeout = 0; + } system.node_list[bbs.node_num-1].action=0xff; // to ensure our node status is updated correctly if (mode != MODE_BL && control.length) { cc = control[control.length-1]; - log(LOG_DEBUG,'CONTROL START: ['+read+'] ('+cc+')'); + log(LOG_DEBUG,'CONTROL START: ['+read+'] ('+cc.getName+')'); read = cc.handle(read); + log(LOG_DEBUG,'CONTROL RETURN: ['+read+'] ('+cc.isComplete+')'); + + if (cc.isComplete) { + control = control.pop(); + log(LOG_DEBUG,'CONTROL COMPLETE: ['+read+'] ('+control.length+')'); + } log(LOG_DEBUG,'CONTROL END: ['+read+']'); } - log(LOG_DEBUG,'MODE START: ['+read+']'); + log(LOG_DEBUG,'MODE START: ['+read.charCodeAt(0)+']'); switch (mode) { case false: log(LOG_DEBUG,'- false: ['+read+']'); @@ -259,7 +287,7 @@ while(bbs.online) { // End of field entry. case '#': case '\r': - log(LOG_DEBUG,'- MODE_FIELD:FRAME_TYPE_RESPONSE: ['+read+']'); + log(LOG_DEBUG,'- MODE_FIELD:FRAME_TYPE_RESPONSE: # ['+read+']'); // Next Field fn++; @@ -292,7 +320,7 @@ while(bbs.online) { // Delete Key pressed case CTRL_H: - log(LOG_DEBUG,'- MODE_FIELD:FRAME_TYPE_RESPONSE: ['+read+']'+' cf:'+(cf ? cf.fvalue.length : '{}')+' ct:'+cf.ftype); + log(LOG_DEBUG,'- MODE_FIELD:FRAME_TYPE_RESPONSE: DEL ['+read+']'+' cf:'+(cf ? cf.fvalue.length : '{}')+' ct:'+cf.ftype); if (cf.fvalue.length > 0) { cf.fvalue = cf.fvalue.substring(0,cf.fvalue.length-1); @@ -302,7 +330,52 @@ while(bbs.online) { break; case KEY_ESC: - log(LOG_DEBUG,'- MODE_FIELD:FRAME_TYPE_RESPONSE: ['+read+'] D'); + log(LOG_DEBUG,'- MODE_FIELD:FRAME_TYPE_RESPONSE: ESC ['+read+']'); + break; + + case KEY_DOWN: + log(LOG_DEBUG,'- MODE_FIELD:FRAME_TYPE_RESPONSE: DOWN ['+read+']'); + // Next Field + fn++; + + cf = fo.frame_fields[fn]; + log(LOG_DEBUG,'fn:'+fn+', cf'+JSON.stringify(cf)); + + if (! cf) { + fn = 0; + cf = fo.frame_fields[fn]; + } + + // If there is a control for this field, + if (cc) + cc.prefield(); + + mode = MODE_FIELD; + console.gotoxy(cf.c+cf.fvalue.length,cf.r); + console.write(KEY_ESC+'['+cf.attribute.i+';'+cf.attribute.f+';'+cf.attribute.b+'m'); + + break; + + case KEY_UP: + log(LOG_DEBUG,'- MODE_FIELD:FRAME_TYPE_RESPONSE: UP ['+read+']'); + // Next Field + fn--; + + if (fn < 0) { + fn = fo.frame_fields.length-1; + } + + cf = fo.frame_fields[fn]; + log(LOG_DEBUG,'fn:'+fn+', cf'+JSON.stringify(cf)); + + // If there is a control for this field, + if (cc) + cc.prefield(); + + mode = MODE_FIELD; + console.gotoxy(cf.c+cf.fvalue.length,cf.r); + console.write(KEY_ESC+'['+cf.attribute.i+';'+cf.attribute.f+';'+cf.attribute.b+'m'); + break; // Record Data Entry @@ -363,6 +436,12 @@ while(bbs.online) { log(LOG_DEBUG,' ! Login failed for User:'+JSON.stringify(fo.frame_fields[0].fvalue)); break; + + default: + // Its assumed that you get here after completing a form and you have pressed 1 to submit that form. + log(LOG_DEBUG,' ! EVAL method:'+JSON.stringify(fo.key)); + x = cc.process(); + log(LOG_DEBUG,' = EVAL method:'+JSON.stringify(x)); } /* @@ -421,6 +500,9 @@ while(bbs.online) { break; } + // Destroy the object. + cc = null; + break; // Response form after Sent processing @@ -651,18 +733,6 @@ while(bbs.online) { case FRAME_TYPE_LOGIN: action = false; - /* - // If this is the registration page - // @todo Should be evaluated out of the DB - if ($this->fo->page() == '981a') { - $control = CONTROL_METHOD; - $method->push(Control::factory('register',$this)); - $method->last()->state['control'] = $control; - $method->last()->state['action'] = FALSE; - $method->last()->state['mode'] = MODE_FIELD; - } - */ - case FRAME_TYPE_RESPONSE: //log(LOG_DEBUG,'FRAME_TYPE_RESPONSE :'+fo.page+', FIELDS: '+fo.frame_fields.count); fn = 0; @@ -693,8 +763,8 @@ while(bbs.online) { // @todo this needs to be configurable if (fo.page == '981a') { log(LOG_DEBUG,'Adding REGISTER to control stack'); - require('ansitex/load/register.js','CONTROL_REGISTER'); - control.push(new register()); + require('ansitex/load/'+fo.key[1]+'.js','CONTROL_REGISTER'); + control.push(eval("new "+fo.key[1]+'();')); } break; diff --git a/save.js b/save.js index 9b31df0..7b12184 100644 --- a/save.js +++ b/save.js @@ -63,10 +63,10 @@ if (! send || ! frame || file) { // Public if (argv.indexOf('-P') >= 0) - frame.isPublic = 1; + frame.isPublic = true; if (argv.indexOf('-A') >= 0) - frame.isAccessible = 1; + frame.isAccessible = true; if (cost) frame.cost = cost; diff --git a/text/11a.tex b/text/11a.tex index e15427b..5f38828 100644 --- a/text/11a.tex +++ b/text/11a.tex @@ -1 +1 @@ -{"version":1,"frame":11,"index":"a","owner":"AWgBUkEBR04BQlMBWUkBbgE3AWt0ZXgBbg==","cost":0,"content":"G1swbRtbMW3fG1swbdsbWzE7MzBt3xtbMG3fG1sxbdsbWzBtICDfICAgIBtbMTszMG3fG1swbdsgICAgICAgIBtbMW3bG1swbdwgIBtbMW3bG1swbSAgICAgICAg2yAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAbWzFtXxtbMG0NChtbMW0gG1swbdsbWzE7MzBt3BtbMG3cICAbWzFt3xtbMG3bICAg3BtbMTszMG3cG1swbdsgIBtbMW3cG1swbd8bWzE7MzBt3xtbMG3fG1sxbdwbWzBtIBtbMW3bG1swbSAbWzE7MzBt3xtbMG3cG1sxbdsbWzBtIBtbMW3cG1swbd8bWzE7MzBt3xtbMG3fG1sxbdwbWzBtIBtbMW3fG1swbdsbWzE7MzBt3xtbMG3fICAgICAgICAgICAgICAgICAgICAgICAgICAgIBtbMW0vICBcG1swbQ0KG1sxbSAbWzBt2xtbMTszMG0gICAgIBtbMG3bICAbWzFt2xtbMG0gINsgIBtbMW3bG1swbSAgIBtbMW3bG1swbSAbWzFt2xtbMG0gICAbWzFt2xtbMG0gG1sxbdsbWzBt3xtbMTszMG3fG1swbd8bWzFt3xtbMG0gINsbWzE7MzBtIBtbMG3cIBtbMW13b3JrcxtbMG0uICAgICAgICAgICAgICAgICAgICAbWzFtL3xvbyBcG1swbQ0KG1sxbd8bWzBt3xtbMTszMG3fG1swbSAgIBtbMW3fG1swbd8bWzE7MzBt3xtbMG0gIN8bWzE7MzBt3xtbMG0gG1sxbd8bWzBtICDfG1sxOzMwbd8bWzBt3yAgG1sxbd8bWzBtICAgG1sxbd8bWzBtICDfG1sxOzMwbd8bWzBt3yAgICAbWzE7MzBt3xtbMG0gICAgICAgICAgICAgICAgICAgICAgICAgICAbWzFtKF98ICAvXykbWzBtDQobWzMxbUZUTjogG1sxbUZpZG8gVGVjaG5vbG9neSBOZXR3b3JrcxtbMG0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAbWzMxbV8bWzE7MzdtYEAvG1swOzMxbV8bWzM3bSAbWzFtXCAgICBfG1swbQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIBtbMzFtfCAgICAgfBtbMzdtIBtbMW1cICAgXFwbWzBtDQogG1szMm0xG1sxbSAbWzM3bVByaXZhdGVOZXQgKEludGVybmFsIFRlc3QgTmV0d29yaykbWzBtIBtbMzJtKjMwMDEwIxtbMzdtICAgICAgICAgICAgICAgICAgIBtbMzFtfCAbWzE7MzBtKCopG1swbSAbWzMxbXwbWzM3bSAgG1sxbVwbWzBtICAgG1sxbSkpG1swbQ0KIBtbMTszMm0yIBtbMzdtZnN4TmV0IChGdW4gU2ltcGxlIEV4cGVyaW1lbnRhbCBOZXR3b3JrKRtbMG0gG1sxOzMybSozMDAyMSMbWzBtICAgIBtbMTszMG1fX19fX18gICAbWzA7MzFtfF9fG1sxOzMwbVUbWzA7MzFtX198G1szN20gG1sxbS8gIFwvLxtbMG0NCiAbWzMybTMbWzE7MzdtIERPVkVuZXQbWzMybSAbWzA7MzJtKjMwNzIzIxtbMzdtICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgG1sxOzMwbS8gG1swbUZJRE8gG1sxOzMwbVwbWzBtICAgG1sxbV8vL3x8IF9cICAgLxtbMG0NCiAbWzMybTQbWzFtIBtbMzdtdHF3TmV0IChUaGUgUXVhbnRvbSBXb3Jtd2hvbGUpG1swbSAbWzMybSozMTMzNyMbWzM3bSAgICAgICAgICAgIBtbMTszMG0oX19fX19fX18pG1swbSAbWzFtKF8vKF98KF9fX18vG1swbQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChqbSkNCiAbWzE7MzBtT3RoZXIgbmV0d29ya3Mgd2lsbCBiZSBhZGRlZCBpbiB0aW1lLi4uG1swbQ0K","isPublic":true,"isAccessible":true,"key":[1,30010,30021,30723,31337,null,null,null,null,null],"date":"2019-10-17T05:22:13.225Z","type":"i"} +{"version":1,"frame":11,"index":"a","owner":"AWgBUkEBR04BQlMBWUkBbgE3AWt0ZXgBbg==","cost":0,"content":"G1swbRtbMW3fG1swbdsbWzE7MzBt3xtbMG3fG1sxbdsbWzBtICDfICAgIBtbMTszMG3fG1swbdsgICAgICAgIBtbMW3bG1swbdwgIBtbMW3bG1swbSAgICAgICAg2yAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAbWzFtXxtbMG0NChtbMW0gG1swbdsbWzE7MzBt3BtbMG3cICAbWzFt3xtbMG3bICAg3BtbMTszMG3cG1swbdsgIBtbMW3cG1swbd8bWzE7MzBt3xtbMG3fG1sxbdwbWzBtIBtbMW3bG1swbSAbWzE7MzBt3xtbMG3cG1sxbdsbWzBtIBtbMW3cG1swbd8bWzE7MzBt3xtbMG3fG1sxbdwbWzBtIBtbMW3fG1swbdsbWzE7MzBt3xtbMG3fICAgICAgICAgICAgICAgICAgICAgICAgICAgIBtbMW0vICBcG1swbQ0KG1sxbSAbWzBt2xtbMTszMG0gICAgIBtbMG3bICAbWzFt2xtbMG0gINsgIBtbMW3bG1swbSAgIBtbMW3bG1swbSAbWzFt2xtbMG0gICAbWzFt2xtbMG0gG1sxbdsbWzBt3xtbMTszMG3fG1swbd8bWzFt3xtbMG0gINsbWzE7MzBtIBtbMG3cIBtbMW13b3JrcxtbMG0uICAgICAgICAgICAgICAgICAgICAbWzFtL3xvbyBcG1swbQ0KG1sxbd8bWzBt3xtbMTszMG3fG1swbSAgIBtbMW3fG1swbd8bWzE7MzBt3xtbMG0gIN8bWzE7MzBt3xtbMG0gG1sxbd8bWzBtICDfG1sxOzMwbd8bWzBt3yAgG1sxbd8bWzBtICAgG1sxbd8bWzBtICDfG1sxOzMwbd8bWzBt3yAgICAbWzE7MzBt3xtbMG0gICAgICAgICAgICAgICAgICAgICAgICAgICAbWzFtKF98ICAvXykbWzBtDQobWzMxbUZUTjogG1sxbUZpZG8gVGVjaG5vbG9neSBOZXR3b3JrcxtbMG0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAbWzMxbV8bWzE7MzdtYEAvG1swOzMxbV8bWzM3bSAbWzFtXCAgICBfG1swbQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIBtbMzFtfCAgICAgfBtbMzdtIBtbMW1cICAgXFwbWzBtDQogG1szMm0xG1sxbSAbWzM3bVByaXZhdGVOZXQgKEludGVybmFsIFRlc3QgTmV0d29yaykbWzBtIBtbMzJtKjEwMDEwIxtbMzdtICAgICAgICAgICAgICAgICAgIBtbMzFtfCAbWzE7MzBtKCopG1swbSAbWzMxbXwbWzM3bSAgG1sxbVwbWzBtICAgG1sxbSkpG1swbQ0KIBtbMTszMm0yIBtbMzdtZnN4TmV0IChGdW4gU2ltcGxlIEV4cGVyaW1lbnRhbCBOZXR3b3JrKRtbMG0gG1sxOzMybSoxMDAyMSMbWzBtICAgIBtbMTszMG1fX19fX18gICAbWzA7MzFtfF9fG1sxOzMwbVUbWzA7MzFtX198G1szN20gG1sxbS8gIFwvLxtbMG0NCiAbWzMybTMbWzE7MzdtIERPVkVuZXQbWzMybSAbWzA7MzJtKjEwNzIzIxtbMzdtICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgG1sxOzMwbS8gG1swbUZJRE8gG1sxOzMwbVwbWzBtICAgG1sxbV8vL3x8IF9cICAgLxtbMG0NCiAbWzMybTQbWzFtIBtbMzdtdHF3TmV0IChUaGUgUXVhbnRvbSBXb3Jtd2hvbGUpG1swbSAbWzMybSoxMTMzNyMbWzM3bSAgICAgICAgICAgIBtbMTszMG0oX19fX19fX18pG1swbSAbWzFtKF8vKF98KF9fX18vG1swbQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChqbSkNCiAbWzE7MzBtT3RoZXIgbmV0d29ya3Mgd2lsbCBiZSBhZGRlZCBpbiB0aW1lLi4uG1swbQ0K","isPublic":false,"isAccessible":true,"type":"i","key":[1,10010,10021,10723,11337,null,null,null,null,null],"frame_fields":[],"date":"2020-07-08T05:24:57.759Z"} diff --git a/text/981a.tex b/text/981a.tex index ec003c6..b2196ef 100644 --- a/text/981a.tex +++ b/text/981a.tex @@ -1 +1 @@ -{"version":1,"frame":"981","index":"a","owner":"AWgBUkEBR04BQlMBWUkBbgE3AWt0ZXgBbg==","cost":0,"content":"G1swbRtbMTszMG3ExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMQbWzBtDQogG1sxOzMxbdzcxNwbWzM3bSAbWzMybdzcxNwbWzM3bSAbWzM0bdzcxNwbWzM3bSAbWzMzbdzcG1swbSAbWzMwOzQ3bSDc3CAgINzcxNwg3Nwg3CAbWzM3OzQwbSAgICAgICAgIBtbMW0uG1szNm0gICAgICAgICAgG1szN20uG1swbQ0KIBtbMTszMW3c3MSxG1szN20gG1szMm2ysRtbMzdtIBtbMzJtsRtbMzdtIBtbMzRt39/E3BtbMzdtIBtbMzNt3NwbWzBtIBtbMzA7NDdtILKxxCAgsrHE3yDf38LfIBtbMzc7NDBtICAgG1sxbcK/wr/Cv7/av8Mtwr/Cv8Mtv9q/2r8NChtbMG0gG1sxOzMxbbGwG1swbSAbWzE7MzFtsBtbMG0gG1sxOzMybbGwG1swbSAbWzE7MzJtsBtbMG0gG1sxOzM0bbGwG1swbSAbWzE7MzRtsBtbMG0gG1sxOzMzbbGwG1swbSAbWzMwOzQ3bSCxsCCwILGwILAgsbAgsCAbWzM3OzQwbSAgILMgw9mzs7PAv7MgsyDCtLMgs7Ozs7MNCiAbWzE7MzFt39/E3xtbMG0gG1sxOzMybd/fG1swbSAbWzE7MzJt3xtbMG0gG1sxOzM0bd/fxN8bWzBtIBtbMTszM23f3xtbMG0gG1szMDs0N20g39/E3yDf38TfIN/fIN8gG1szNzs0MG0gICAbWzE7MzBt2RtbMzZtIBtbMzBtwdnBtNnA2cDZ2RtbMzZtIBtbMzBtwcHA2dnA2dnZG1swbQ0KG1sxOzMwbcTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExBtbMG0gICAgICAbWzE7MzBtxNkbWzM3bQ0KG1swbQ0KG1sxbSBQbGVhc2UgY29tcGxldGUgdGhlIHVzZXIgcmVnaXN0cmF0aW9uOhtbMG0NCg0KICAgICAgG1sxOzMxbUVtYWlsOhtbMG0gG1sxbRtfRU1BSUw7NjB0O/kbXBtbMG0NCiAgICAbWzE7MzFtVXNlciBJRDobWzBtIBtbMW0bX1VJRDsyNXQ7+RtcG1swbQ0KICAgG1sxOzMxbVBhc3N3b3JkOhtbMG0gG1sxbRtfUEFTUzs0MHA7+RtcG1swbQ0KICAbWzE7MzFtRnVsbCBOYW1lOhtbMG0gG1sxbRtfRlVMTE5BTUU7MjV0O/kbXBtbMG0NCiAgICAgICAbWzE7MzFtQ2l0eTobWzBtIBtbMW0bX0NJVFk7MjV0O/kbXBtbMG0NCiAgICAbWzE7MzFtQ291bnRyeTobWzBtIBtbMW0bX0NOVFJZOzN0O/kbXBtbMG0NChtbMTszMW1Qb3N0YWwgQ29kZTobWzBtIBtbMW0bX1BDT0RFOzEwdDv5G1wbWzBtDQogICAgICAbWzE7MzFtVG9rZW46G1swbSAbWzFtG19UT0tFTjs2dDv5G1wbWzBtDQoNCiAbWzFtUmVnaXN0ZXJpbmcgYW5kIHVzaW5nIHRoaXMgc3lzdGVtLCB5b3UgYWdyZWUgdG8gYWJpZGUgYnkgdGhlIHN5c3RlbSBydWxlcy4bWzBtDQogG1sxbVlvdSBjYW4gdmlldyB0aG9zZSBydWxlcyBvbiBwYWdlIBtbMzJtKjk4OCMbWzM3bS4bWzBtDQo=","isPublic":true,"isAccessible":true,"type":"r","key":[980,"register",null,null,null,null,null,null,null,null],"frame_fields":[],"date":"2020-07-06T11:09:47.037Z"} +{"version":1,"frame":"981","index":"a","owner":"AWgBUkEBR04BQlMBWUkBbgE3AWt0ZXgBbg==","cost":0,"content":"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","isPublic":true,"isAccessible":true,"type":"r","key":[980,"register",null,null,null,null,null,null,null,null],"frame_fields":[],"date":"2020-07-09T11:42:40.643Z"} \ No newline at end of file diff --git a/text/98a.tex b/text/98a.tex index 7e343e8..9ca2730 100644 --- a/text/98a.tex +++ b/text/98a.tex @@ -1 +1 @@ -{"version":1,"frame":98,"index":"a","owner":"AWgBUkEBR04BQlMBWUkBbgE3AWt0ZXgBbg==","cost":0,"content":"G1swbRtbNjlDG1sxOzMybTAwMDEwMDAxMDEbWzBtDQobWzU1QxtbMW1AREFURVRJTUVAG1swbQ0KG1syMkMbWzFt2iC/wr+z2r/av9rCv8K/G1swbSAbWzFtwy3avxtbMG0NChtbMjJDs7Ozw9mzsyCzs7Mgs8PZG1szMG3bG1szN22zILOzDQobWzIyQxtbMTszMG3AwdnB2cDA2cDZwCDZwdkbWzBtIBtbMTszMG3A2cDZG1swbSAbWzE7MzBt+vr6G1swbQ0KG1syMkMbWzE7MzBtxMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEG1swbQ0KG1syM0MbWzE7MzFt3NzE3BtbMzdtIBtbMzJt3NzE3BtbMzdtIBtbMzRt3NzE3BtbMzdtIBtbMzNt3NwbWzBtIBtbMzA7NDdtINzcICAg3NzE3CDc3CDcIBtbMzc7NDBtDQobWzIzQxtbMTszMW3c3MSxG1szN20gG1szMm2ysRtbMzdtIBtbMzJtsRtbMzdtIBtbMzRt39/E3BtbMzdtIBtbMzNt3NwbWzBtIBtbMzA7NDdtILKxxCAgsrHE3yDf38LfIBtbMzc7NDBtDQobWzIzQxtbMTszMW2xsBtbMG0gG1sxOzMxbbAbWzBtIBtbMTszMm2xsBtbMG0gG1sxOzMybbAbWzBtIBtbMTszNG2xsBtbMG0gG1sxOzM0bbAbWzBtIBtbMTszM22xsBtbMG0gG1szMDs0N20gsbAgsCCxsCCwILGwILAgG1szNzs0MG0NChtbMjNDG1sxOzMxbd/fxN8bWzBtIBtbMTszMm3f3xtbMG0gG1sxOzMybd8bWzBtIBtbMTszNG3f38TfG1swbSAbWzE7MzNt398bWzBtIBtbMzA7NDdtIN/fxN8g39/E3yDf3yDfIBtbMzc7NDBtDQobWzIyQxtbMTszMG3ExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMQbWzBtDQobWzRDG1sxbS4gICAgIC4gICDaG1swbSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIBtbMW2/G1swbQ0KG1syQxtbMW3av7/Cv9q/IL/avxtbMG0gG1sxOzMwbbMbWzBtIBtbMTszMW1VU0VSOhtbMG0gG1sxbRtfVVNFUjsyNXQ7+RtcG1swbSAgICAgICAgICAgICAgICAbWzE7MzBtsxtbMG0NChtbMkPAv7Ozs7OzILOzsyAbWzE7MzBtwxtbMG0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAbWzE7MzBttBtbMG0NChtbMkMbWzE7MzBtwNnZwbTZ2RtbMzdtIBtbMzBt2dnZG1szN20gG1szMG2zG1swbSAbWzE7MzFtUEFTUzobWzBtIBtbMW0bX1BBU1M7NDBwO/kbXBtbMG0gG1sxOzMwbbMbWzBtDQobWzVDG1sxOzMwbcTZG1swbSAgICAgICAbWzFtwBtbMG0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAbWzFt2RtbMG0NCg0KDQoNCg0KG1sxM0MbWzE7MzBtVG8gcmVnaXN0ZXIgYW4gYWNjb3VudCBlbnRlchtbMG0gG1sxbU5FVxtbMG0gG1sxOzMwbWZvciB0aGUgdXNlciBuYW1lG1swbQ0KG1sxNkMbWzE7MzBtVXNlG1swbSAbWzE7MzJtKiobWzBtIBtbMTszMG10byBjbGVhciB5b3VyIGlucHV0G1swbSAbWzE7MzJtKjAwG1swbSAbWzE7MzBtdG8gc3RhcnQgYWdhaW4bWzBtDQo=","isPublic":true,"isAccessible":true,"type":"l","key":[null,"login",null,null,null,null,null,null,null,null],"frame_fields":[],"date":"2020-07-06T13:38:58.689Z"} \ No newline at end of file +{"version":1,"frame":98,"index":"a","owner":"AWgBUkEBR04BQlMBWUkBbgE3AWt0ZXgBbg==","cost":0,"content":"G1swbRtbNjlDG1sxOzMybTAwMDEwMDAxMDEbWzBtDQobWzU1QxtbMW1AREFURVRJTUVAG1swbQ0KG1syMkMbWzFt2iC/wr+z2r/av9rCv8K/G1swbSAbWzFtwy3avxtbMG0NChtbMjJDs7Ozw9mzsyCzs7Mgs8PZG1szMG3bG1szN22zILOzDQobWzIyQxtbMTszMG3AwdnB2cDA2cDZwCDZwdkbWzBtIBtbMTszMG3A2cDZG1swbSAbWzE7MzBt+vr6G1swbQ0KG1syMkMbWzE7MzBtxMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEG1swbQ0KG1syM0MbWzE7MzFt3NzE3BtbMzdtIBtbMzJt3NzE3BtbMzdtIBtbMzRt3NzE3BtbMzdtIBtbMzNt3NwbWzBtIBtbMzA7NDdtINzcICAg3NzE3CDc3CDcIBtbMzc7NDBtDQobWzIzQxtbMTszMW3c3MSxG1szN20gG1szMm2ysRtbMzdtIBtbMzJtsRtbMzdtIBtbMzRt39/E3BtbMzdtIBtbMzNt3NwbWzBtIBtbMzA7NDdtILKxxCAgsrHE3yDf38LfIBtbMzc7NDBtDQobWzIzQxtbMTszMW2xsBtbMG0gG1sxOzMxbbAbWzBtIBtbMTszMm2xsBtbMG0gG1sxOzMybbAbWzBtIBtbMTszNG2xsBtbMG0gG1sxOzM0bbAbWzBtIBtbMTszM22xsBtbMG0gG1szMDs0N20gsbAgsCCxsCCwILGwILAgG1szNzs0MG0NChtbMjNDG1sxOzMxbd/fxN8bWzBtIBtbMTszMm3f3xtbMG0gG1sxOzMybd8bWzBtIBtbMTszNG3f38TfG1swbSAbWzE7MzNt398bWzBtIBtbMzA7NDdtIN/fxN8g39/E3yDf3yDfIBtbMzc7NDBtDQobWzIyQxtbMTszMG3ExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMQbWzBtDQobWzRDG1sxbS4gICAgIC4gICAbWzMwbbMbWzBtICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgG1sxOzMwbbMbWzBtDQobWzJDG1sxbdq/v8K/2r8gv9q/G1swbSAbWzE7MzBtsxtbMG0gG1sxOzMxbVVTRVI6G1swbSAbWzFtG19VU0VSOzI1dDv5G1wbWzBtICAgICAgICAgICAgICAgIBtbMTszMG2zG1swbQ0KG1syQ8C/s7Ozs7Mgs7OzIBtbMTszMG2zG1swbSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIBtbMTszMG2zG1swbQ0KG1syQxtbMTszMG3A2dnBtNnZG1szN20gG1szMG3Z2dkbWzM3bSAbWzMwbbMbWzBtIBtbMTszMW1QQVNTOhtbMG0gG1sxbRtfUEFTUzs0MHA7+RtcG1swbSAbWzE7MzBtsxtbMG0NChtbNUMbWzE7MzBtxNkbWzBtICAgICAgIBtbMTszMG2zG1swbSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIBtbMTszMG2zG1swbQ0KDQoNCg0KDQobWzEzQxtbMTszMG1UbyByZWdpc3RlciBhbiBhY2NvdW50IGVudGVyG1swbSAbWzFtTkVXG1swbSAbWzE7MzBtZm9yIHRoZSB1c2VyIG5hbWUbWzBtDQobWzE2QxtbMTszMG1Vc2UbWzBtIBtbMTszMm0qKhtbMG0gG1sxOzMwbXRvIGNsZWFyIHlvdXIgaW5wdXQbWzBtIBtbMTszMm0qMDAbWzBtIBtbMTszMG10byBzdGFydCBhZ2FpbhtbMG0NCg==","isPublic":true,"isAccessible":true,"type":"l","key":[null,"login",null,null,null,null,null,null,null,null],"frame_fields":[],"date":"2020-07-08T05:17:35.174Z"} \ No newline at end of file