Built motion from commit (unavailable).|2.5.4
[motion2.git] / server / services / ami / report / userReport.js
index 081c1eb..a3e57fb 100644 (file)
@@ -15,4 +15,4 @@
 // * treaties. The SOFTWARE PRODUCT is licensed, not sold.                        *
 // *                                                                       *
 // *************************************************************************
-var _0xc624=['localhost','socket.io-emitter','trunks','agents','telephones','syncRegistry','bind','registry','devicestatechange','syncDeviceState','peerstatus','loopSyncRealTimeShow','actionSipShowRegistry','then','actionDeviceStateList','actionSipPeerStatus','catch','[loopSyncRealTimeShow]','inspect','prototype','isNotNull','emit','find','state','merge','omit','actionid','username','format','trunk:%s','name','[syncRegistry][UserReport]','device','toLowerCase','local','stateTime','toNumber','updateStatusRealtime','telephone:%s','trunk:save','startsWith','Queue','Local','substring','indexOf','mobile','phone','[syncDeviceState][UserReport]','syncPeerStatus','peer','status','address','error','moment','util','ioredis','../../../config/environment','../../../config/logger','ami','defaults','redis'];(function(_0x4b32fb,_0x44fbbf){var _0x4d9753=function(_0x445063){while(--_0x445063){_0x4b32fb['push'](_0x4b32fb['shift']());}};_0x4d9753(++_0x44fbbf);}(_0xc624,0xec));var _0x4c62=function(_0x281d4e,_0x37647e){_0x281d4e=_0x281d4e-0x0;var _0x5b6888=_0xc624[_0x281d4e];return _0x5b6888;};'use strict';var _=require('lodash');var moment=require(_0x4c62('0x0'));var BPromise=require('bluebird');var util=require(_0x4c62('0x1'));var Redis=require(_0x4c62('0x2'));var config=require(_0x4c62('0x3'));var logger=require(_0x4c62('0x4'))(_0x4c62('0x5'));var ami=require('../ami');config['redis']=_[_0x4c62('0x6')](config[_0x4c62('0x7')],{'host':_0x4c62('0x8'),'port':0x18eb});var io=require(_0x4c62('0x9'))(new Redis(config[_0x4c62('0x7')]));function UserReport(_0xa5ec0c){this[_0x4c62('0xa')]=_0xa5ec0c[_0x4c62('0xa')];this[_0x4c62('0xb')]=_0xa5ec0c[_0x4c62('0xb')];this[_0x4c62('0xc')]=_0xa5ec0c[_0x4c62('0xc')];ami['on']('registryentry',this[_0x4c62('0xd')][_0x4c62('0xe')](this));ami['on'](_0x4c62('0xf'),this['syncRegistry'][_0x4c62('0xe')](this));ami['on'](_0x4c62('0x10'),this[_0x4c62('0x11')][_0x4c62('0xe')](this));ami['on'](_0x4c62('0x12'),this['syncPeerStatus'][_0x4c62('0xe')](this));this[_0x4c62('0x13')]();return BPromise['resolve']()['then'](ami[_0x4c62('0x14')]())[_0x4c62('0x15')](ami[_0x4c62('0x16')]())[_0x4c62('0x15')](ami[_0x4c62('0x17')]())[_0x4c62('0x18')](loggerCatch(_0x4c62('0x19')));}function loggerCatch(_0x2d9ae0){return function(_0x12d0ea){logger['error'](_0x2d9ae0,util[_0x4c62('0x1a')](_0x12d0ea,{'showHidden':![],'depth':null}));};}UserReport[_0x4c62('0x1b')][_0x4c62('0x13')]=function(){setInterval(function(){BPromise['resolve']()['then'](ami[_0x4c62('0x14')]())['then'](ami[_0x4c62('0x16')]())[_0x4c62('0x15')](ami[_0x4c62('0x17')]())[_0x4c62('0x18')](loggerCatch(_0x4c62('0x19')));},0x32c8);};UserReport[_0x4c62('0x1b')][_0x4c62('0x1c')]=function(_0x545ff4){return _0x545ff4!==null&&!_['isUndefined'](_0x545ff4);};UserReport[_0x4c62('0x1b')]['emit']=function(_0x15d275,_0x2fcfb0,_0xf06a37){io['to'](_0x15d275)[_0x4c62('0x1d')](_0x2fcfb0,_0xf06a37);};UserReport[_0x4c62('0x1b')][_0x4c62('0xd')]=function(_0x1ec60e){try{if(this['isNotNull'](_0x1ec60e)){var _0x2a9d9b=_[_0x4c62('0x1e')](this[_0x4c62('0xa')],{'registry':_0x1ec60e['username']});if(_0x2a9d9b){_0x1ec60e['stateRegistry']=_0x1ec60e[_0x4c62('0x1f')];_[_0x4c62('0x20')](_0x2a9d9b,_[_0x4c62('0x21')](_0x1ec60e,['event',_0x4c62('0x22'),_0x4c62('0x23'),_0x4c62('0x1f')]));this['emit'](util[_0x4c62('0x24')](_0x4c62('0x25'),_0x2a9d9b[_0x4c62('0x26')]),'trunk:save',_0x2a9d9b);}}}catch(_0x2dd91b){logger['error'](_0x4c62('0x27'),util[_0x4c62('0x1a')](_0x2dd91b,{'showHidden':![],'depth':null}));}};UserReport[_0x4c62('0x1b')][_0x4c62('0x11')]=function(_0x40e496){try{if(this[_0x4c62('0x1c')](_0x40e496)){if(this[_0x4c62('0xb')][_0x40e496[_0x4c62('0x28')]]){if(!this['agents'][_0x40e496[_0x4c62('0x28')]]['local']||_0x40e496['state'][_0x4c62('0x29')]()=='inuse'){this[_0x4c62('0xb')][_0x40e496[_0x4c62('0x28')]][_0x4c62('0x2a')]=![];if(this['agents'][_0x40e496[_0x4c62('0x28')]]['state']!==_0x40e496[_0x4c62('0x1f')][_0x4c62('0x29')]()){this['agents'][_0x40e496[_0x4c62('0x28')]][_0x4c62('0x2b')]=_[_0x4c62('0x2c')](moment()[_0x4c62('0x24')]('x'));}this['agents'][_0x40e496['device']][_0x4c62('0x1f')]=_0x40e496[_0x4c62('0x1f')]['toLowerCase']();this[_0x4c62('0xb')][_0x40e496[_0x4c62('0x28')]][_0x4c62('0x2d')](_0x40e496);}}else if(this[_0x4c62('0xc')][_0x40e496[_0x4c62('0x28')]]){if(this[_0x4c62('0xc')][_0x40e496[_0x4c62('0x28')]][_0x4c62('0x1f')]!==_0x40e496[_0x4c62('0x1f')][_0x4c62('0x29')]()){this['telephones'][_0x40e496[_0x4c62('0x28')]]['stateTime']=_[_0x4c62('0x2c')](moment()[_0x4c62('0x24')]('x'));}this[_0x4c62('0xc')][_0x40e496[_0x4c62('0x28')]]['state']=_0x40e496[_0x4c62('0x1f')][_0x4c62('0x29')]();this['emit'](util[_0x4c62('0x24')](_0x4c62('0x2e'),this[_0x4c62('0xc')][_0x40e496['device']]['name']),'telephone:save',this[_0x4c62('0xc')][_0x40e496[_0x4c62('0x28')]]);}else if(this['trunks'][_0x40e496[_0x4c62('0x28')]]){if(this[_0x4c62('0xa')][_0x40e496[_0x4c62('0x28')]][_0x4c62('0x1f')]!==_0x40e496[_0x4c62('0x1f')]['toLowerCase']()){this[_0x4c62('0xa')][_0x40e496[_0x4c62('0x28')]][_0x4c62('0x2b')]=_['toNumber'](moment()[_0x4c62('0x24')]('x'));}this['trunks'][_0x40e496[_0x4c62('0x28')]]['state']=_0x40e496[_0x4c62('0x1f')][_0x4c62('0x29')]();this[_0x4c62('0x1d')](util[_0x4c62('0x24')](_0x4c62('0x25'),this[_0x4c62('0xa')][_0x40e496['device']][_0x4c62('0x26')]),_0x4c62('0x2f'),this['trunks'][_0x40e496['device']]);}else if(_[_0x4c62('0x30')](_0x40e496[_0x4c62('0x28')],_0x4c62('0x31'))){}else if(_[_0x4c62('0x30')](_0x40e496[_0x4c62('0x28')],_0x4c62('0x32'))){var _0x4cce1f=_0x40e496[_0x4c62('0x28')];var _0x40e761=_0x4cce1f[_0x4c62('0x33')](_0x4cce1f[_0x4c62('0x34')]('/')+0x1,_0x4cce1f[_0x4c62('0x34')]('@'));var _0x4b5735=_[_0x4c62('0x1e')](this[_0x4c62('0xb')],function(_0x12d467){return _0x12d467[_0x4c62('0x35')]==_0x40e761||_0x12d467[_0x4c62('0x36')]==_0x40e761||_0x12d467['accountcode']==_0x40e761;});if(_0x4b5735){if(_0x4b5735[_0x4c62('0x1f')]!==_0x40e496[_0x4c62('0x1f')]['toLowerCase']()){_0x4b5735[_0x4c62('0x2b')]=_['toNumber'](moment()[_0x4c62('0x24')]('x'));}_0x4b5735[_0x4c62('0x1f')]=_0x40e496[_0x4c62('0x1f')][_0x4c62('0x29')]();_0x4b5735['local']=!![];_0x4b5735[_0x4c62('0x2d')](_0x40e496);}}else{}}}catch(_0x2c4019){logger['error'](_0x4c62('0x37'),util[_0x4c62('0x1a')](_0x2c4019,{'showHidden':![],'depth':null}));}};UserReport[_0x4c62('0x1b')][_0x4c62('0x38')]=function(_0x422021){try{if(this[_0x4c62('0x1c')](_0x422021)&&this[_0x4c62('0x1c')](_0x422021[_0x4c62('0x12')])){if(this['agents'][_0x422021[_0x4c62('0x39')]]){if(!this[_0x4c62('0xb')][_0x422021['peer']]['local']||_0x422021[_0x4c62('0x12')][_0x4c62('0x29')]()=='registered'){this[_0x4c62('0xb')][_0x422021[_0x4c62('0x39')]][_0x4c62('0x2a')]=![];this[_0x4c62('0xb')][_0x422021[_0x4c62('0x39')]][_0x4c62('0x3a')]=_0x422021[_0x4c62('0x12')]['toLowerCase']();this[_0x4c62('0xb')][_0x422021[_0x4c62('0x39')]][_0x4c62('0x3b')]=_0x422021[_0x4c62('0x3b')];this['agents'][_0x422021[_0x4c62('0x39')]][_0x4c62('0x2d')](_0x422021);}}else if(this[_0x4c62('0xc')][_0x422021['peer']]){this[_0x4c62('0xc')][_0x422021[_0x4c62('0x39')]]['status']=_0x422021['peerstatus']['toLowerCase']();this['telephones'][_0x422021[_0x4c62('0x39')]]['address']=_0x422021[_0x4c62('0x3b')];this[_0x4c62('0x1d')](util[_0x4c62('0x24')](_0x4c62('0x2e'),this[_0x4c62('0xc')][_0x422021[_0x4c62('0x39')]][_0x4c62('0x26')]),'telephone:save',this[_0x4c62('0xc')][_0x422021[_0x4c62('0x39')]]);}else if(this[_0x4c62('0xa')][_0x422021[_0x4c62('0x39')]]){this['trunks'][_0x422021['peer']][_0x4c62('0x3a')]=_0x422021[_0x4c62('0x12')]['toLowerCase']();this[_0x4c62('0xa')][_0x422021[_0x4c62('0x39')]][_0x4c62('0x3b')]=_0x422021[_0x4c62('0x3b')];this['emit'](util[_0x4c62('0x24')](_0x4c62('0x25'),this[_0x4c62('0xa')][_0x422021['peer']][_0x4c62('0x26')]),'trunk:save',this[_0x4c62('0xa')][_0x422021[_0x4c62('0x39')]]);}else{}}}catch(_0x4424b4){logger[_0x4c62('0x3c')]('[syncPeerStatus][UserReport]',util[_0x4c62('0x1a')](_0x4424b4,{'showHidden':![],'depth':null}));}};module['exports']=UserReport;
\ No newline at end of file
+var _0xdb7f=['syncRegistry','bind','registry','devicestatechange','syncDeviceState','syncPeerStatus','loopSyncRealTimeShow','resolve','then','actionSipShowRegistry','actionDeviceStateList','actionSipPeerStatus','catch','inspect','prototype','[loopSyncRealTimeShow]','isUndefined','emit','state','omit','event','username','format','trunk:%s','trunk:save','[syncRegistry][UserReport]','isNotNull','device','local','toLowerCase','inuse','toNumber','telephone:%s','name','telephone:save','stateTime','startsWith','Queue','Local','substring','indexOf','find','accountcode','error','peerstatus','peer','registered','status','address','updateStatusRealtime','exports','lodash','bluebird','../../../config/logger','../ami','redis','defaults','socket.io-emitter','trunks','agents','telephones','registryentry'];(function(_0x221d4e,_0x4d1e7a){var _0x1b4c8b=function(_0x9b7673){while(--_0x9b7673){_0x221d4e['push'](_0x221d4e['shift']());}};_0x1b4c8b(++_0x4d1e7a);}(_0xdb7f,0xed));var _0xfdb7=function(_0x2c91e9,_0x2fb965){_0x2c91e9=_0x2c91e9-0x0;var _0x13f0ff=_0xdb7f[_0x2c91e9];return _0x13f0ff;};'use strict';var _=require(_0xfdb7('0x0'));var moment=require('moment');var BPromise=require(_0xfdb7('0x1'));var util=require('util');var Redis=require('ioredis');var config=require('../../../config/environment');var logger=require(_0xfdb7('0x2'))('ami');var ami=require(_0xfdb7('0x3'));config[_0xfdb7('0x4')]=_[_0xfdb7('0x5')](config[_0xfdb7('0x4')],{'host':'localhost','port':0x18eb});var io=require(_0xfdb7('0x6'))(new Redis(config[_0xfdb7('0x4')]));function UserReport(_0x5220ca){this[_0xfdb7('0x7')]=_0x5220ca[_0xfdb7('0x7')];this['agents']=_0x5220ca[_0xfdb7('0x8')];this[_0xfdb7('0x9')]=_0x5220ca[_0xfdb7('0x9')];ami['on'](_0xfdb7('0xa'),this[_0xfdb7('0xb')][_0xfdb7('0xc')](this));ami['on'](_0xfdb7('0xd'),this['syncRegistry'][_0xfdb7('0xc')](this));ami['on'](_0xfdb7('0xe'),this[_0xfdb7('0xf')]['bind'](this));ami['on']('peerstatus',this[_0xfdb7('0x10')][_0xfdb7('0xc')](this));this[_0xfdb7('0x11')]();return BPromise[_0xfdb7('0x12')]()[_0xfdb7('0x13')](ami[_0xfdb7('0x14')]())[_0xfdb7('0x13')](ami[_0xfdb7('0x15')]())[_0xfdb7('0x13')](ami[_0xfdb7('0x16')]())[_0xfdb7('0x17')](loggerCatch('[loopSyncRealTimeShow]'));}function loggerCatch(_0x2108aa){return function(_0x4d810a){logger['error'](_0x2108aa,util[_0xfdb7('0x18')](_0x4d810a,{'showHidden':![],'depth':null}));};}UserReport[_0xfdb7('0x19')][_0xfdb7('0x11')]=function(){setInterval(function(){BPromise['resolve']()[_0xfdb7('0x13')](ami[_0xfdb7('0x14')]())[_0xfdb7('0x13')](ami[_0xfdb7('0x15')]())[_0xfdb7('0x13')](ami[_0xfdb7('0x16')]())[_0xfdb7('0x17')](loggerCatch(_0xfdb7('0x1a')));},0x32c8);};UserReport[_0xfdb7('0x19')]['isNotNull']=function(_0x5d3b69){return _0x5d3b69!==null&&!_[_0xfdb7('0x1b')](_0x5d3b69);};UserReport[_0xfdb7('0x19')][_0xfdb7('0x1c')]=function(_0x363ac5,_0x2c5a23,_0x2f0d6a){io['to'](_0x363ac5)['emit'](_0x2c5a23,_0x2f0d6a);};UserReport[_0xfdb7('0x19')][_0xfdb7('0xb')]=function(_0x46fa3e){try{if(this['isNotNull'](_0x46fa3e)){var _0x2cc750=_['find'](this['trunks'],{'registry':_0x46fa3e['username']});if(_0x2cc750){_0x46fa3e['stateRegistry']=_0x46fa3e[_0xfdb7('0x1d')];_['merge'](_0x2cc750,_[_0xfdb7('0x1e')](_0x46fa3e,[_0xfdb7('0x1f'),'actionid',_0xfdb7('0x20'),_0xfdb7('0x1d')]));this[_0xfdb7('0x1c')](util[_0xfdb7('0x21')](_0xfdb7('0x22'),_0x2cc750['name']),_0xfdb7('0x23'),_0x2cc750);}}}catch(_0x309ac7){logger['error'](_0xfdb7('0x24'),util[_0xfdb7('0x18')](_0x309ac7,{'showHidden':![],'depth':null}));}};UserReport[_0xfdb7('0x19')][_0xfdb7('0xf')]=function(_0x556677){try{if(this[_0xfdb7('0x25')](_0x556677)){if(this[_0xfdb7('0x8')][_0x556677[_0xfdb7('0x26')]]){if(!this[_0xfdb7('0x8')][_0x556677[_0xfdb7('0x26')]][_0xfdb7('0x27')]||_0x556677[_0xfdb7('0x1d')][_0xfdb7('0x28')]()==_0xfdb7('0x29')){this[_0xfdb7('0x8')][_0x556677['device']][_0xfdb7('0x27')]=![];if(this[_0xfdb7('0x8')][_0x556677[_0xfdb7('0x26')]]['state']!==_0x556677[_0xfdb7('0x1d')]['toLowerCase']()){this[_0xfdb7('0x8')][_0x556677[_0xfdb7('0x26')]]['stateTime']=_[_0xfdb7('0x2a')](moment()[_0xfdb7('0x21')]('x'));}this[_0xfdb7('0x8')][_0x556677[_0xfdb7('0x26')]][_0xfdb7('0x1d')]=_0x556677[_0xfdb7('0x1d')]['toLowerCase']();this[_0xfdb7('0x8')][_0x556677[_0xfdb7('0x26')]]['updateStatusRealtime'](_0x556677);}}else if(this['telephones'][_0x556677[_0xfdb7('0x26')]]){if(this[_0xfdb7('0x9')][_0x556677[_0xfdb7('0x26')]][_0xfdb7('0x1d')]!==_0x556677[_0xfdb7('0x1d')]['toLowerCase']()){this[_0xfdb7('0x9')][_0x556677[_0xfdb7('0x26')]]['stateTime']=_[_0xfdb7('0x2a')](moment()[_0xfdb7('0x21')]('x'));}this['telephones'][_0x556677[_0xfdb7('0x26')]][_0xfdb7('0x1d')]=_0x556677[_0xfdb7('0x1d')][_0xfdb7('0x28')]();this['emit'](util[_0xfdb7('0x21')](_0xfdb7('0x2b'),this['telephones'][_0x556677[_0xfdb7('0x26')]][_0xfdb7('0x2c')]),_0xfdb7('0x2d'),this[_0xfdb7('0x9')][_0x556677[_0xfdb7('0x26')]]);}else if(this[_0xfdb7('0x7')][_0x556677[_0xfdb7('0x26')]]){if(this['trunks'][_0x556677['device']][_0xfdb7('0x1d')]!==_0x556677['state'][_0xfdb7('0x28')]()){this['trunks'][_0x556677[_0xfdb7('0x26')]][_0xfdb7('0x2e')]=_[_0xfdb7('0x2a')](moment()[_0xfdb7('0x21')]('x'));}this[_0xfdb7('0x7')][_0x556677[_0xfdb7('0x26')]][_0xfdb7('0x1d')]=_0x556677[_0xfdb7('0x1d')][_0xfdb7('0x28')]();this['emit'](util[_0xfdb7('0x21')]('trunk:%s',this[_0xfdb7('0x7')][_0x556677[_0xfdb7('0x26')]][_0xfdb7('0x2c')]),_0xfdb7('0x23'),this[_0xfdb7('0x7')][_0x556677[_0xfdb7('0x26')]]);}else if(_[_0xfdb7('0x2f')](_0x556677[_0xfdb7('0x26')],_0xfdb7('0x30'))){}else if(_[_0xfdb7('0x2f')](_0x556677['device'],_0xfdb7('0x31'))){var _0xc86226=_0x556677[_0xfdb7('0x26')];var _0x16aaa1=_0xc86226[_0xfdb7('0x32')](_0xc86226[_0xfdb7('0x33')]('/')+0x1,_0xc86226[_0xfdb7('0x33')]('@'));var _0x5b53b7=_[_0xfdb7('0x34')](this[_0xfdb7('0x8')],function(_0x4c7984){return _0x4c7984['mobile']==_0x16aaa1||_0x4c7984['phone']==_0x16aaa1||_0x4c7984[_0xfdb7('0x35')]==_0x16aaa1;});if(_0x5b53b7){if(_0x5b53b7[_0xfdb7('0x1d')]!==_0x556677[_0xfdb7('0x1d')]['toLowerCase']()){_0x5b53b7[_0xfdb7('0x2e')]=_[_0xfdb7('0x2a')](moment()[_0xfdb7('0x21')]('x'));}_0x5b53b7[_0xfdb7('0x1d')]=_0x556677[_0xfdb7('0x1d')][_0xfdb7('0x28')]();_0x5b53b7[_0xfdb7('0x27')]=!![];_0x5b53b7['updateStatusRealtime'](_0x556677);}}else{}}}catch(_0x3fe681){logger[_0xfdb7('0x36')]('[syncDeviceState][UserReport]',util[_0xfdb7('0x18')](_0x3fe681,{'showHidden':![],'depth':null}));}};UserReport[_0xfdb7('0x19')]['syncPeerStatus']=function(_0x454727){try{if(this[_0xfdb7('0x25')](_0x454727)&&this[_0xfdb7('0x25')](_0x454727[_0xfdb7('0x37')])){if(this['agents'][_0x454727[_0xfdb7('0x38')]]){if(!this[_0xfdb7('0x8')][_0x454727[_0xfdb7('0x38')]]['local']||_0x454727[_0xfdb7('0x37')][_0xfdb7('0x28')]()==_0xfdb7('0x39')){this[_0xfdb7('0x8')][_0x454727[_0xfdb7('0x38')]][_0xfdb7('0x27')]=![];this[_0xfdb7('0x8')][_0x454727[_0xfdb7('0x38')]][_0xfdb7('0x3a')]=_0x454727[_0xfdb7('0x37')][_0xfdb7('0x28')]();this['agents'][_0x454727[_0xfdb7('0x38')]][_0xfdb7('0x3b')]=_0x454727['address'];this['agents'][_0x454727[_0xfdb7('0x38')]][_0xfdb7('0x3c')](_0x454727);}}else if(this[_0xfdb7('0x9')][_0x454727[_0xfdb7('0x38')]]){this[_0xfdb7('0x9')][_0x454727[_0xfdb7('0x38')]][_0xfdb7('0x3a')]=_0x454727[_0xfdb7('0x37')][_0xfdb7('0x28')]();this[_0xfdb7('0x9')][_0x454727[_0xfdb7('0x38')]][_0xfdb7('0x3b')]=_0x454727[_0xfdb7('0x3b')];this['emit'](util[_0xfdb7('0x21')](_0xfdb7('0x2b'),this[_0xfdb7('0x9')][_0x454727['peer']]['name']),_0xfdb7('0x2d'),this['telephones'][_0x454727['peer']]);}else if(this[_0xfdb7('0x7')][_0x454727[_0xfdb7('0x38')]]){this[_0xfdb7('0x7')][_0x454727['peer']][_0xfdb7('0x3a')]=_0x454727[_0xfdb7('0x37')][_0xfdb7('0x28')]();this['trunks'][_0x454727[_0xfdb7('0x38')]][_0xfdb7('0x3b')]=_0x454727[_0xfdb7('0x3b')];this[_0xfdb7('0x1c')](util[_0xfdb7('0x21')](_0xfdb7('0x22'),this[_0xfdb7('0x7')][_0x454727[_0xfdb7('0x38')]][_0xfdb7('0x2c')]),_0xfdb7('0x23'),this['trunks'][_0x454727['peer']]);}else{}}}catch(_0x38f1ca){logger['error']('[syncPeerStatus][UserReport]',util[_0xfdb7('0x18')](_0x38f1ca,{'showHidden':![],'depth':null}));}};module[_0xfdb7('0x3d')]=UserReport;
\ No newline at end of file