text: var Web3 = require("web3");
  var SolidityEvent = require("web3/lib/web3/event.js");
  
  (function() {
    // Planned for future features, logging, etc.
    function Provider(provider) {
      this.provider = provider;
    }
  
    Provider.prototype.send = function() {
      this.provider.send.apply(this.provider, arguments);
    };
  
    Provider.prototype.sendAsync = function() {
      this.provider.sendAsync.apply(this.provider, arguments);
    };
  
    var BigNumber = (new Web3()).toBigNumber(0).constructor;
  
    var Utils = {
      is_object: function(val) {
        return typeof val == "object" && !Array.isArray(val);
      },
      is_big_number: function(val) {
        if (typeof val != "object") return false;
  
        // Instanceof won't work because we have multiple versions of Web3.
        try {
          new BigNumber(val);
          return true;
        } catch (e) {
          return false;
        }
      },
      merge: function() {
        var merged = {};
        var args = Array.prototype.slice.call(arguments);
  
        for (var i = 0; i < args.length; i++) {
          var object = args[i];
          var keys = Object.keys(object);
          for (var j = 0; j < keys.length; j++) {
            var key = keys[j];
            var value = object[key];
            merged[key] = value;
          }
        }
  
        return merged;
      },
      promisifyFunction: function(fn, C) {
        var self = this;
        return function() {
          var instance = this;
  
          var args = Array.prototype.slice.call(arguments);
          var tx_params = {};
          var last_arg = args[args.length - 1];
  
          // It's only tx_params if it's an object and not a BigNumber.
          if (Utils.is_object(last_arg) && !Utils.is_big_number(last_arg)) {
            tx_params = args.pop();
          }
  
          tx_params = Utils.merge(C.class_defaults, tx_params);
  
          return new Promise(function(accept, reject) {
            var callback = function(error, result) {
              if (error != null) {
                reject(error);
              } else {
                accept(result);
              }
            };
            args.push(tx_params, callback);
            fn.apply(instance.contract, args);
          });
        };
      },
      synchronizeFunction: function(fn, instance, C) {
        var self = this;
        return function() {
          var args = Array.prototype.slice.call(arguments);
          var tx_params = {};
          var last_arg = args[args.length - 1];
  
          // It's only tx_params if it's an object and not a BigNumber.
          if (Utils.is_object(last_arg) && !Utils.is_big_number(last_arg)) {
            tx_params = args.pop();
          }
  
          tx_params = Utils.merge(C.class_defaults, tx_params);
  
          return new Promise(function(accept, reject) {
  
            var decodeLogs = function(logs) {
              return logs.map(function(log) {
                var logABI = C.events[log.topics[0]];
  
                if (logABI == null) {
                  return null;
                }
  
                var decoder = new SolidityEvent(null, logABI, instance.address);
                return decoder.decode(log);
              }).filter(function(log) {
                return log != null;
              });
            };
  
            var callback = function(error, tx) {
              if (error != null) {
                reject(error);
                return;
              }
  
              var timeout = C.synchronization_timeout || 240000;
              var start = new Date().getTime();
  
              var make_attempt = function() {
                C.web3.eth.getTransactionReceipt(tx, function(err, receipt) {
                  if (err) return reject(err);
  
                  if (receipt != null) {
                    // If they've opted into next gen, return more information.
                    if (C.next_gen == true) {
                      return accept({
                        tx: tx,
                        receipt: receipt,
                        logs: decodeLogs(receipt.logs)
                      });
                    } else {
                      return accept(tx);
                    }
                  }
  
                  if (timeout > 0 && new Date().getTime() - start > timeout) {
                    return reject(new Error("Transaction " + tx + " wasn't processed in " + (timeout / 1000) + " seconds!"));
                  }
  
                  setTimeout(make_attempt, 1000);
                });
              };
  
              make_attempt();
            };
  
            args.push(tx_params, callback);
            fn.apply(self, args);
          });
        };
      }
    };
  
    function instantiate(instance, contract) {
      instance.contract = contract;
      var constructor = instance.constructor;
  
      // Provision our functions.
      for (var i = 0; i < instance.abi.length; i++) {
        var item = instance.abi[i];
        if (item.type == "function") {
          if (item.constant == true) {
            instance[item.name] = Utils.promisifyFunction(contract[item.name], constructor);
          } else {
            instance[item.name] = Utils.synchronizeFunction(contract[item.name], instance, constructor);
          }
  
          instance[item.name].call = Utils.promisifyFunction(contract[item.name].call, constructor);
          instance[item.name].sendTransaction = Utils.promisifyFunction(contract[item.name].sendTransaction, constructor);
          instance[item.name].request = contract[item.name].request;
          instance[item.name].estimateGas = Utils.promisifyFunction(contract[item.name].estimateGas, constructor);
        }
  
        if (item.type == "event") {
          instance[item.name] = contract[item.name];
        }
      }
  
      instance.allEvents = contract.allEvents;
      instance.address = contract.address;
      instance.transactionHash = contract.transactionHash;
    };
  
    // Use inheritance to create a clone of this contract,
    // and copy over contract's static functions.
    function mutate(fn) {
      var temp = function Clone() { return fn.apply(this, arguments); };
  
      Object.keys(fn).forEach(function(key) {
        temp[key] = fn[key];
      });
  
      temp.prototype = Object.create(fn.prototype);
      bootstrap(temp);
      return temp;
    };
  
    function bootstrap(fn) {
      fn.web3 = new Web3();
      fn.class_defaults  = fn.prototype.defaults || {};
  
      // Set the network iniitally to make default data available and re-use code.
      // Then remove the saved network id so the network will be auto-detected on first use.
      fn.setNetwork("default");
      fn.network_id = null;
      return fn;
    };
  
    // Accepts a contract object created with web3.eth.contract.
    // Optionally, if called without `new`, accepts a network_id and will
    // create a new version of the contract abstraction with that network_id set.
    function Contract() {
      if (this instanceof Contract) {
        instantiate(this, arguments[0]);
      } else {
        var C = mutate(Contract);
        var network_id = arguments.length > 0 ? arguments[0] : "default";
        C.setNetwork(network_id);
        return C;
      }
    };
  
    Contract.currentProvider = null;
  
    Contract.setProvider = function(provider) {
      var wrapped = new Provider(provider);
      this.web3.setProvider(wrapped);
      this.currentProvider = provider;
    };
  
    Contract.new = function() {
      if (this.currentProvider == null) {
        throw new Error("localsService error: Please call setProvider() first before calling new().");
      }
  
      var args = Array.prototype.slice.call(arguments);
  
      if (!this.unlinked_binary) {
        throw new Error("localsService error: contract binary not set. Can't deploy new instance.");
      }
  
      var regex = /__[^_]+_+/g;
      var unlinked_libraries = this.binary.match(regex);
  
      if (unlinked_libraries != null) {
        unlinked_libraries = unlinked_libraries.map(function(name) {
          // Remove underscores
          return name.replace(/_/g, "");
        }).sort().filter(function(name, index, arr) {
          // Remove duplicates
          if (index + 1 >= arr.length) {
            return true;
          }
  
          return name != arr[index + 1];
        }).join(", ");
  
        throw new Error("localsService contains unresolved libraries. You must deploy and link the following libraries before you can deploy a new version of localsService: " + unlinked_libraries);
      }
  
      var self = this;
  
      return new Promise(function(accept, reject) {
        var contract_class = self.web3.eth.contract(self.abi);
        var tx_params = {};
        var last_arg = args[args.length - 1];
  
        // It's only tx_params if it's an object and not a BigNumber.
        if (Utils.is_object(last_arg) && !Utils.is_big_number(last_arg)) {
          tx_params = args.pop();
        }
  
        tx_params = Utils.merge(self.class_defaults, tx_params);
  
        if (tx_params.data == null) {
          tx_params.data = self.binary;
        }
  
        // web3 0.9.0 and above calls new twice this callback twice.
        // Why, I have no idea...
        var intermediary = function(err, web3_instance) {
          if (err != null) {
            reject(err);
            return;
          }
  
          if (err == null && web3_instance != null && web3_instance.address != null) {
            accept(new self(web3_instance));
          }
        };
  
        args.push(tx_params, intermediary);
        contract_class.new.apply(contract_class, args);
      });
    };
  
    Contract.at = function(address) {
      if (address == null || typeof address != "string" || address.length != 42) {
        throw new Error("Invalid address passed to localsService.at(): " + address);
      }
  
      var contract_class = this.web3.eth.contract(this.abi);
      var contract = contract_class.at(address);
  
      return new this(contract);
    };
  
    Contract.deployed = function() {
      if (!this.address) {
        throw new Error("Cannot find deployed address: localsService not deployed or address not set.");
      }
  
      return this.at(this.address);
    };
  
    Contract.defaults = function(class_defaults) {
      if (this.class_defaults == null) {
        this.class_defaults = {};
      }
  
      if (class_defaults == null) {
        class_defaults = {};
      }
  
      var self = this;
      Object.keys(class_defaults).forEach(function(key) {
        var value = class_defaults[key];
        self.class_defaults[key] = value;
      });
  
      return this.class_defaults;
    };
  
    Contract.extend = function() {
      var args = Array.prototype.slice.call(arguments);
  
      for (var i = 0; i < arguments.length; i++) {
        var object = arguments[i];
        var keys = Object.keys(object);
        for (var j = 0; j < keys.length; j++) {
          var key = keys[j];
          var value = object[key];
          this.prototype[key] = value;
        }
      }
    };
  
    Contract.all_networks = {
    "default": {
      "abi": [
        {
          "constant": false,
          "inputs": [
            {
              "name": "_name",
              "type": "string"
            },
            {
              "name": "_address",
              "type": "address"
            }
          ],
          "name": "register",
          "outputs": [],
          "type": "function"
        },
        {
          "constant": true,
          "inputs": [],
          "name": "owner",
          "outputs": [
            {
              "name": "",
              "type": "address"
            }
          ],
          "type": "function"
        },
        {
          "constant": true,
          "inputs": [
            {
              "name": "name",
              "type": "string"
            }
          ],
          "name": "addressOf",
          "outputs": [
            {
              "name": "addr",
              "type": "address"
            }
          ],
          "type": "function"
        },
        {
          "constant": false,
          "inputs": [
            {
              "name": "newOwner",
              "type": "address"
            }
          ],
          "name": "transferOwnership",
          "outputs": [],
          "type": "function"
        },
        {
          "constant": true,
          "inputs": [
            {
              "name": "addr",
              "type": "address"
            }
          ],
          "name": "nameOf",
          "outputs": [
            {
              "name": "name",
              "type": "string"
            }
          ],
          "type": "function"
        },
        {
          "inputs": [],
          "type": "constructor"
        }
      ],
      "unlinked_binary": "0x60008054600160a060020a0319163317815560a0604090815260046060527f626173650000000000000000000000000000000000000000000000000000000060805230600160a060020a03168252600160208181529183208054818552938390207f6261736500000000000000000000000000000000000000000000000000000008825590936100c093601f60026000199584161561010002959095019092169390930401919091048101905b8082111561011957600081556001016100ac565b5050604080517f626173650000000000000000000000000000000000000000000000000000000081526002600482015290519081900360240190208054600160a060020a031916301790556103d88061011d6000396000f35b509056606060405260e060020a60003504631e59c52981146100475780638da5cb5b14610107578063ccf1454a14610119578063f2fde38b146101ba578063f5c57382146101db575b005b6040805160206004803580820135601f81018490048402850184019095528484526100459491936024939092918401919081908401838280828437509496505093359350505050600160a060020a038116600090815260016020818152604083208551815482865294839020919460029481161561010002600019011693909304601f908101839004820193928701908390106102eb57805160ff19168380011785555b5061031b9291505b8082111561037b57600081556001016100f3565b610260600054600160a060020a031681565b6040805160206004803580820135601f81018490048402850184019095528484526102609491936024939092918401919081908401838280828437509496505050505050506000600260005082604051808280519060200190808383829060006004602084601f0104600302600f01f150905001915050908152602001604051809103902060009054906101000a9004600160a060020a031690505b919050565b61004560043560005433600160a060020a0390811691161461037f57610002565b60408051602081810183526000808352600160a060020a03600435908116825260018084529185902080548651600294821615610100026000190190911693909304601f810185900485028401850190965285835261027d959194939091908301828280156103cc5780601f106103a1576101008083540402835291602001916103cc565b60408051600160a060020a03929092168252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156102dd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b828001600101855582156100eb579182015b828111156100eb5782518260005055916020019190600101906102fd565b505080600260005083604051808280519060200190808383829060006004602084601f0104600302600f01f150905001915050908152602001604051809103902060006101000a815481600160a060020a03021916908302179055505050565b5090565b6000805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b820191906000526020600020905b8154815290600101906020018083116103af57829003601f168201915b505050505090506101b556",
      "events": {},
      "updated_at": 1474467172441,
      "links": {}
    }
  };
  
    Contract.checkNetwork = function(callback) {
      var self = this;
  
      if (this.network_id != null) {
        return callback();
      }
  
      this.web3.version.network(function(err, result) {
        if (err) return callback(err);
  
        var network_id = result.toString();
  
        // If we have the main network,
        if (network_id == "1") {
          var possible_ids = ["1", "live", "default"];
  
          for (var i = 0; i < possible_ids.length; i++) {
            var id = possible_ids[i];
            if (Contract.all_networks[id] != null) {
              network_id = id;
              break;
            }
          }
        }
  
        if (self.all_networks[network_id] == null) {
          return callback(new Error(self.name + " error: Can't find artifacts for network id '" + network_id + "'"));
        }
  
        self.setNetwork(network_id);
        callback();
      })
    };
  
    Contract.setNetwork = function(network_id) {
      var network = this.all_networks[network_id] || {};
  
      this.abi             = this.prototype.abi             = network.abi;
      this.unlinked_binary = this.prototype.unlinked_binary = network.unlinked_binary;
      this.address         = this.prototype.address         = network.address;
      this.updated_at      = this.prototype.updated_at      = network.updated_at;
      this.links           = this.prototype.links           = network.links || {};
      this.events          = this.prototype.events          = network.events || {};
  
      this.network_id = network_id;
    };
  
    Contract.networks = function() {
      return Object.keys(this.all_networks);
    };
  
    Contract.link = function(name, address) {
      if (typeof name == "function") {
        var contract = name;
  
        if (contract.address == null) {
          throw new Error("Cannot link contract without an address.");
        }
  
        Contract.link(contract.contract_name, contract.address);
  
        // Merge events so this contract knows about library's events
        Object.keys(contract.events).forEach(function(topic) {
          Contract.events[topic] = contract.events[topic];
        });
  
        return;
      }
  
      if (typeof name == "object") {
        var obj = name;
        Object.keys(obj).forEach(function(name) {
          var a = obj[name];
          Contract.link(name, a);
        });
        return;
      }
  
      Contract.links[name] = address;
    };
  
    Contract.contract_name   = Contract.prototype.contract_name   = "localsService";
    Contract.generated_with  = Contract.prototype.generated_with  = "3.2.0";
  
    // Allow people to opt-in to breaking changes now.
    Contract.next_gen = false;
  
    var properties = {
      binary: function() {
        var binary = Contract.unlinked_binary;
  
        Object.keys(Contract.links).forEach(function(library_name) {
          var library_address = Contract.links[library_name];
          var regex = new RegExp("__" + library_name + "_*", "g");
  
          binary = binary.replace(regex, library_address.replace("0x", ""));
        });
  
        return binary;
      }
    };
  
    Object.keys(properties).forEach(function(key) {
      var getter = properties[key];
  
      var definition = {};
      definition.enumerable = true;
      definition.configurable = false;
      definition.get = getter;
  
      Object.defineProperty(Contract, key, definition);
      Object.defineProperty(Contract.prototype, key, definition);
    });
  
    bootstrap(Contract);
  
    if (typeof module != "undefined" && typeof module.exports != "undefined") {
      module.exports = Contract;
    } else {
      // There will only be one version of this contract in the browser,
      // and we can use that.
      window.localsService = Contract;
    }
  })();
  