<commit_before>angular.module("omniControllers")
	.controller("ExchangePendingController",["$scope", "$http", "hashExplorer", "ADDRESS_EXPLORER_URL", "Transaction", "SATOSHI_UNIT", "MIN_MINER_FEE", "OMNI_PROTOCOL_COST", "MINER_SPEED", "$filter",
		function ExchangePendingController($scope, $http, hashExplorer, ADDRESS_EXPLORER_URL, Transaction, SATOSHI_UNIT, MIN_MINER_FEE, OMNI_PROTOCOL_COST, MINER_SPEED, $filter) {
		  function checkSend(sendAmount) {
			if($scope.selectedAddress != undefined){
				avail = parseFloat($scope.selectedAddress.getDisplayBalance(0));
				console.log(avail);
				$scope.selectedAddress.estimateFee(sendAmount).then(function(result){
					$scope.feeData=result;
					if($scope.feeType != 'custom'){
						$scope.minersFee = new Big(result.class_c[$scope.feeType]);
						$scope.topupAmount = new Big(result.topup_c[$scope.feeType]);
					}
				});

				if ( avail >= parseFloat(sendAmount) + parseFloat($scope.minersFee) + parseFloat($scope.protocolFee) ) {
					$scope.cansend = true;
				} else {
					$scope.cansend = false;
				}
				console.log($scope.cansend);
			} else {
				$scope.cansend = false;
			}
		  }

		  $scope.protocolFee = new Big(OMNI_PROTOCOL_COST);
		  $scope.feeType = MINER_SPEED;

		  $scope.editTransactionCost = function(){
			$scope.omniAnnounce = false;
			$scope.modalManager.openTransactionCostModal($scope, $scope.sendTransaction);
			checkSend($scope.sendAmount);
		  }

		  $scope.setHashExplorer = hashExplorer.setHash.bind(hashExplorer)
		  //$scope.selectedAddress = $scope.wallet.addresses[ $scope.wallet.addresses.length-1 ].address;
		  $scope.currencyUnit = 'stom'
		  $scope.pendingThinking = true
		  $scope.hasAddressesWithPrivkey = $scope.wallet.addresses.filter(function(address){
		    return (address.privkey && address.privkey.length == 58) || (address.pubkey && address.pubkey.length > 65);
		  }).map(function(e){
		          return e.hash;
		        });
		  $scope.selectedAddress = $scope.hasAddressesWithPrivkey[0];
		  $scope.wallet.assets.filter(function(currency){
		       return currency.tradable;
		  }).forEach(function(coin){
		    if(coin.symbol=='BTC'){
		      $scope.selectedCoin = coin;
		    }
		  });

		  //Get All data
		  $scope.timeNow = Date.now();
		  $scope.selectedTimeframe = $scope.timeNow - 1394834400000;
		  //$scope.selectedTimeframe = "604800"
		  $scope.filterData = function(time) {
		    var orderbook = JSON.parse($scope.orderBookStorage);

		    var now = Date.now()
		    var filtered_transaction_data = orderbook.filter(function(item) {
		      console.log('time2', +item.tx_time, '>= ?', (now - (+time)))
		      return true //(+item.tx_time) <= (now - (+time) )
		    });
		    $scope.orderbook = filtered_transaction_data;
		  }
		  $scope.getData = function(time) {
		    $scope.orderbook = []
		    var transaction_data = []
		    var postData = {
		      type: 'ADDRESS',
		      currencyType: 'BOTH',
		      address: JSON.stringify($scope.hasAddressesWithPrivkey),
		      offerType: 'BOTH'
		    };
		    $http.post('/v1/exchange/offers', postData).success(function(offerSuccess) {
		      console.log(offerSuccess, ' ofsec');

		      //capture data
		      var nestedData = offerSuccess.data,
		        nestedLevels = 0,
		        capturedData = [];
		      while (typeof nestedData == 'object' && nestedLevels < 5) {
		        var savedData = []
		        if (nestedData instanceof Object && !(nestedData instanceof Array)) { //DEBUG console.log('got obj', nestedData);
		          var data_keys = Object.keys(nestedData)
		          data_keys.forEach(function(key) {
		            savedData = savedData.concat(nestedData[key])
		          });
		        }
		        if (nestedData instanceof Array) { //DEBUG console.log('got arr', nestedData);
		          var arrayOfObjects = []
		          nestedData.forEach(function(elem) {
		            if (elem instanceof Array || !(elem instanceof Object))
		              capturedData.push(elem)
		            else if (elem instanceof Object && !(elem instanceof Array)) { //DEBUG console.log('got obj', elem);
		              var elem_keys = Object.keys(elem)
		              elem_keys.forEach(function(key) { //DEBUG console.log('got item', typeof elem[key])
		                if (typeof elem[key] == 'object' && key != 'invalid')
		                  arrayOfObjects = arrayOfObjects.concat(elem[key])
		              });
		              //DEBUG console.log('check len', arrayOfObjects.length)
		              if (arrayOfObjects.length == 0)
		                capturedData.push(elem)
		            }
		          });
		          savedData = arrayOfObjects
		        }
		        //console.log('nesteddata orig', nestedData, 'data saved', savedData)
		        nestedData = savedData
		        nestedLevels++
		      }

		      transaction_data = capturedData;
		      transaction_data.forEach(function(tx) {
		        if (tx != "ADDRESS_NOT_FOUND") {
		          transaction_data_keys = ['formatted_amount', 'formatted_amount_available',
		            'formatted_bitcoin_amount_desired', 'formatted_fee_required', 'formatted_price_per_coin', 'bitcoin_required'];
		          transaction_data_keys.forEach(function(key) {
		            tx[key] = tx[key];
		          });
		        }
		      });

		      var filtered_transaction_data = transaction_data.filter(function(item) {
		        //console.log('stf', item, typeof item != 'string', 'inv', item.invalid == false && item.invalid.length == undefined)
		        return (typeof item == 'object' && (item.invalid == false && item.invalid.length == undefined))
		      });

		      //DEBUG console.log(filtered_transaction_data, 'tettst')
		      //DEBUG console.log('filtered tx data, pending offers',filtered_transaction_data)

		      $scope.filtered_buys = filtered_transaction_data.filter(function(item) {
		        var orderType = item.tx_type_str.toLowerCase()
		        var orderStatus = item.status ? item.status.toLowerCase() : undefined;
		        //DEBUG console.log(item.tx_type_str, item.status, orderStatus)
		        return (orderType == 'sell accept') && (orderStatus != 'expired') && (orderStatus != 'closed')
		      });

		      $scope.filtered_sells = filtered_transaction_data.filter(function(item) {
		        var orderType = item.tx_type_str.toLowerCase()
		        var orderStatus = item.color.match(/(bgc-done|expired|invalid)/gi) || []
		        //DEBUG console.log(orderStatus, item.color)
		        return (orderType == 'sell offer') && (orderStatus.length == 0)
		      });

		      angular.forEach(filtered_transaction_data, function(transaction, index) {
		        //DEBUG console.log(new Date(Number(transaction.tx_time)))
		        filtered_transaction_data[index].tx_hash_concat = transaction.tx_hash.substring(0, 22) + '...';
		      });

		      transaction_data = filtered_transaction_data;
		      //if null, then append simple message
		      $scope.orderbook = transaction_data.length != 0 ? transaction_data : [{
		            tx_hash: 'No offers/bids found for this timeframe'
		          }];

		      //store around for filtering
		      $scope.orderBookStorage = JSON.stringify($scope.orderbook);
		    });
		  };

		  $scope.purchaseCoin = function(tx) {
		    $scope.minersFee = MIN_MINER_FEE;
		    $scope.pendingThinking = false;
		    $scope.buyTransaction = tx;
		    $scope.sendTo = tx.to_address;
		    $scope.sendAmount = tx.bitcoin_required;
		    $scope.selectedAddress = $scope.wallet.getAddress(tx.from_address);
		    $scope.selectedAsset = $scope.wallet.getAsset(0);
		    checkSend(tx.bitcoin_required);
		    $http.get('/v1/transaction/tx/' + tx.sell_offer_txid + '.json').success(function(data) {
		      var sell_tx = data[0];
		      //$scope.minersFee= new Big(sell_tx.formatted_fee_required);
		      $http.post('/v1/blocks/getlast',{origin:"blockchain"}).success(function(block){
		        $scope.remainingBlocks = sell_tx.formatted_block_time_limit - (block.height - tx.block);
		      });
		    });
		  };

		  $scope.isCancel=true;
		  $scope.confirmCancel = function(tx) {
		    var go = false;
		    sendingAddress = $scope.wallet.getAddress(tx.from_address);
		    sendingAddress.estimateFee().then(function(result){
                                        $scope.feeData=result;
                                        if($scope.feeType != 'custom'){
                                                $scope.minersFee = new Big(result.class_c[$scope.feeType]);
                                                $scope.topupAmount = new Big(result.topup_c[$scope.feeType]);
                                        }
					$scope.omniAnnounce = true;
					$scope.buttonOverride = 'COMMON.NEXT';
					$scope.modalManager.openTransactionCostModal($scope, function(){$scope.sendCancel(tx);} );
                                  });
		  };

		  $scope.sendCancel = function(tx) {
			//var fee = new Big(0.0001);
			var fee = $scope.minersFee;
			var exchangeCancel = new Transaction(20,$scope.wallet.getAddress(tx.from_address),fee,{
			  transaction_version:1,
			  amount_for_sale: 0,
			  amount_desired: 0,
			  min_buyer_fee: 0,
			  blocks: 10,
			  currency_identifier: tx.currencyId,
			  action:3,
			  donate: $scope.account.getSetting("donate")
			});

			$scope.modalManager.openConfirmationModal({
			  dataTemplate: '/views/modals/partials/cancel.html',
			  scope:{
			    title:"EXCHANGE.MYOFFERS.CANCELTITLE",
			    confirmText:"EXCHANGE.MYOFFERS.CANCELCONFIRM",
		            explorerUrl:ADDRESS_EXPLORER_URL,
		            successRedirect:"/exchange/myoffers",
			    minersFee: fee
		          },
		          transaction:exchangeCancel
			})
		  };

		  $scope.sendTransaction = function(){
			// TODO: Validations
			var fee = $scope.minersFee;
			var amount = $scope.sendAmount;
			var acceptSend = new Transaction(0,$scope.selectedAddress,fee,{
		        transaction_version:0,
		        currency_identifier:$scope.selectedAsset.id,
		        amount_to_transfer : +new Big(amount).valueOf(),
		        transaction_to: $scope.sendTo,
		        donate: $scope.account.getSetting("donate"),
		        marker: true
		    });

			var btcPrice = $scope.selectedAsset.price;

			var modalScope = {
				title:"WALLET.SEND.CONFIRM",
				token:$filter('truncate')($scope.selectedAsset.name,15,0),
				sendAmount:$scope.sendAmount,
				symbol:$scope.selectedAsset.symbol,
				sendValue:$scope.sendAmount * btcPrice,
				toAddress:$scope.sendTo,
				fees:new Big(acceptSend.totalCost).plus(new Big(OMNI_PROTOCOL_COST)).valueOf(),
				confirmText:"WALLET.SEND.FUNDS",
            	successRedirect:"/wallet"
			};

			$scope.modalManager.openConfirmationModal({
				dataTemplate: '/views/modals/partials/send.html',
				footerTemplate: $scope.selectedAsset.id == 0 ? '/views/modals/partials/send_footer.html' : undefined,
				scope: $scope.selectedAsset.id != 0 ? modalScope : angular.extend(modalScope, {
					btcValueChanged:false,
					bitcoinValue:btcPrice,
					bitcoin:$scope.selectedAsset
				}),
				transaction:acceptSend
			})
		};
		}])
<commit_msg>remove extra variable<commit_after>angular.module("omniControllers")
	.controller("ExchangePendingController",["$scope", "$http", "hashExplorer", "ADDRESS_EXPLORER_URL", "Transaction", "SATOSHI_UNIT", "MIN_MINER_FEE", "OMNI_PROTOCOL_COST", "MINER_SPEED", "$filter",
		function ExchangePendingController($scope, $http, hashExplorer, ADDRESS_EXPLORER_URL, Transaction, SATOSHI_UNIT, MIN_MINER_FEE, OMNI_PROTOCOL_COST, MINER_SPEED, $filter) {
		  function checkSend(sendAmount) {
			if($scope.selectedAddress != undefined){
				avail = parseFloat($scope.selectedAddress.getDisplayBalance(0));
				console.log(avail);
				$scope.selectedAddress.estimateFee(sendAmount).then(function(result){
					$scope.feeData=result;
					if($scope.feeType != 'custom'){
						$scope.minersFee = new Big(result.class_c[$scope.feeType]);
						$scope.topupAmount = new Big(result.topup_c[$scope.feeType]);
					}
				});

				if ( avail >= parseFloat(sendAmount) + parseFloat($scope.minersFee) + parseFloat($scope.protocolFee) ) {
					$scope.cansend = true;
				} else {
					$scope.cansend = false;
				}
				console.log($scope.cansend);
			} else {
				$scope.cansend = false;
			}
		  }

		  $scope.protocolFee = new Big(OMNI_PROTOCOL_COST);
		  $scope.feeType = MINER_SPEED;

		  $scope.editTransactionCost = function(){
			$scope.omniAnnounce = false;
			$scope.modalManager.openTransactionCostModal($scope, $scope.sendTransaction);
			checkSend($scope.sendAmount);
		  }

		  $scope.setHashExplorer = hashExplorer.setHash.bind(hashExplorer)
		  //$scope.selectedAddress = $scope.wallet.addresses[ $scope.wallet.addresses.length-1 ].address;
		  $scope.currencyUnit = 'stom'
		  $scope.pendingThinking = true
		  $scope.hasAddressesWithPrivkey = $scope.wallet.addresses.filter(function(address){
		    return (address.privkey && address.privkey.length == 58) || (address.pubkey && address.pubkey.length > 65);
		  }).map(function(e){
		          return e.hash;
		        });
		  $scope.selectedAddress = $scope.hasAddressesWithPrivkey[0];
		  $scope.wallet.assets.filter(function(currency){
		       return currency.tradable;
		  }).forEach(function(coin){
		    if(coin.symbol=='BTC'){
		      $scope.selectedCoin = coin;
		    }
		  });

		  //Get All data
		  $scope.timeNow = Date.now();
		  $scope.selectedTimeframe = $scope.timeNow - 1394834400000;
		  //$scope.selectedTimeframe = "604800"
		  $scope.filterData = function(time) {
		    var orderbook = JSON.parse($scope.orderBookStorage);

		    var now = Date.now()
		    var filtered_transaction_data = orderbook.filter(function(item) {
		      console.log('time2', +item.tx_time, '>= ?', (now - (+time)))
		      return true //(+item.tx_time) <= (now - (+time) )
		    });
		    $scope.orderbook = filtered_transaction_data;
		  }
		  $scope.getData = function(time) {
		    $scope.orderbook = []
		    var transaction_data = []
		    var postData = {
		      type: 'ADDRESS',
		      currencyType: 'BOTH',
		      address: JSON.stringify($scope.hasAddressesWithPrivkey),
		      offerType: 'BOTH'
		    };
		    $http.post('/v1/exchange/offers', postData).success(function(offerSuccess) {
		      console.log(offerSuccess, ' ofsec');

		      //capture data
		      var nestedData = offerSuccess.data,
		        nestedLevels = 0,
		        capturedData = [];
		      while (typeof nestedData == 'object' && nestedLevels < 5) {
		        var savedData = []
		        if (nestedData instanceof Object && !(nestedData instanceof Array)) { //DEBUG console.log('got obj', nestedData);
		          var data_keys = Object.keys(nestedData)
		          data_keys.forEach(function(key) {
		            savedData = savedData.concat(nestedData[key])
		          });
		        }
		        if (nestedData instanceof Array) { //DEBUG console.log('got arr', nestedData);
		          var arrayOfObjects = []
		          nestedData.forEach(function(elem) {
		            if (elem instanceof Array || !(elem instanceof Object))
		              capturedData.push(elem)
		            else if (elem instanceof Object && !(elem instanceof Array)) { //DEBUG console.log('got obj', elem);
		              var elem_keys = Object.keys(elem)
		              elem_keys.forEach(function(key) { //DEBUG console.log('got item', typeof elem[key])
		                if (typeof elem[key] == 'object' && key != 'invalid')
		                  arrayOfObjects = arrayOfObjects.concat(elem[key])
		              });
		              //DEBUG console.log('check len', arrayOfObjects.length)
		              if (arrayOfObjects.length == 0)
		                capturedData.push(elem)
		            }
		          });
		          savedData = arrayOfObjects
		        }
		        //console.log('nesteddata orig', nestedData, 'data saved', savedData)
		        nestedData = savedData
		        nestedLevels++
		      }

		      transaction_data = capturedData;
		      transaction_data.forEach(function(tx) {
		        if (tx != "ADDRESS_NOT_FOUND") {
		          transaction_data_keys = ['formatted_amount', 'formatted_amount_available',
		            'formatted_bitcoin_amount_desired', 'formatted_fee_required', 'formatted_price_per_coin', 'bitcoin_required'];
		          transaction_data_keys.forEach(function(key) {
		            tx[key] = tx[key];
		          });
		        }
		      });

		      var filtered_transaction_data = transaction_data.filter(function(item) {
		        //console.log('stf', item, typeof item != 'string', 'inv', item.invalid == false && item.invalid.length == undefined)
		        return (typeof item == 'object' && (item.invalid == false && item.invalid.length == undefined))
		      });

		      //DEBUG console.log(filtered_transaction_data, 'tettst')
		      //DEBUG console.log('filtered tx data, pending offers',filtered_transaction_data)

		      $scope.filtered_buys = filtered_transaction_data.filter(function(item) {
		        var orderType = item.tx_type_str.toLowerCase()
		        var orderStatus = item.status ? item.status.toLowerCase() : undefined;
		        //DEBUG console.log(item.tx_type_str, item.status, orderStatus)
		        return (orderType == 'sell accept') && (orderStatus != 'expired') && (orderStatus != 'closed')
		      });

		      $scope.filtered_sells = filtered_transaction_data.filter(function(item) {
		        var orderType = item.tx_type_str.toLowerCase()
		        var orderStatus = item.color.match(/(bgc-done|expired|invalid)/gi) || []
		        //DEBUG console.log(orderStatus, item.color)
		        return (orderType == 'sell offer') && (orderStatus.length == 0)
		      });

		      angular.forEach(filtered_transaction_data, function(transaction, index) {
		        //DEBUG console.log(new Date(Number(transaction.tx_time)))
		        filtered_transaction_data[index].tx_hash_concat = transaction.tx_hash.substring(0, 22) + '...';
		      });

		      transaction_data = filtered_transaction_data;
		      //if null, then append simple message
		      $scope.orderbook = transaction_data.length != 0 ? transaction_data : [{
		            tx_hash: 'No offers/bids found for this timeframe'
		          }];

		      //store around for filtering
		      $scope.orderBookStorage = JSON.stringify($scope.orderbook);
		    });
		  };

		  $scope.purchaseCoin = function(tx) {
		    $scope.minersFee = MIN_MINER_FEE;
		    $scope.pendingThinking = false;
		    $scope.buyTransaction = tx;
		    $scope.sendTo = tx.to_address;
		    $scope.sendAmount = tx.bitcoin_required;
		    $scope.selectedAddress = $scope.wallet.getAddress(tx.from_address);
		    $scope.selectedAsset = $scope.wallet.getAsset(0);
		    checkSend(tx.bitcoin_required);
		    $http.get('/v1/transaction/tx/' + tx.sell_offer_txid + '.json').success(function(data) {
		      var sell_tx = data[0];
		      //$scope.minersFee= new Big(sell_tx.formatted_fee_required);
		      $http.post('/v1/blocks/getlast',{origin:"blockchain"}).success(function(block){
		        $scope.remainingBlocks = sell_tx.formatted_block_time_limit - (block.height - tx.block);
		      });
		    });
		  };

		  $scope.isCancel=true;
		  $scope.confirmCancel = function(tx) {
		    sendingAddress = $scope.wallet.getAddress(tx.from_address);
		    sendingAddress.estimateFee().then(function(result){
                                        $scope.feeData=result;
                                        if($scope.feeType != 'custom'){
                                                $scope.minersFee = new Big(result.class_c[$scope.feeType]);
                                                $scope.topupAmount = new Big(result.topup_c[$scope.feeType]);
                                        }
					$scope.omniAnnounce = true;
					$scope.buttonOverride = 'COMMON.NEXT';
					$scope.modalManager.openTransactionCostModal($scope, function(){$scope.sendCancel(tx);} );
                                  });
		  };

		  $scope.sendCancel = function(tx) {
			//var fee = new Big(0.0001);
			var fee = $scope.minersFee;
			var exchangeCancel = new Transaction(20,$scope.wallet.getAddress(tx.from_address),fee,{
			  transaction_version:1,
			  amount_for_sale: 0,
			  amount_desired: 0,
			  min_buyer_fee: 0,
			  blocks: 10,
			  currency_identifier: tx.currencyId,
			  action:3,
			  donate: $scope.account.getSetting("donate")
			});

			$scope.modalManager.openConfirmationModal({
			  dataTemplate: '/views/modals/partials/cancel.html',
			  scope:{
			    title:"EXCHANGE.MYOFFERS.CANCELTITLE",
			    confirmText:"EXCHANGE.MYOFFERS.CANCELCONFIRM",
		            explorerUrl:ADDRESS_EXPLORER_URL,
		            successRedirect:"/exchange/myoffers",
			    minersFee: fee
		          },
		          transaction:exchangeCancel
			})
		  };

		  $scope.sendTransaction = function(){
			// TODO: Validations
			var fee = $scope.minersFee;
			var amount = $scope.sendAmount;
			var acceptSend = new Transaction(0,$scope.selectedAddress,fee,{
		        transaction_version:0,
		        currency_identifier:$scope.selectedAsset.id,
		        amount_to_transfer : +new Big(amount).valueOf(),
		        transaction_to: $scope.sendTo,
		        donate: $scope.account.getSetting("donate"),
		        marker: true
		    });

			var btcPrice = $scope.selectedAsset.price;

			var modalScope = {
				title:"WALLET.SEND.CONFIRM",
				token:$filter('truncate')($scope.selectedAsset.name,15,0),
				sendAmount:$scope.sendAmount,
				symbol:$scope.selectedAsset.symbol,
				sendValue:$scope.sendAmount * btcPrice,
				toAddress:$scope.sendTo,
				fees:new Big(acceptSend.totalCost).plus(new Big(OMNI_PROTOCOL_COST)).valueOf(),
				confirmText:"WALLET.SEND.FUNDS",
            	successRedirect:"/wallet"
			};

			$scope.modalManager.openConfirmationModal({
				dataTemplate: '/views/modals/partials/send.html',
				footerTemplate: $scope.selectedAsset.id == 0 ? '/views/modals/partials/send_footer.html' : undefined,
				scope: $scope.selectedAsset.id != 0 ? modalScope : angular.extend(modalScope, {
					btcValueChanged:false,
					bitcoinValue:btcPrice,
					bitcoin:$scope.selectedAsset
				}),
				transaction:acceptSend
			})
		};
		}])
<|endoftext|>


<commit_before>angular.module("omniControllers")
	.controller("ExchangePendingController",["$scope", "$http", "hashExplorer", "ADDRESS_EXPLORER_URL", "Transaction", "SATOSHI_UNIT",
		function ExchangePendingController($scope, $http, hashExplorer, ADDRESS_EXPLORER_URL, Transaction, SATOSHI_UNIT) {
		  $scope.setHashExplorer = hashExplorer.setHash.bind(hashExplorer)
		  //$scope.selectedAddress = $scope.wallet.addresses[ $scope.wallet.addresses.length-1 ].address;
		  $scope.currencyUnit = 'stom'
		  $scope.pendingThinking = true
		  $scope.hasAddressesWithPrivkey = $scope.wallet.addresses.filter(function(address){
		    return address.privkey && address.privkey.length == 58
		  }).map(function(e){
		          return e.hash;
		        });
		  $scope.selectedAddress = $scope.hasAddressesWithPrivkey[0];
		  $scope.wallet.assets.filter(function(currency){
		       return currency.tradable;
		  }).forEach(function(coin){
		    if(coin.symbol=='BTC'){
		      $scope.selectedCoin = coin;
		    }
		  });

		  //Get All data
		  $scope.timeNow = Date.now();
		  $scope.selectedTimeframe = $scope.timeNow - 1394834400000;
		  //$scope.selectedTimeframe = "604800"
		  $scope.filterData = function(time) {
		    var orderbook = JSON.parse($scope.orderBookStorage);

		    var now = Date.now()
		    var filtered_transaction_data = orderbook.filter(function(item) {
		      console.log('time2', +item.tx_time, '>= ?', (now - (+time)))
		      return true //(+item.tx_time) <= (now - (+time) )
		    });
		    $scope.orderbook = filtered_transaction_data;
		  }
		  $scope.getData = function(time) {
		    $scope.orderbook = []
		    var transaction_data = []
		    var postData = {
		      type: 'ADDRESS',
		      currencyType: 'BOTH',
		      address: JSON.stringify($scope.hasAddressesWithPrivkey),
		      offerType: 'BOTH'
		    };
		    $http.post('/v1/exchange/offers', postData).success(function(offerSuccess) {
		      console.log(offerSuccess, ' ofsec');

		      //capture data
		      var nestedData = offerSuccess.data,
		        nestedLevels = 0,
		        capturedData = [];
		      while (typeof nestedData == 'object' && nestedLevels < 5) {
		        var savedData = []
		        if (nestedData instanceof Object && !(nestedData instanceof Array)) { //DEBUG console.log('got obj', nestedData);
		          var data_keys = Object.keys(nestedData)
		          data_keys.forEach(function(key) {
		            savedData = savedData.concat(nestedData[key])
		          });
		        }
		        if (nestedData instanceof Array) { //DEBUG console.log('got arr', nestedData);
		          var arrayOfObjects = []
		          nestedData.forEach(function(elem) {
		            if (elem instanceof Array || !(elem instanceof Object))
		              capturedData.push(elem)
		            else if (elem instanceof Object && !(elem instanceof Array)) { //DEBUG console.log('got obj', elem);
		              var elem_keys = Object.keys(elem)
		              elem_keys.forEach(function(key) { //DEBUG console.log('got item', typeof elem[key])
		                if (typeof elem[key] == 'object' && key != 'invalid')
		                  arrayOfObjects = arrayOfObjects.concat(elem[key])
		              });
		              //DEBUG console.log('check len', arrayOfObjects.length)
		              if (arrayOfObjects.length == 0)
		                capturedData.push(elem)
		            }
		          });
		          savedData = arrayOfObjects
		        }
		        //console.log('nesteddata orig', nestedData, 'data saved', savedData)
		        nestedData = savedData
		        nestedLevels++
		      }

		      transaction_data = capturedData;
		      transaction_data.forEach(function(tx) {
		        if (tx != "ADDRESS_NOT_FOUND") {
		          transaction_data_keys = ['formatted_amount', 'formatted_amount_available',
		            'formatted_bitcoin_amount_desired', 'formatted_fee_required', 'formatted_price_per_coin', 'bitcoin_required'];
		          transaction_data_keys.forEach(function(key) {
		            tx[key] = tx[key];
		          });
		        }
		      });

		      var filtered_transaction_data = transaction_data.filter(function(item) {
		        //console.log('stf', item, typeof item != 'string', 'inv', item.invalid == false && item.invalid.length == undefined)
		        return (typeof item == 'object' && (item.invalid == false && item.invalid.length == undefined))
		      });

		      //DEBUG console.log(filtered_transaction_data, 'tettst')
		      //DEBUG console.log('filtered tx data, pending offers',filtered_transaction_data)

		      $scope.filtered_buys = filtered_transaction_data.filter(function(item) {
		        var orderType = item.tx_type_str.toLowerCase()
		        var orderStatus = item.status ? item.status.toLowerCase() : undefined;
		        //DEBUG console.log(item.tx_type_str, item.status, orderStatus)
		        return (orderType == 'sell accept') && (orderStatus != 'expired') && (orderStatus != 'closed')
		      });

		      $scope.filtered_sells = filtered_transaction_data.filter(function(item) {
		        var orderType = item.tx_type_str.toLowerCase()
		        var orderStatus = item.color.match(/(bgc-done|expired|invalid)/gi) || []
		        //DEBUG console.log(orderStatus, item.color)
		        return (orderType == 'sell offer') && (orderStatus.length == 0)
		      });

		      angular.forEach(filtered_transaction_data, function(transaction, index) {
		        //DEBUG console.log(new Date(Number(transaction.tx_time)))
		        filtered_transaction_data[index].tx_hash_concat = transaction.tx_hash.substring(0, 22) + '...';
		      });

		      transaction_data = filtered_transaction_data;
		      //if null, then append simple message
		      $scope.orderbook = transaction_data.length != 0 ? transaction_data : [{
		            tx_hash: 'No offers/bids found for this timeframe'
		          }];

		      //store around for filtering
		      $scope.orderBookStorage = JSON.stringify($scope.orderbook);
		    });
		  };
		  $scope.purchaseCoin = function(tx) {
		    $scope.pendingThinking = false;
		    $scope.buyTransaction = tx;
		    $scope.sendTo = tx.to_address;
		    $scope.sendAmount = tx.bitcoin_required;
		    $scope.selectedAddress = $scope.wallet.getAddress(tx.from_address);
		    $scope.selectedAsset = $scope.wallet.getAsset(0);
		    $http.get('/v1/transaction/tx/' + tx.sell_offer_txid + '.json').success(function(data) {
		      var sell_tx = data[0];
		      $scope.minersFee= new Big(sell_tx.formatted_fee_required);
		      $http.post('/v1/blocks/getlast',{origin:"blockchain"}).success(function(block){
		        $scope.remainingBlocks = sell_tx.formatted_block_time_limit - (block.height - tx.block);
		      });
		    });
		  };

		  $scope.isCancel=true;
		  $scope.confirmCancel = function(tx) {
		  	var fee = new Big(0.0001);
	        var exchangeCancel = new Transaction(20,$scope.wallet.getAddress(tx.from_address),fee,{
	            amount: 0,
	            price: 0,
	            min_buyer_fee: 0,
	            blocks: 10,
	            currency: (+tx.currencyId) == 1 ? 'MSC' : 'TMSC',
	            donate: $scope.account.getSetting("donate")
	          });

	        $scope.modalManager.openConfirmationModal({
	          dataTemplate: '/views/modals/partials/cancel.html',
	          scope:{
	            title:"EXCHANGE.MYOFFERS.CANCELTITLE",
	            confirmText:"EXCHANGE.MYOFFERS.CANCELCONFIRM",
	            explorerUrl:ADDRESS_EXPLORER_URL,
	            successRedirect:"/exchange/myoffers"
	          },
	          transaction:exchangeCancel
	        })
		  }

		  $scope.sendTransaction = function(){
			// TODO: Validations
			var fee = $scope.minersFee;
			var amount = $scope.sendAmount;
			var acceptSend = new Transaction(0,$scope.selectedAddress,fee,{
		        transaction_version:0,
		        currency_identifier:$scope.selectedAsset.id,
		        amount_to_transfer : $scope.selectedAsset.divisible ? +new Big(amount).times(SATOSHI_UNIT).valueOf() : +amount,
		        transaction_to: $scope.sendTo,
		        donate: $scope.account.getSetting("donate"),
		        marker: true
		    });

			var btcPrice = $scope.selectedAsset.price;

			var modalScope = {
				title:"WALLET.SEND.CONFIRM",
				token:$filter('truncate')($scope.selectedAsset.name,15,0),
				sendAmount:$scope.sendAmount,
				symbol:$scope.selectedAsset.symbol,
				sendValue:$scope.sendAmount * btcPrice,
				toAddress:$scope.sendTo,
				fees:acceptSend.totalCost,
				confirmText:"WALLET.SEND.FUNDS",
            	successRedirect:"/wallet"
			};

			$scope.modalManager.openConfirmationModal({
				dataTemplate: '/views/modals/partials/send.html',
				footerTemplate: $scope.selectedAsset.id == 0 ? '/views/modals/partials/send_footer.html' : undefined,
				scope: $scope.selectedAsset.id != 0 ? modalScope : angular.extend(modalScope, {
					btcValueChanged:false,
					bitcoinValue:btcPrice,
					bitcoin:$scope.selectedAsset
				}),
				transaction:simpleSend
			})
		};
		}])<commit_msg>Added missing dependency<commit_after>angular.module("omniControllers")
	.controller("ExchangePendingController",["$scope", "$http", "hashExplorer", "ADDRESS_EXPLORER_URL", "Transaction", "SATOSHI_UNIT", "$filter",
		function ExchangePendingController($scope, $http, hashExplorer, ADDRESS_EXPLORER_URL, Transaction, SATOSHI_UNIT, $filter) {
		  $scope.setHashExplorer = hashExplorer.setHash.bind(hashExplorer)
		  //$scope.selectedAddress = $scope.wallet.addresses[ $scope.wallet.addresses.length-1 ].address;
		  $scope.currencyUnit = 'stom'
		  $scope.pendingThinking = true
		  $scope.hasAddressesWithPrivkey = $scope.wallet.addresses.filter(function(address){
		    return address.privkey && address.privkey.length == 58
		  }).map(function(e){
		          return e.hash;
		        });
		  $scope.selectedAddress = $scope.hasAddressesWithPrivkey[0];
		  $scope.wallet.assets.filter(function(currency){
		       return currency.tradable;
		  }).forEach(function(coin){
		    if(coin.symbol=='BTC'){
		      $scope.selectedCoin = coin;
		    }
		  });

		  //Get All data
		  $scope.timeNow = Date.now();
		  $scope.selectedTimeframe = $scope.timeNow - 1394834400000;
		  //$scope.selectedTimeframe = "604800"
		  $scope.filterData = function(time) {
		    var orderbook = JSON.parse($scope.orderBookStorage);

		    var now = Date.now()
		    var filtered_transaction_data = orderbook.filter(function(item) {
		      console.log('time2', +item.tx_time, '>= ?', (now - (+time)))
		      return true //(+item.tx_time) <= (now - (+time) )
		    });
		    $scope.orderbook = filtered_transaction_data;
		  }
		  $scope.getData = function(time) {
		    $scope.orderbook = []
		    var transaction_data = []
		    var postData = {
		      type: 'ADDRESS',
		      currencyType: 'BOTH',
		      address: JSON.stringify($scope.hasAddressesWithPrivkey),
		      offerType: 'BOTH'
		    };
		    $http.post('/v1/exchange/offers', postData).success(function(offerSuccess) {
		      console.log(offerSuccess, ' ofsec');

		      //capture data
		      var nestedData = offerSuccess.data,
		        nestedLevels = 0,
		        capturedData = [];
		      while (typeof nestedData == 'object' && nestedLevels < 5) {
		        var savedData = []
		        if (nestedData instanceof Object && !(nestedData instanceof Array)) { //DEBUG console.log('got obj', nestedData);
		          var data_keys = Object.keys(nestedData)
		          data_keys.forEach(function(key) {
		            savedData = savedData.concat(nestedData[key])
		          });
		        }
		        if (nestedData instanceof Array) { //DEBUG console.log('got arr', nestedData);
		          var arrayOfObjects = []
		          nestedData.forEach(function(elem) {
		            if (elem instanceof Array || !(elem instanceof Object))
		              capturedData.push(elem)
		            else if (elem instanceof Object && !(elem instanceof Array)) { //DEBUG console.log('got obj', elem);
		              var elem_keys = Object.keys(elem)
		              elem_keys.forEach(function(key) { //DEBUG console.log('got item', typeof elem[key])
		                if (typeof elem[key] == 'object' && key != 'invalid')
		                  arrayOfObjects = arrayOfObjects.concat(elem[key])
		              });
		              //DEBUG console.log('check len', arrayOfObjects.length)
		              if (arrayOfObjects.length == 0)
		                capturedData.push(elem)
		            }
		          });
		          savedData = arrayOfObjects
		        }
		        //console.log('nesteddata orig', nestedData, 'data saved', savedData)
		        nestedData = savedData
		        nestedLevels++
		      }

		      transaction_data = capturedData;
		      transaction_data.forEach(function(tx) {
		        if (tx != "ADDRESS_NOT_FOUND") {
		          transaction_data_keys = ['formatted_amount', 'formatted_amount_available',
		            'formatted_bitcoin_amount_desired', 'formatted_fee_required', 'formatted_price_per_coin', 'bitcoin_required'];
		          transaction_data_keys.forEach(function(key) {
		            tx[key] = tx[key];
		          });
		        }
		      });

		      var filtered_transaction_data = transaction_data.filter(function(item) {
		        //console.log('stf', item, typeof item != 'string', 'inv', item.invalid == false && item.invalid.length == undefined)
		        return (typeof item == 'object' && (item.invalid == false && item.invalid.length == undefined))
		      });

		      //DEBUG console.log(filtered_transaction_data, 'tettst')
		      //DEBUG console.log('filtered tx data, pending offers',filtered_transaction_data)

		      $scope.filtered_buys = filtered_transaction_data.filter(function(item) {
		        var orderType = item.tx_type_str.toLowerCase()
		        var orderStatus = item.status ? item.status.toLowerCase() : undefined;
		        //DEBUG console.log(item.tx_type_str, item.status, orderStatus)
		        return (orderType == 'sell accept') && (orderStatus != 'expired') && (orderStatus != 'closed')
		      });

		      $scope.filtered_sells = filtered_transaction_data.filter(function(item) {
		        var orderType = item.tx_type_str.toLowerCase()
		        var orderStatus = item.color.match(/(bgc-done|expired|invalid)/gi) || []
		        //DEBUG console.log(orderStatus, item.color)
		        return (orderType == 'sell offer') && (orderStatus.length == 0)
		      });

		      angular.forEach(filtered_transaction_data, function(transaction, index) {
		        //DEBUG console.log(new Date(Number(transaction.tx_time)))
		        filtered_transaction_data[index].tx_hash_concat = transaction.tx_hash.substring(0, 22) + '...';
		      });

		      transaction_data = filtered_transaction_data;
		      //if null, then append simple message
		      $scope.orderbook = transaction_data.length != 0 ? transaction_data : [{
		            tx_hash: 'No offers/bids found for this timeframe'
		          }];

		      //store around for filtering
		      $scope.orderBookStorage = JSON.stringify($scope.orderbook);
		    });
		  };
		  $scope.purchaseCoin = function(tx) {
		    $scope.pendingThinking = false;
		    $scope.buyTransaction = tx;
		    $scope.sendTo = tx.to_address;
		    $scope.sendAmount = tx.bitcoin_required;
		    $scope.selectedAddress = $scope.wallet.getAddress(tx.from_address);
		    $scope.selectedAsset = $scope.wallet.getAsset(0);
		    $http.get('/v1/transaction/tx/' + tx.sell_offer_txid + '.json').success(function(data) {
		      var sell_tx = data[0];
		      $scope.minersFee= new Big(sell_tx.formatted_fee_required);
		      $http.post('/v1/blocks/getlast',{origin:"blockchain"}).success(function(block){
		        $scope.remainingBlocks = sell_tx.formatted_block_time_limit - (block.height - tx.block);
		      });
		    });
		  };

		  $scope.isCancel=true;
		  $scope.confirmCancel = function(tx) {
		  	var fee = new Big(0.0001);
	        var exchangeCancel = new Transaction(20,$scope.wallet.getAddress(tx.from_address),fee,{
	            amount: 0,
	            price: 0,
	            min_buyer_fee: 0,
	            blocks: 10,
	            currency: (+tx.currencyId) == 1 ? 'MSC' : 'TMSC',
	            donate: $scope.account.getSetting("donate")
	          });

	        $scope.modalManager.openConfirmationModal({
	          dataTemplate: '/views/modals/partials/cancel.html',
	          scope:{
	            title:"EXCHANGE.MYOFFERS.CANCELTITLE",
	            confirmText:"EXCHANGE.MYOFFERS.CANCELCONFIRM",
	            explorerUrl:ADDRESS_EXPLORER_URL,
	            successRedirect:"/exchange/myoffers"
	          },
	          transaction:exchangeCancel
	        })
		  }

		  $scope.sendTransaction = function(){
			// TODO: Validations
			var fee = $scope.minersFee;
			var amount = $scope.sendAmount;
			var acceptSend = new Transaction(0,$scope.selectedAddress,fee,{
		        transaction_version:0,
		        currency_identifier:$scope.selectedAsset.id,
		        amount_to_transfer : $scope.selectedAsset.divisible ? +new Big(amount).times(SATOSHI_UNIT).valueOf() : +amount,
		        transaction_to: $scope.sendTo,
		        donate: $scope.account.getSetting("donate"),
		        marker: true
		    });

			var btcPrice = $scope.selectedAsset.price;

			var modalScope = {
				title:"WALLET.SEND.CONFIRM",
				token:$filter('truncate')($scope.selectedAsset.name,15,0),
				sendAmount:$scope.sendAmount,
				symbol:$scope.selectedAsset.symbol,
				sendValue:$scope.sendAmount * btcPrice,
				toAddress:$scope.sendTo,
				fees:acceptSend.totalCost,
				confirmText:"WALLET.SEND.FUNDS",
            	successRedirect:"/wallet"
			};

			$scope.modalManager.openConfirmationModal({
				dataTemplate: '/views/modals/partials/send.html',
				footerTemplate: $scope.selectedAsset.id == 0 ? '/views/modals/partials/send_footer.html' : undefined,
				scope: $scope.selectedAsset.id != 0 ? modalScope : angular.extend(modalScope, {
					btcValueChanged:false,
					bitcoinValue:btcPrice,
					bitcoin:$scope.selectedAsset
				}),
				transaction:simpleSend
			})
		};
		}])<|endoftext|>


<commit_before>module.exports = {
	worker: {
		output: {
			filename: "hash.worker.js",
			chunkFilename: "[id].hash.worker.js"
		}
	}
}<commit_msg>fix: pass worker options using LoaderOptionsPlugin<commit_after>var webpack = require("../../");
module.exports = {
    plugins: [
        new webpack.LoaderOptionsPlugin({
            options: {
                worker: {
                    output: {
                        filename: "hash.worker.js",
                        chunkFilename: "[id].hash.worker.js"
                    }
                }
            }
        })
    ]
}
<|endoftext|>


<commit_before>/**
 * ip2region client for nodejs
 *
 * project: https://github.com/lionsoul2014/ip2region
 *
 * @author dongyado<dongyado@gmail.com>
 * */
var fs   = require('fs');

var ipbase = [16777216, 65536, 256, 1]; // for ip2long
var ip2region = {};
ip2region.db_file_path   = null;
ip2region.db_fd          = null;

var totalBlocks         = 0;
var firstIndexPtr       = 0;
var lastIndexPtr        = 0;
var superBlock          = new Buffer(8);

var indexBlockLength    = 12;
var totalHeaderLength   = 8192;

/**
 * binary search synchronized
 * */
ip2region.binarySearchSync = function(ip)
{
    var low     = 0;
    var mid     = 0;
    var high    = totalBlocks;
    var dataPos = 0;
    var pos     = 0;
    var sip     = 0;
    var eip     = 0;
    var indexBuffer = new Buffer(12);

    if( typeof(ip) == 'string' ) ip = ip2long(ip);

    // binary search
    while( low <= high ) {
        mid = ((low + high) >> 1);
        pos = firstIndexPtr + mid * indexBlockLength;
        fs.readSync(this.db_fd, indexBuffer, 0, indexBlockLength, pos);
        sip = getLong(indexBuffer, 0);

        //console.log( ' sip : ' + sip + ' eip : ' + eip );
        if ( ip < sip) {
            high = mid - 1;
        } else {
            eip = getLong(indexBuffer, 4);
            if ( ip > eip ) {
                low = mid + 1;
            } else {
                dataPos = getLong(indexBuffer, 8);
                break;
            }
        }
    }

    // read data
    if (dataPos == 0) return null;
    var dataLen = ((dataPos >> 24) & 0xFF);
    var dataPos = (dataPos & 0x00FFFFFF);
    var dataBuffer = new Buffer(dataLen);

    fs.readSync(this.db_fd, dataBuffer, 0, dataLen, dataPos);

    var city_id = getLong(dataBuffer, 0);
    var data    = dataBuffer.toString('utf8', 4, dataLen);

    //console.log(city_id);
    //console.log(data);

    return { city: city_id, region: data };
}

var headerSip = null;
var headerPtr = 0;
var headerLen = 0;

/**
 * btree  search synchronized
 * */
ip2region.btreeSearchSync = function(ip)
{
    var indexBlockBuffer  = new Buffer(indexBlockLength);
    var headerIndexBuffer = new Buffer(totalHeaderLength);
    if( typeof(ip) == 'string' )  ip = ip2long(ip);

    var i = 0;
    // header index handler
    if (headerSip == null) {
        fs.readSync(this.db_fd, headerIndexBuffer, 0, totalHeaderLength, 8);
        headerSip = new Array();
        headerPtr = new Array();

        var startIp = 0;
        var dataPtr = 0;
        for ( i = 0; i < totalHeaderLength; i += 8) {
            startIp = getLong(headerIndexBuffer, i);
            dataPtr = getLong(headerIndexBuffer, i + 4);
            if ( dataPtr == 0) break;

            headerSip.push(startIp);
            headerPtr.push(dataPtr);
            headerLen++; // header index size count
        }
    }

    // first search  (in header index)
    var low  = 0;
    var mid  = 0;
    var high = headerLen;
    var sptr = 0;
    var eptr = 0;

    while(low <= high) {
        mid = ((low + high) >> 1);

        if (ip == headerSip[mid]) {
            if ( m > 0) {
                sptr = headerPtr[mid - 1];
                eptr = headerPtr[mid];
            } else {
                sptr = headerPtr[mid];
                eptr = headerPtr[mid + 1];
            }
            break;
        }

        if ( ip < headerSip[mid]) {
            if (mid == 0) {
                sptr = headerPtr[mid];
                eptr = headerPtr[mid + 1];
                break;
            } else if ( ip > headerSip[mid - 1]) {
                sptr = headerPtr[mid - 1];
                eptr = headerPtr[mid];
                break;
            }
            high = mid - 1;
        } else {
            if ( mid == headerLen - 1) {
                sptr = headerPtr[mid - 1];
                eptr = headerPtr[mid];
                break;
            } else if ( ip <= headerSip[mid + 1]) {
                sptr = headerPtr[mid];
                eptr = headerPtr[mid + 1];
                break;
            }
            low = mid + 1;
        }
    }

    // match nothing
    if (sptr == 0) return null;

    // second search (in index)
    var blockLen    = eptr - sptr;
    var blockBuffer = new Buffer(blockLen + indexBlockLength);
    fs.readSync(this.db_fd, blockBuffer, 0, blockLen + indexBlockLength, sptr);

    low = 0;
    high = blockLen / indexBlockLength;

    var p = 0;
    var sip = 0;
    var eip = 0;
    var dataPtr = 0;

    while(low <= high) {
        mid = ((low + high) >> 1);
        p = mid * indexBlockLength;
        sip = getLong(blockBuffer, p);

        if (ip < sip) {
            high = mid - 1;
        } else {
            eip = getLong(blockBuffer, p + 4);
            if (ip > eip) {
                low = mid + 1;
            } else {
                dataPtr =  getLong(blockBuffer, p + 8);
                break;
            }
        }
    }

    // read data
    if (dataPtr == 0) return null;
    var dataLen = ((dataPtr >> 24) & 0xFF);
    var dataPtr = (dataPtr & 0x00FFFFFF);
    var dataBuffer = new Buffer(dataLen);

    fs.readSync(this.db_fd, dataBuffer, 0, dataLen, dataPtr);

    var city_id = getLong(dataBuffer, 0);
    var data    = dataBuffer.toString('utf8', 4, dataLen);

    //console.log(city_id);
    //console.log(data);

    return { city: city_id, region: data };
}

/**
 * convert ip to long (xxx.xxx.xxx.xxx to a integer)
 * */
function ip2long(ip)
{
    var val = 0;
    ip.split('.').forEach(function(ele, i){
        val += ipbase[i] * ele;
    });

    return val;
}

/**
 * get long value from buffer with specified offset
 * */
function getLong(buffer, offset)
{
    var val =  (
        (buffer[offset] & 0x000000FF) |
        ((buffer[offset + 1] <<  8) & 0x0000FF00) |
        ((buffer[offset + 2] << 16) & 0x00FF0000) |
        ((buffer[offset + 3] << 24) & 0xFF000000)
    );

    // convert to unsigned int
    if (val < 0) {
        val = val >>> 0;
    }
    return val;
}

exports.create = function(db_path)
{
    if (typeof(db_path) == "undefined" || fs.exists(db_path) ) {
        throw("[ip2region] db file not exists : " + db_path);
    }

    ip2region.db_file_path = db_path;

    try {
        ip2region.db_fd = fs.openSync(ip2region.db_file_path, 'r');
    } catch(e) {
        throw("[ip2region] Can not open ip2region.db file , path : "
                + ip2region.db_file_path);
    }

    // init basic search environment
    if (totalBlocks == 0) {
        fs.readSync(ip2region.db_fd, superBlock, 0, 8, 0);
        firstIndexPtr = getLong(superBlock, 0);
        lastIndexPtr  = getLong(superBlock, 4);
        totalBlocks   = (lastIndexPtr - firstIndexPtr)
                            / indexBlockLength + 1;
    }

    return ip2region;
}

exports.destroy = function(ip2rObj)
{
    ip2rObj.db_file_path = null;
    fs.closeSync(ip2rObj.db_fd);
}
<commit_msg>fix: ReferenceError: m is not defined<commit_after>/**
 * ip2region client for nodejs
 *
 * project: https://github.com/lionsoul2014/ip2region
 *
 * @author dongyado<dongyado@gmail.com>
 * */
var fs   = require('fs');

var ipbase = [16777216, 65536, 256, 1]; // for ip2long
var ip2region = {};
ip2region.db_file_path   = null;
ip2region.db_fd          = null;

var totalBlocks         = 0;
var firstIndexPtr       = 0;
var lastIndexPtr        = 0;
var superBlock          = new Buffer(8);

var indexBlockLength    = 12;
var totalHeaderLength   = 8192;

/**
 * binary search synchronized
 * */
ip2region.binarySearchSync = function(ip)
{
    var low     = 0;
    var mid     = 0;
    var high    = totalBlocks;
    var dataPos = 0;
    var pos     = 0;
    var sip     = 0;
    var eip     = 0;
    var indexBuffer = new Buffer(12);

    if( typeof(ip) == 'string' ) ip = ip2long(ip);

    // binary search
    while( low <= high ) {
        mid = ((low + high) >> 1);
        pos = firstIndexPtr + mid * indexBlockLength;
        fs.readSync(this.db_fd, indexBuffer, 0, indexBlockLength, pos);
        sip = getLong(indexBuffer, 0);

        //console.log( ' sip : ' + sip + ' eip : ' + eip );
        if ( ip < sip) {
            high = mid - 1;
        } else {
            eip = getLong(indexBuffer, 4);
            if ( ip > eip ) {
                low = mid + 1;
            } else {
                dataPos = getLong(indexBuffer, 8);
                break;
            }
        }
    }

    // read data
    if (dataPos == 0) return null;
    var dataLen = ((dataPos >> 24) & 0xFF);
    var dataPos = (dataPos & 0x00FFFFFF);
    var dataBuffer = new Buffer(dataLen);

    fs.readSync(this.db_fd, dataBuffer, 0, dataLen, dataPos);

    var city_id = getLong(dataBuffer, 0);
    var data    = dataBuffer.toString('utf8', 4, dataLen);

    //console.log(city_id);
    //console.log(data);

    return { city: city_id, region: data };
}

var headerSip = null;
var headerPtr = 0;
var headerLen = 0;

/**
 * btree  search synchronized
 * */
ip2region.btreeSearchSync = function(ip)
{
    var indexBlockBuffer  = new Buffer(indexBlockLength);
    var headerIndexBuffer = new Buffer(totalHeaderLength);
    if( typeof(ip) == 'string' )  ip = ip2long(ip);

    var i = 0;
    // header index handler
    if (headerSip == null) {
        fs.readSync(this.db_fd, headerIndexBuffer, 0, totalHeaderLength, 8);
        headerSip = new Array();
        headerPtr = new Array();

        var startIp = 0;
        var dataPtr = 0;
        for ( i = 0; i < totalHeaderLength; i += 8) {
            startIp = getLong(headerIndexBuffer, i);
            dataPtr = getLong(headerIndexBuffer, i + 4);
            if ( dataPtr == 0) break;

            headerSip.push(startIp);
            headerPtr.push(dataPtr);
            headerLen++; // header index size count
        }
    }

    // first search  (in header index)
    var low  = 0;
    var mid  = 0;
    var high = headerLen;
    var sptr = 0;
    var eptr = 0;

    while(low <= high) {
        mid = ((low + high) >> 1);

        if (ip == headerSip[mid]) {
            if ( mid > 0) {
                sptr = headerPtr[mid - 1];
                eptr = headerPtr[mid];
            } else {
                sptr = headerPtr[mid];
                eptr = headerPtr[mid + 1];
            }
            break;
        }

        if ( ip < headerSip[mid]) {
            if (mid == 0) {
                sptr = headerPtr[mid];
                eptr = headerPtr[mid + 1];
                break;
            } else if ( ip > headerSip[mid - 1]) {
                sptr = headerPtr[mid - 1];
                eptr = headerPtr[mid];
                break;
            }
            high = mid - 1;
        } else {
            if ( mid == headerLen - 1) {
                sptr = headerPtr[mid - 1];
                eptr = headerPtr[mid];
                break;
            } else if ( ip <= headerSip[mid + 1]) {
                sptr = headerPtr[mid];
                eptr = headerPtr[mid + 1];
                break;
            }
            low = mid + 1;
        }
    }

    // match nothing
    if (sptr == 0) return null;

    // second search (in index)
    var blockLen    = eptr - sptr;
    var blockBuffer = new Buffer(blockLen + indexBlockLength);
    fs.readSync(this.db_fd, blockBuffer, 0, blockLen + indexBlockLength, sptr);

    low = 0;
    high = blockLen / indexBlockLength;

    var p = 0;
    var sip = 0;
    var eip = 0;
    var dataPtr = 0;

    while(low <= high) {
        mid = ((low + high) >> 1);
        p = mid * indexBlockLength;
        sip = getLong(blockBuffer, p);

        if (ip < sip) {
            high = mid - 1;
        } else {
            eip = getLong(blockBuffer, p + 4);
            if (ip > eip) {
                low = mid + 1;
            } else {
                dataPtr =  getLong(blockBuffer, p + 8);
                break;
            }
        }
    }

    // read data
    if (dataPtr == 0) return null;
    var dataLen = ((dataPtr >> 24) & 0xFF);
    var dataPtr = (dataPtr & 0x00FFFFFF);
    var dataBuffer = new Buffer(dataLen);

    fs.readSync(this.db_fd, dataBuffer, 0, dataLen, dataPtr);

    var city_id = getLong(dataBuffer, 0);
    var data    = dataBuffer.toString('utf8', 4, dataLen);

    //console.log(city_id);
    //console.log(data);

    return { city: city_id, region: data };
}

/**
 * convert ip to long (xxx.xxx.xxx.xxx to a integer)
 * */
function ip2long(ip)
{
    var val = 0;
    ip.split('.').forEach(function(ele, i){
        val += ipbase[i] * ele;
    });

    return val;
}

/**
 * get long value from buffer with specified offset
 * */
function getLong(buffer, offset)
{
    var val =  (
        (buffer[offset] & 0x000000FF) |
        ((buffer[offset + 1] <<  8) & 0x0000FF00) |
        ((buffer[offset + 2] << 16) & 0x00FF0000) |
        ((buffer[offset + 3] << 24) & 0xFF000000)
    );

    // convert to unsigned int
    if (val < 0) {
        val = val >>> 0;
    }
    return val;
}

exports.create = function(db_path)
{
    if (typeof(db_path) == "undefined" || fs.exists(db_path) ) {
        throw("[ip2region] db file not exists : " + db_path);
    }

    ip2region.db_file_path = db_path;

    try {
        ip2region.db_fd = fs.openSync(ip2region.db_file_path, 'r');
    } catch(e) {
        throw("[ip2region] Can not open ip2region.db file , path : "
                + ip2region.db_file_path);
    }

    // init basic search environment
    if (totalBlocks == 0) {
        fs.readSync(ip2region.db_fd, superBlock, 0, 8, 0);
        firstIndexPtr = getLong(superBlock, 0);
        lastIndexPtr  = getLong(superBlock, 4);
        totalBlocks   = (lastIndexPtr - firstIndexPtr)
                            / indexBlockLength + 1;
    }

    return ip2region;
}

exports.destroy = function(ip2rObj)
{
    ip2rObj.db_file_path = null;
    fs.closeSync(ip2rObj.db_fd);
}
<|endoftext|>


<commit_before>// remap jQuery to $
(function($){})(window.jQuery);

var filtered_events = [];
var filtered_events_count = 0;
var global_events = {items: [
  { value: 1, name: "testing" }
]};

function capitaliseFirstLetter(string) {
  var newStr = '';
  var splitStr = string.split(' ');
  for (var word in splitStr) {
    newStr += splitStr[word].charAt(0).toUpperCase() + splitStr[word].slice(1) + ' ';
  }
  return newStr;
}

function sortEvents(a,b) {
  return a - b;
}

function fetchAlerts() {
  $.getJSON('/events.json', function(data) {
    m_events = new Array();

    $('table#alerts > tbody').empty();

    for (var nodekey in data) {
      global_events['items'].push({value: nodekey, name: nodekey});
      if ((filtered_events_count > 0) && ($.inArray(nodekey, filtered_events) == -1)) {
      } else {
        var node = data[nodekey];

        for (var a in node) {
          var dataObject = {
            client: nodekey,
            check: a,
            status: node[a]['status'],
            output: node[a]['output'],
            occurrences: node[a]['occurrences']
          };

          if (m_events[node[a]['status']] == null) {
            m_events[node[a]['status']] = new Array();
          }

          m_events[node[a]['status']][nodekey+a] = dataObject;
        }
      }
    }

    for (status in m_events) {
      for (a in m_events[status]) {
        var m_event = m_events[status][a];
        var ccheck = m_event['client'] + m_event['check'];

        $('#eventTemplate').tmpl(m_event).prependTo('table#alerts > tbody');

        $('tr#' + ccheck).click(function() {
          $('div#event_details_modal > div#event_data').empty();
          $('div#event_details_modal > div#client_data').empty();
          var selectedStatus = $(this).children('td#status').html();
          var selectedNodeKey = $(this).attr('id');
          var selectedEvent = m_events[selectedStatus][selectedNodeKey];
          $('#eventDetailsRowTemplate').tmpl(selectedEvent).appendTo('div#event_details_modal > div#event_data');

          var client_alert_img = $("#disable_client_alerts").children().first();
          $.ajax({
            url: '/stash/silence/'+selectedEvent['client']+'.json',
            success: function(data, textStatus, xhr) {
              if(xhr.status == 200) {
                client_alert_img.attr("src", "/img/megaphone_icon_off.png");
              }
            },
            error: function(xhr, textStatus, errorThrown) {
              if(xhr.status == 404) {
                client_alert_img.attr("src", "/img/megaphone_icon.png");
              }
            }});

          var event_alert_img = $("#disable_client_check_alerts").children().first();
          $.ajax({
            url: '/stash/silence/'+selectedEvent['client']+'/'+selectedEvent['check']+'.json',
            success: function(data, textStatus, xhr) {
              if(xhr.status == 200) {
                event_alert_img.attr("src", "/img/megaphone_icon_off.png");
              }
            },
            error: function(xhr, textStatus, errorThrown) {
              if(xhr.status == 404) {
                event_alert_img.attr("src", "/img/megaphone_icon.png");
              }
            }});

          $.getJSON('/client/'+selectedEvent['client']+'.json', function(data) {
            var client = data;
            client['subscriptions'] = client['subscriptions'].join(', ');
            $('#clientDetailsRowTemplate').tmpl(client).appendTo('div#event_details_modal > div#client_data');
            $('div#event_details_modal > div#client_data > h1').click(function() {
              $(this).select();
            });
          });
        });
      }
    }

    $('tr[rel*=leanModal]').leanModal({ top : 50, bottom : 50 });

    var row_count = $('table#alerts > tbody > tr').length;
    $('span#alert_count').html(row_count);

    addTableSorting();
  });
}

function fetchClients() {
  $.getJSON('/clients.json', function(data) {

    m_clients = new Array();

    $('table#clients > tbody').empty();

    for (var clientkey in data) {
      var client = data[clientkey];
      client['subscriptions'] = client['subscriptions'].join(', ');
      m_clients.push(client);
    }

    $('#clientTemplate').tmpl(m_clients).prependTo('table#clients > tbody');

    $('tbody > tr').click(function() {
      $('div#event_details_modal > div#client_data').empty();

      var client_id = $(this).children('td#client_id').html();

      $.getJSON('/client/'+client_id+'.json', function(clientdata) {
        $('#clientDetailsRowTemplate').tmpl(clientdata).appendTo('div#event_details_modal > div#client_data');
      });
    });

    $('tr[rel*=leanModal]').leanModal({ top : 50, bottom : 50 });
    var row_count = $('table#clients > tbody > tr').length;
    $('span#client_count').html(row_count);

    addTableSorting();
  });
}

function addTableSorting() {
  var table = $('table');

  $('table > thead > tr > td').each(function() {
    var td = $(this),
      tdIndex = td.index(),
      inverse = false;

    td.click(function() {
      table.find('tbody').find('td').filter(function() {
        return $(this).index() === tdIndex;
      }).sortElements(function(a, b) {
        return $.text([a]) > $.text([b]) ?
          inverse ? -1 : 1
          : inverse ? 1 : -1
      }, function() {
        return this.parentNode;
      });
      inverse = !inverse;
    });
  });
}

function filterEvents() {
  var values = $("input[type=hidden]").val().split(",");
  filtered_events = [];
  filtered_events_count = 0;

  for(value in values) {
    if(values[value] != "") {
      filtered_events_count++;
      filtered_events.push(values[value]);
    }
  }

  fetchAlerts();
}

/* trigger when page is ready */
$(document).ready(function() {

  $("input[type=text]").autoSuggest("http://127.0.0.1:8080/events_clients.json", {
    startText: "Enter keywords to filter by",
    selectedItemProp: "name",
    searchObjProps: "name",
    selectionAdded: function(elem) {
      filterEvents();
    },
    selectionRemoved: function(elem) {
      elem.fadeTo("fast", 0, function() { elem.remove(); });
      filterEvents();
    }
  });

  // TODO: fix clipboard support
  /*$('div#event_details_modal > div.alert_detail_group > div.copy').click(function() {
    var currentVal = $(this).parent().find('div.alert_detail').children().last().text();

    $(this).zclip({
      path:'swf/ZeroClipboard.swf',
      copy:currentVal
    });
  });*/

});

/* optional triggers

$(window).load(function() {

});

$(window).resize(function() {

});

*/
<commit_msg>[autocomplete-fixes] dashboard can run on any port on any host<commit_after>// remap jQuery to $
(function($){})(window.jQuery);

var filtered_events = [];
var filtered_events_count = 0;
var global_events = {items: [
  { value: 1, name: "testing" }
]};

function capitaliseFirstLetter(string) {
  var newStr = '';
  var splitStr = string.split(' ');
  for (var word in splitStr) {
    newStr += splitStr[word].charAt(0).toUpperCase() + splitStr[word].slice(1) + ' ';
  }
  return newStr;
}

function sortEvents(a,b) {
  return a - b;
}

function fetchAlerts() {
  $.getJSON('/events.json', function(data) {
    m_events = new Array();

    $('table#alerts > tbody').empty();

    for (var nodekey in data) {
      global_events['items'].push({value: nodekey, name: nodekey});
      if ((filtered_events_count > 0) && ($.inArray(nodekey, filtered_events) == -1)) {
      } else {
        var node = data[nodekey];

        for (var a in node) {
          var dataObject = {
            client: nodekey,
            check: a,
            status: node[a]['status'],
            output: node[a]['output'],
            occurrences: node[a]['occurrences']
          };

          if (m_events[node[a]['status']] == null) {
            m_events[node[a]['status']] = new Array();
          }

          m_events[node[a]['status']][nodekey+a] = dataObject;
        }
      }
    }

    for (status in m_events) {
      for (a in m_events[status]) {
        var m_event = m_events[status][a];
        var ccheck = m_event['client'] + m_event['check'];

        $('#eventTemplate').tmpl(m_event).prependTo('table#alerts > tbody');

        $('tr#' + ccheck).click(function() {
          $('div#event_details_modal > div#event_data').empty();
          $('div#event_details_modal > div#client_data').empty();
          var selectedStatus = $(this).children('td#status').html();
          var selectedNodeKey = $(this).attr('id');
          var selectedEvent = m_events[selectedStatus][selectedNodeKey];
          $('#eventDetailsRowTemplate').tmpl(selectedEvent).appendTo('div#event_details_modal > div#event_data');

          var client_alert_img = $("#disable_client_alerts").children().first();
          $.ajax({
            url: '/stash/silence/'+selectedEvent['client']+'.json',
            success: function(data, textStatus, xhr) {
              if(xhr.status == 200) {
                client_alert_img.attr("src", "/img/megaphone_icon_off.png");
              }
            },
            error: function(xhr, textStatus, errorThrown) {
              if(xhr.status == 404) {
                client_alert_img.attr("src", "/img/megaphone_icon.png");
              }
            }});

          var event_alert_img = $("#disable_client_check_alerts").children().first();
          $.ajax({
            url: '/stash/silence/'+selectedEvent['client']+'/'+selectedEvent['check']+'.json',
            success: function(data, textStatus, xhr) {
              if(xhr.status == 200) {
                event_alert_img.attr("src", "/img/megaphone_icon_off.png");
              }
            },
            error: function(xhr, textStatus, errorThrown) {
              if(xhr.status == 404) {
                event_alert_img.attr("src", "/img/megaphone_icon.png");
              }
            }});

          $.getJSON('/client/'+selectedEvent['client']+'.json', function(data) {
            var client = data;
            client['subscriptions'] = client['subscriptions'].join(', ');
            $('#clientDetailsRowTemplate').tmpl(client).appendTo('div#event_details_modal > div#client_data');
            $('div#event_details_modal > div#client_data > h1').click(function() {
              $(this).select();
            });
          });
        });
      }
    }

    $('tr[rel*=leanModal]').leanModal({ top : 50, bottom : 50 });

    var row_count = $('table#alerts > tbody > tr').length;
    $('span#alert_count').html(row_count);

    addTableSorting();
  });
}

function fetchClients() {
  $.getJSON('/clients.json', function(data) {

    m_clients = new Array();

    $('table#clients > tbody').empty();

    for (var clientkey in data) {
      var client = data[clientkey];
      client['subscriptions'] = client['subscriptions'].join(', ');
      m_clients.push(client);
    }

    $('#clientTemplate').tmpl(m_clients).prependTo('table#clients > tbody');

    $('tbody > tr').click(function() {
      $('div#event_details_modal > div#client_data').empty();

      var client_id = $(this).children('td#client_id').html();

      $.getJSON('/client/'+client_id+'.json', function(clientdata) {
        $('#clientDetailsRowTemplate').tmpl(clientdata).appendTo('div#event_details_modal > div#client_data');
      });
    });

    $('tr[rel*=leanModal]').leanModal({ top : 50, bottom : 50 });
    var row_count = $('table#clients > tbody > tr').length;
    $('span#client_count').html(row_count);

    addTableSorting();
  });
}

function addTableSorting() {
  var table = $('table');

  $('table > thead > tr > td').each(function() {
    var td = $(this),
      tdIndex = td.index(),
      inverse = false;

    td.click(function() {
      table.find('tbody').find('td').filter(function() {
        return $(this).index() === tdIndex;
      }).sortElements(function(a, b) {
        return $.text([a]) > $.text([b]) ?
          inverse ? -1 : 1
          : inverse ? 1 : -1
      }, function() {
        return this.parentNode;
      });
      inverse = !inverse;
    });
  });
}

function filterEvents() {
  var values = $("input[type=hidden]").val().split(",");
  filtered_events = [];
  filtered_events_count = 0;

  for(value in values) {
    if(values[value] != "") {
      filtered_events_count++;
      filtered_events.push(values[value]);
    }
  }

  fetchAlerts();
}

/* trigger when page is ready */
$(document).ready(function() {

  $("input[type=text]").autoSuggest("http://" + location.hostname + ":" + location.port + "/events_clients.json", {
    startText: "Enter keywords to filter by",
    selectedItemProp: "name",
    searchObjProps: "name",
    selectionAdded: function(elem) {
      filterEvents();
    },
    selectionRemoved: function(elem) {
      elem.fadeTo("fast", 0, function() { elem.remove(); });
      filterEvents();
    }
  });

  // TODO: fix clipboard support
  /*$('div#event_details_modal > div.alert_detail_group > div.copy').click(function() {
    var currentVal = $(this).parent().find('div.alert_detail').children().last().text();

    $(this).zclip({
      path:'swf/ZeroClipboard.swf',
      copy:currentVal
    });
  });*/

});

/* optional triggers

$(window).load(function() {

});

$(window).resize(function() {

});

*/
<|endoftext|>


<commit_before>var m = require('mithril');
var classSet = require('chessground').util.classSet;
var titleNameToId = require('../util').titleNameToId;
var inviteFormCtrl = require('./inviteForm').ctrl;
var partial = require('chessground').util.partial;

function memberActivity(onIdle) {
  var timeout;
  var schedule = function() {
    if (timeout) clearTimeout(timeout);
    timeout = setTimeout(onIdle, 100);
  };
  schedule();
  return schedule;
};

module.exports = {
  ctrl: function(initDict, myId, ownerId, send, setTab, startTour, notif) {

    var dict = m.prop(initDict);
    var confing = m.prop(null); // which user is being configured by us
    var active = {}; // recently active contributors
    var online = {}; // userId -> bool
    var spectatorIds = [];

    var owner = function() {
      return dict()[ownerId];
    };

    var isOwner = function() {
      return myId === ownerId;
    };

    var myMember = function() {
      return myId ? dict()[myId] : null;
    };

    var canContribute = function() {
      return (myMember() || {}).role === 'w';
    };

    var inviteForm = inviteFormCtrl(send, dict, setTab);

    var setActive = function(id) {
      if (active[id]) active[id]();
      else active[id] = memberActivity(function() {
        delete(active[id]);
        m.redraw();
      });
      m.redraw();
    };

    var updateOnline = function() {
      online = {};
      var members = dict();
      spectatorIds.forEach(function(id) {
        if (members[id]) online[id] = true;
      });
      m.redraw();
    }

    return {
      dict: dict,
      confing: confing,
      myId: myId,
      inviteForm: inviteForm,
      update: function(members) {
        if (isOwner) confing(Object.keys(members).filter(function(uid) {
          return !dict()[uid];
        })[0]);
        var wasViewer = myMember() && !canContribute();
        var wasContrib = myMember() && canContribute();
        dict(members);
        if (wasViewer && canContribute()) {
          if (lichess.once('study-tour')) startTour();
          notif.set({
            text: 'You are now a contributor',
            duration: 3000
          });
        } else if (wasContrib && !canContribute()) notif.set({
          text: 'You are now a spectator',
          duration: 3000
        });
        updateOnline();
      },
      setActive: setActive,
      isActive: function(id) {
        return !!active[id];
      },
      owner: owner,
      myMember: myMember,
      isOwner: isOwner,
      canContribute: canContribute,
      setRole: function(id, role) {
        setActive(id);
        send("setRole", {
          userId: id,
          role: role
        });
        confing(null);
      },
      kick: function(id) {
        send("kick", id);
        confing(null);
      },
      ordered: function() {
        return Object.keys(dict()).map(function(id) {
          return dict()[id];
        }).sort(function(a, b) {
          if (a.role === 'r' && b.role === 'w') return 1;
          if (a.role === 'w' && b.role === 'r') return -1;
          return a.addedAt > b.addedAt;
        });
      },
      setSpectators: function(usernames) {
        this.inviteForm.setSpectators(usernames);
        spectatorIds = usernames.map(titleNameToId);
        updateOnline();
      },
      isOnline: function(userId) {
        return online[userId];
      },
      titleNameToId: titleNameToId
    };
  },
  view: function(ctrl) {

    var username = function(member) {
      var u = member.user;
      return m('span.user_link.ulpt', {
        'data-href': '/@/' + u.name
      }, (u.title ? u.title + ' ' : '') + u.name);
    };

    var statusIcon = function(member) {
      var contrib = member.role === 'w';
      return m('span', {
        class: classSet({
          contrib: contrib,
          active: ctrl.members.isActive(member.user.id),
          online: ctrl.members.isOnline(member.user.id),
          status: true
        }),
        title: contrib ? 'Contributor' : 'Viewer',
      }, m('i', {
        'data-icon': contrib ? '' : 'v'
      }));
    };

    var configButton = function(member, confing) {
      if (!ctrl.members.isOwner() || member.user.id === ctrl.members.myId) return null;
      return m('span.action.config', {
        onclick: function() {
          ctrl.members.confing(confing ? null : member.user.id);
        }
      }, m('i', {
        'data-icon': '%'
      }));
    };

    var memberConfig = function(member) {
      return m('div.config', {
        key: member.user.id + '-config',
        config: function(el, isUpdate) {
          if (!isUpdate) $(el).parent('.members').scrollTo(el, 200);
        }
      }, [
        (function(id) {
          return m('div.role', [
            m('div.switch', [
              m('input', {
                id: id,
                class: 'cmn-toggle cmn-toggle-round',
                type: 'checkbox',
                checked: member.role === 'w',
                onchange: function(e) {
                  ctrl.members.setRole(member.user.id, e.target.checked ? 'w' : 'r');
                }
              }),
              m('label', {
                'for': id
              })
            ]),
            m('label', {
              'for': id
            }, 'Contributor')
          ]);
        })('member-role'),
        m('div.kick', m('a.button.text[data-icon=L]', {
          onclick: partial(ctrl.members.kick, member.user.id)
        }, 'Kick from this study'))
      ]);
    };

    return [
      m('div', {
        key: 'members',
        class: 'list members',
        config: function() {
          $('body').trigger('lichess.content_loaded');
        }
      }, ctrl.members.ordered().map(function(member) {
        var confing = ctrl.members.confing() === member.user.id;
        var attrs = {
          key: member.user.id,
          class: classSet({
            elem: true,
            member: true,
            editing: confing
          })
        };
        return [
          m('div', attrs, [
            m('div.left', [
              statusIcon(member),
              username(member)
            ]),
            configButton(member, confing)
          ]),
          confing ? memberConfig(member) : null
        ];
      })),
      ctrl.members.isOwner() ? m('i.add[data-icon=0]', {
        title: 'Invite someone',
        'data-icon': 'O',
        onclick: ctrl.members.inviteForm.toggle
      }) : null
    ];
  }
};
<commit_msg>study UI bug<commit_after>var m = require('mithril');
var classSet = require('chessground').util.classSet;
var titleNameToId = require('../util').titleNameToId;
var inviteFormCtrl = require('./inviteForm').ctrl;
var partial = require('chessground').util.partial;

function memberActivity(onIdle) {
  var timeout;
  var schedule = function() {
    if (timeout) clearTimeout(timeout);
    timeout = setTimeout(onIdle, 100);
  };
  schedule();
  return schedule;
};

module.exports = {
  ctrl: function(initDict, myId, ownerId, send, setTab, startTour, notif) {

    var dict = m.prop(initDict);
    var confing = m.prop(null); // which user is being configured by us
    var active = {}; // recently active contributors
    var online = {}; // userId -> bool
    var spectatorIds = [];

    var owner = function() {
      return dict()[ownerId];
    };

    var isOwner = function() {
      return myId === ownerId;
    };

    var myMember = function() {
      return myId ? dict()[myId] : null;
    };

    var canContribute = function() {
      return (myMember() || {}).role === 'w';
    };

    var inviteForm = inviteFormCtrl(send, dict, setTab);

    var setActive = function(id) {
      if (active[id]) active[id]();
      else active[id] = memberActivity(function() {
        delete(active[id]);
        m.redraw();
      });
      m.redraw();
    };

    var updateOnline = function() {
      online = {};
      var members = dict();
      spectatorIds.forEach(function(id) {
        if (members[id]) online[id] = true;
      });
      m.redraw();
    }

    return {
      dict: dict,
      confing: confing,
      myId: myId,
      inviteForm: inviteForm,
      update: function(members) {
        if (isOwner()) confing(Object.keys(members).filter(function(uid) {
          return !dict()[uid];
        })[0]);
        var wasViewer = myMember() && !canContribute();
        var wasContrib = myMember() && canContribute();
        dict(members);
        if (wasViewer && canContribute()) {
          if (lichess.once('study-tour')) startTour();
          notif.set({
            text: 'You are now a contributor',
            duration: 3000
          });
        } else if (wasContrib && !canContribute()) notif.set({
          text: 'You are now a spectator',
          duration: 3000
        });
        updateOnline();
      },
      setActive: setActive,
      isActive: function(id) {
        return !!active[id];
      },
      owner: owner,
      myMember: myMember,
      isOwner: isOwner,
      canContribute: canContribute,
      setRole: function(id, role) {
        setActive(id);
        send("setRole", {
          userId: id,
          role: role
        });
        confing(null);
      },
      kick: function(id) {
        send("kick", id);
        confing(null);
      },
      ordered: function() {
        return Object.keys(dict()).map(function(id) {
          return dict()[id];
        }).sort(function(a, b) {
          if (a.role === 'r' && b.role === 'w') return 1;
          if (a.role === 'w' && b.role === 'r') return -1;
          return a.addedAt > b.addedAt;
        });
      },
      setSpectators: function(usernames) {
        this.inviteForm.setSpectators(usernames);
        spectatorIds = usernames.map(titleNameToId);
        updateOnline();
      },
      isOnline: function(userId) {
        return online[userId];
      },
      titleNameToId: titleNameToId
    };
  },
  view: function(ctrl) {

    var username = function(member) {
      var u = member.user;
      return m('span.user_link.ulpt', {
        'data-href': '/@/' + u.name
      }, (u.title ? u.title + ' ' : '') + u.name);
    };

    var statusIcon = function(member) {
      var contrib = member.role === 'w';
      return m('span', {
        class: classSet({
          contrib: contrib,
          active: ctrl.members.isActive(member.user.id),
          online: ctrl.members.isOnline(member.user.id),
          status: true
        }),
        title: contrib ? 'Contributor' : 'Viewer',
      }, m('i', {
        'data-icon': contrib ? '' : 'v'
      }));
    };

    var configButton = function(member, confing) {
      if (!ctrl.members.isOwner() || member.user.id === ctrl.members.myId) return null;
      return m('span.action.config', {
        onclick: function() {
          ctrl.members.confing(confing ? null : member.user.id);
        }
      }, m('i', {
        'data-icon': '%'
      }));
    };

    var memberConfig = function(member) {
      return m('div.config', {
        key: member.user.id + '-config',
        config: function(el, isUpdate) {
          if (!isUpdate) $(el).parent('.members').scrollTo(el, 200);
        }
      }, [
        (function(id) {
          return m('div.role', [
            m('div.switch', [
              m('input', {
                id: id,
                class: 'cmn-toggle cmn-toggle-round',
                type: 'checkbox',
                checked: member.role === 'w',
                onchange: function(e) {
                  ctrl.members.setRole(member.user.id, e.target.checked ? 'w' : 'r');
                }
              }),
              m('label', {
                'for': id
              })
            ]),
            m('label', {
              'for': id
            }, 'Contributor')
          ]);
        })('member-role'),
        m('div.kick', m('a.button.text[data-icon=L]', {
          onclick: partial(ctrl.members.kick, member.user.id)
        }, 'Kick from this study'))
      ]);
    };

    return [
      m('div', {
        key: 'members',
        class: 'list members',
        config: function() {
          $('body').trigger('lichess.content_loaded');
        }
      }, ctrl.members.ordered().map(function(member) {
        var confing = ctrl.members.confing() === member.user.id;
        var attrs = {
          key: member.user.id,
          class: classSet({
            elem: true,
            member: true,
            editing: confing
          })
        };
        return [
          m('div', attrs, [
            m('div.left', [
              statusIcon(member),
              username(member)
            ]),
            configButton(member, confing)
          ]),
          confing ? memberConfig(member) : null
        ];
      })),
      ctrl.members.isOwner() ? m('i.add[data-icon=0]', {
        title: 'Invite someone',
        'data-icon': 'O',
        onclick: ctrl.members.inviteForm.toggle
      }) : null
    ];
  }
};
<|endoftext|>


<commit_before>// utility to process `require('./file')` and build bundled files of client tree
//

'use strict';

// stdlib
var fs    = require('fs');
var path  = require('path');

// 3rd-party
var ejs           = require('ejs');
var findRequires  = require('find-requires');

////////////////////////////////////////////////////////////////////////////////

var TEMPLATE = fs.readFileSync(__dirname + '/template/requisite.js.ejs', 'utf8');

////////////////////////////////////////////////////////////////////////////////

function Requisite() {
  this.requires = {};
  this.idx      = 1;
}

Requisite.prototype.process = function (source, pathname) {
  var base = path.dirname(pathname.toString());

  findRequires(source, { raw: true }).forEach(function (info) {
    var requiredPath = info.value;

    if (!requiredPath) {
      throw new Error("Can't resolve required path " + JSON.stringify(info.raw) +
                      " in " + pathname + ":" + info.line);
    }

    try {
      // resolve as node module into absolute path
      requiredPath = require.resolve(requiredPath);
    } catch (e) {
      // do nothing
    }

    try {
      // resolve path relatively to pathname (it will not affect absolute paths)
      // if it was resolved as node module path
      requiredPath = require.resolve(path.resolve(base, requiredPath));
    } catch (err) {
      throw new Error("Can't resolve required path " + JSON.stringify(info.raw) +
                      " in " + pathname + ":" + info.line);
    }

    if (undefined === this.requires[requiredPath]) {
      // prevent from "cyclic" loops
      this.requires[requiredPath] = {
        idx:      this.idx++,
        apiPath:  pathname.apiPath,
        source:   null
      };

      this.requires[requiredPath].source =
        this.process(fs.readFileSync(requiredPath, 'utf8'), requiredPath);
    }

    source = source.replace(info.value, this.requires[requiredPath].idx);
  }, this);

  return source;
};

Requisite.prototype.bundle = function () {
  return ejs.render(TEMPLATE, this);
};

////////////////////////////////////////////////////////////////////////////////

module.exports = Requisite;
<commit_msg>Fix path resolving<commit_after>// utility to process `require('./file')` and build bundled files of client tree
//

'use strict';

// stdlib
var fs    = require('fs');
var path  = require('path');

// 3rd-party
var ejs           = require('ejs');
var findRequires  = require('find-requires');

////////////////////////////////////////////////////////////////////////////////

var TEMPLATE = fs.readFileSync(__dirname + '/template/requisite.js.ejs', 'utf8');

////////////////////////////////////////////////////////////////////////////////

function Requisite() {
  this.requires = {};
  this.idx      = 1;
}

Requisite.prototype.process = function (source, pathname) {
  var base = path.dirname(pathname.toString());

  findRequires(source, { raw: true }).forEach(function (info) {
    var requiredPath = info.value;

    if (!requiredPath) {
      throw new Error("Can't resolve required path " + JSON.stringify(info.raw) +
                      " in " + pathname + ":" + info.line);
    }

    try {
      if ('.' === requiredPath[0]) {
        // resolve relative pathname (prepend basepath)
        requiredPath = path.resolve(base, requiredPath);
      }

      requiredPath = require.resolve(requiredPath);
    } catch (err) {
      throw new Error("Can't resolve required path " + JSON.stringify(info.raw) +
                      " in " + pathname + ":" + info.line);
    }

    if (undefined === this.requires[requiredPath]) {
      // prevent from "cyclic" loops
      this.requires[requiredPath] = {
        idx:      this.idx++,
        apiPath:  pathname.apiPath,
        source:   null
      };

      this.requires[requiredPath].source =
        this.process(fs.readFileSync(requiredPath, 'utf8'), requiredPath);
    }

    source = source.replace(info.value, this.requires[requiredPath].idx);
  }, this);

  return source;
};

Requisite.prototype.bundle = function () {
  return ejs.render(TEMPLATE, this);
};

////////////////////////////////////////////////////////////////////////////////

module.exports = Requisite;
<|endoftext|>