<commit_before>
angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services',
  'cesium.settings.services', 'cesium.wot.services' ])

.factory('csTx', function($q, $timeout, $filter, $translate, FileSaver, UIUtils, BMA, Api,
                          csConfig, csSettings, csWot, csCurrency) {
  'ngInject';

  var
    api = new Api(this, "csTx");

  function reduceTxAndPush(pubkey, txArray, result, processedTxMap, allowPendings) {
    if (!txArray || !txArray.length) return; // Skip if empty

    _.forEach(txArray, function(tx) {
      if (tx.block_number !== null || allowPendings) {
        var walletIsIssuer = false;
        var otherIssuers = tx.issuers.reduce(function(res, issuer) {
          walletIsIssuer = walletIsIssuer || (issuer === pubkey);
          return (issuer !== pubkey) ? res.concat(issuer) : res;
        }, []);
        var otherRecipients = [],
          outputBase,
          sources = [],
          lockedOutputs;

        var amount = tx.outputs.reduce(function(sum, output, noffset) {
          // FIXME duniter v1.4.13
          var outputArray = (typeof output === 'string') ? output.split(':',3) : [output.amount,output.base,output.conditions];
          outputBase = parseInt(outputArray[1]);
          var outputAmount = powBase(parseInt(outputArray[0]), outputBase);
          var outputCondition = outputArray[2];
          var sigMatches =  BMA.regexp.TX_OUTPUT_SIG.exec(outputCondition);

          // Simple unlock condition
          if (sigMatches) {
            var outputPubkey = sigMatches[1];
            if (outputPubkey === pubkey) { // output is for the wallet
              if (!walletIsIssuer) {
                return sum + outputAmount;
              }
              // If pending: use output as new sources
              else if (tx.block_number === null) {
                sources.push({
                  amount: parseInt(outputArray[0]),
                  base: outputBase,
                  type: 'T',
                  identifier: tx.hash,
                  noffset: noffset,
                  consumed: false,
                  conditions: outputCondition
                });
              }
            }

            // The output is for someone else
            else {
              // Add into recipients list(if not a issuer)
              if (outputPubkey !== '' && !_.contains(otherIssuers, outputPubkey)) {
                otherRecipients.push(outputPubkey);
              }
              if (walletIsIssuer) {
                // TODO: should be fix, when TX has multiple issuers (need a repartition)
                return sum - outputAmount;
              }
            }
          }

          // Complex unlock condition, on the issuer pubkey
          else if (outputCondition.indexOf('SIG('+pubkey+')') !== -1) {
            var lockedOutput = BMA.tx.parseUnlockCondition(outputCondition);
            if (lockedOutput) {
              // Add a source
              sources.push(angular.merge({
                amount: parseInt(outputArray[0]),
                base: outputBase,
                type: 'T',
                identifier: tx.hash,
                noffset: noffset,
                conditions: outputCondition,
                consumed: false
              }, lockedOutput));
              lockedOutput.amount = outputAmount;
              lockedOutputs = lockedOutputs || [];
              lockedOutputs.push(lockedOutput);
              console.debug('[tx] has locked output:', lockedOutput);

              return sum + outputAmount;
            }
          }
          return sum;
        }, 0);

        var txPubkeys = amount > 0 ? otherIssuers : otherRecipients;
        var time = tx.time || tx.blockstampTime;

        // Avoid duplicated tx, or tx to him self
        var txKey = amount + ':' + tx.hash + ':' + time;
        if (!processedTxMap[txKey]) {
          processedTxMap[txKey] = true; // Mark as processed
          var newTx = {
            time: time,
            amount: amount,
            pubkey: txPubkeys.length === 1 ? txPubkeys[0] : undefined,
            pubkeys: txPubkeys.length > 1 ? txPubkeys : undefined,
            comment: tx.comment,
            isUD: false,
            hash: tx.hash,
            locktime: tx.locktime,
            block_number: tx.block_number
          };

            // If pending: store sources and inputs for a later use - see method processTransactionsAndSources()<commit_msg>[fix] My Operations: Hide change operations (TX to himself) - fix #891<commit_after>
angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services',
  'cesium.settings.services', 'cesium.wot.services' ])

.factory('csTx', function($q, $timeout, $filter, $translate, FileSaver, UIUtils, BMA, Api,
                          csConfig, csSettings, csWot, csCurrency) {
  'ngInject';

  var
    api = new Api(this, "csTx");

  function reduceTxAndPush(pubkey, txArray, result, processedTxMap, allowPendings) {
    if (!txArray || !txArray.length) return; // Skip if empty

    _.forEach(txArray, function(tx) {
      if (tx.block_number !== null || allowPendings) {
        var walletIsIssuer = false;
        var otherIssuers = tx.issuers.reduce(function(res, issuer) {
          walletIsIssuer = walletIsIssuer || (issuer === pubkey);
          return (issuer !== pubkey) ? res.concat(issuer) : res;
        }, []);
        var otherRecipients = [],
          outputBase,
          sources = [],
          lockedOutputs;

        var amount = tx.outputs.reduce(function(sum, output, noffset) {
          // FIXME duniter v1.4.13
          var outputArray = (typeof output === 'string') ? output.split(':',3) : [output.amount,output.base,output.conditions];
          outputBase = parseInt(outputArray[1]);
          var outputAmount = powBase(parseInt(outputArray[0]), outputBase);
          var outputCondition = outputArray[2];
          var sigMatches =  BMA.regexp.TX_OUTPUT_SIG.exec(outputCondition);

          // Simple unlock condition
          if (sigMatches) {
            var outputPubkey = sigMatches[1];
            if (outputPubkey === pubkey) { // output is for the wallet
              if (!walletIsIssuer) {
                return sum + outputAmount;
              }
              // If pending: use output as new sources
              else if (tx.block_number === null) {
                sources.push({
                  amount: parseInt(outputArray[0]),
                  base: outputBase,
                  type: 'T',
                  identifier: tx.hash,
                  noffset: noffset,
                  consumed: false,
                  conditions: outputCondition
                });
              }
            }

            // The output is for someone else
            else {
              // Add into recipients list(if not a issuer)
              if (outputPubkey !== '' && !_.contains(otherIssuers, outputPubkey)) {
                otherRecipients.push(outputPubkey);
              }
              if (walletIsIssuer) {
                // TODO: should be fix, when TX has multiple issuers (need a repartition)
                return sum - outputAmount;
              }
            }

          }

          // Complex unlock condition, on the issuer pubkey
          else if (outputCondition.indexOf('SIG('+pubkey+')') !== -1) {
            var lockedOutput = BMA.tx.parseUnlockCondition(outputCondition);
            if (lockedOutput) {
              // Add a source
              sources.push(angular.merge({
                amount: parseInt(outputArray[0]),
                base: outputBase,
                type: 'T',
                identifier: tx.hash,
                noffset: noffset,
                conditions: outputCondition,
                consumed: false
              }, lockedOutput));
              lockedOutput.amount = outputAmount;
              lockedOutputs = lockedOutputs || [];
              lockedOutputs.push(lockedOutput);
              console.debug('[tx] has locked output:', lockedOutput);

              return sum + outputAmount;
            }
          }
          return sum;
        }, 0);

        var txPubkeys = amount > 0 ? otherIssuers : otherRecipients;
        var time = tx.time || tx.blockstampTime;

        // Avoid duplicated tx, or tx to him self
        var txKey = (amount !== 0) && amount + ':' + tx.hash + ':' + time;
        if (txKey && !processedTxMap[txKey]) {
          processedTxMap[txKey] = true; // Mark as processed
          var newTx = {
            time: time,
            amount: amount,
            pubkey: txPubkeys.length === 1 ? txPubkeys[0] : undefined,
            pubkeys: txPubkeys.length > 1 ? txPubkeys : undefined,
            comment: tx.comment,
            isUD: false,
            hash: tx.hash,
            locktime: tx.locktime,
            block_number: tx.block_number
          };

            // If pending: store sources and inputs for a later use - see method processTransactionsAndSources()
{'fraction_non_alphanumeric': 0.10980917308336123, 'fraction_numerical': 0.004240598147528178, 'mean_word_length': 1.6864508393285371, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2989831', 'n_tokens_mistral': 2433, 'n_tokens_neox': 2370, 'n_words': 602}