// Generated by IcedCoffeeScript 1.7.1-c
(function() {
  var Base, Config, JSS, Lock, SortedMap, chain_err, deq, format_hex, hex_cmp, hex_len, iced, is_hex, iutils, json_stringify_sorted, log_16, make_esc, map, my_cmp, node_types, strcmp, __iced_k, __iced_k_noop, _ref;

  iced = require('iced-runtime').iced;
  __iced_k = __iced_k_noop = function() {};

  iutils = require('iced-utils');

  Lock = iutils.lock.Lock;

  json_stringify_sorted = iutils.util.json_stringify_sorted;

  _ref = require('iced-error'), chain_err = _ref.chain_err, make_esc = _ref.make_esc;

  deq = require('deep-equal');

  exports.node_types = node_types = {
    NONE: 0,
    INODE: 1,
    LEAF: 2
  };

  log_16 = function(y) {
    var ret;
    ret = 0;
    while (y > 1) {
      y = y >> 4;
      ret++;
    }
    return ret;
  };

  JSS = function(x) {
    var inner, pr;
    inner = function(y) {
      return json_stringify_sorted(y, {
        sort_fn: hex_cmp
      });
    };
    pr = x.prev_root != null ? '"prev_root":"' + x.prev_root + '",' : "";
    return "{" + pr + "\"tab\":" + (inner(x.tab)) + ",\"type\":" + (inner(x.type)) + "}";
  };

  format_hex = function(i, len) {
    var buf;
    buf = new Buffer(4);
    buf.writeUInt32BE(i, 0);
    return buf.toString('hex').slice(8 - len);
  };

  hex_len = function(a) {
    var c, ret, _i, _len;
    ret = a.length;
    for (_i = 0, _len = a.length; _i < _len; _i++) {
      c = a[_i];
      if (c === '0') {
        ret--;
      } else {
        break;
      }
    }
    return ret;
  };

  map = {
    0: 0,
    1: 1,
    2: 2,
    3: 3,
    4: 4,
    5: 5,
    6: 6,
    7: 7,
    8: 8,
    9: 9,
    a: 10,
    b: 11,
    c: 12,
    d: 13,
    e: 14,
    f: 15
  };

  is_hex = function(x) {
    return x.match(/^[a-fA-F0-9]+$/);
  };

  strcmp = function(x, y) {
    if (x === y) {
      return 0;
    } else if (x < y) {
      return -1;
    } else {
      return 1;
    }
  };

  exports.my_cmp = my_cmp = function(a, b) {
    if (is_hex(a) && is_hex(b)) {
      return hex_cmp(a, b);
    } else {
      return strcmp(a, b);
    }
  };

  exports.hex_cmp = hex_cmp = function(a, b) {
    var a_len, b_len, c, d, i, ret, tmp;
    a_len = hex_len(a);
    b_len = hex_len(b);
    ret = (function() {
      var _i, _len;
      if (a_len > b_len) {
        return 1;
      } else if (a_len < b_len) {
        return -1;
      } else {
        tmp = 0;
        for (i = _i = 0, _len = a.length; _i < _len; i = ++_i) {
          c = a[i];
          d = b[i];
          if (map[c] > map[d]) {
            tmp = 1;
          } else if (map[c] < map[d]) {
            tmp = -1;
          }
          if (tmp !== 0) {
            break;
          }
        }
        return tmp;
      }
    })();
    return ret;
  };

  exports.SortedMap = SortedMap = (function() {
    function SortedMap(_arg) {
      var i, j, k, key, list, node, obj, sorted, sorted_list, v, val, _i, _ref1;
      node = _arg.node, obj = _arg.obj, list = _arg.list, sorted_list = _arg.sorted_list, key = _arg.key, val = _arg.val;
      if (node != null) {
        obj = node.tab;
        this._type = node.type;
      }
      if (obj != null) {
        list = (function() {
          var _results;
          _results = [];
          for (k in obj) {
            v = obj[k];
            _results.push([k, v]);
          }
          return _results;
        })();
      } else if (sorted_list != null) {
        this._list = sorted_list;
      }
      if ((key != null) && (val != null)) {
        this._list = [[key, val]];
      }
      if ((list != null) && (this._list == null)) {
        sorted = true;
        for (i = _i = 0, _ref1 = list.length; 0 <= _ref1 ? _i < _ref1 : _i > _ref1; i = 0 <= _ref1 ? ++_i : --_i) {
          j = i + 1;
          if ((j < list.length) && (hex_cmp(list[i][0], list[j][0])) > 0) {
            sorted = false;
            break;
          }
        }
        if (!sorted) {
          list.sort(function(a, b) {
            return hex_cmp(a[0], b[0]);
          });
        }
        this._list = list;
      }
      if (this._list == null) {
        this._list = [];
      }
    }

    SortedMap.prototype.slice = function(a, b) {
      return new SortedMap({
        sorted_list: this._list.slice(a, b)
      });
    };

    SortedMap.prototype.len = function() {
      return this._list.length;
    };

    SortedMap.prototype.at = function(i) {
      return this._list[i];
    };

    SortedMap.prototype.push = function(_arg) {
      var key, val;
      key = _arg.key, val = _arg.val;
      return this._list.push([key, val]);
    };

    SortedMap.prototype.to_hash = function(_arg) {
      var JS, hasher, k, key, level, obj, obj_s, parts, pr, prev_root, tab, tab_s, type, v, _i, _len, _ref1, _ref2;
      hasher = _arg.hasher, type = _arg.type, prev_root = _arg.prev_root, level = _arg.level;
      JS = JSON.stringify;
      type || (type = this._type);
      parts = [];
      tab = {};
      _ref1 = this._list;
      for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
        _ref2 = _ref1[_i], k = _ref2[0], v = _ref2[1];
        parts.push([JS(k), JS(v)].join(":"));
        tab[k] = v;
      }
      tab_s = "{" + parts.join(",") + "}";
      pr = prev_root != null ? '"prev_root":"' + prev_root + '",' : "";
      obj_s = "{" + pr + "\"tab\":" + tab_s + ",\"type\":" + type + "}";
      obj = {};
      if ((prev_root != null) && (level != null) && level === 0) {
        obj.prev_root;
      }
      obj.tab = tab;
      obj.type = type;
      key = hasher(obj_s);
      return {
        key: key,
        obj: obj,
        obj_s: obj_s
      };
    };

    SortedMap.prototype.binary_search = function(_arg) {
      var beg, c, end, eq, key, mid, ret;
      key = _arg.key;
      beg = 0;
      end = this._list.length - 1;
      while (beg < end) {
        mid = (end + beg) >> 1;
        c = hex_cmp(key, this._list[mid][0]);
        if (c > 0) {
          beg = mid + 1;
        } else {
          end = mid;
        }
      }
      c = hex_cmp(key, this._list[beg][0]);
      eq = 0;
      ret = c > 0 ? beg + 1 : c === 0 ? (eq = 1, beg) : beg;
      return [ret, eq];
    };

    SortedMap.prototype.replace = function(_arg) {
      var eq, index, key, val, _ref1;
      key = _arg.key, val = _arg.val;
      if (this._list.length) {
        _ref1 = this.binary_search({
          key: key
        }), index = _ref1[0], eq = _ref1[1];
        this._list = this._list.slice(0, index).concat([[key, val]]).concat(this._list.slice(index + eq));
      } else {
        this._list = [[key, val]];
      }
      return this;
    };

    return SortedMap;

  })();

  exports.Config = Config = (function() {
    function Config(_arg) {
      var M, N;
      M = _arg.M, N = _arg.N;
      this.M = M || 256;
      this.N = N || 256;
      this.C = log_16(this.M);
    }

    Config.prototype.obj_to_key = function(o) {
      return o[0];
    };

    Config.prototype.prefix_at_level = function(_arg) {
      var key, level, obj;
      level = _arg.level, key = _arg.key, obj = _arg.obj;
      key || (key = this.obj_to_key(obj));
      return key.slice(level * this.C, (level + 1) * this.C);
    };

    Config.prototype.prefix_through_level = function(_arg) {
      var key, level, obj;
      level = _arg.level, key = _arg.key, obj = _arg.obj;
      key || (key = this.obj_to_key(obj));
      return key.slice(0, (level + 1) * this.C);
    };

    return Config;

  })();

  exports.Base = Base = (function() {
    function Base(_arg) {
      var config;
      config = _arg.config;
      this.config = config || (new Config({}));
      this._lock = new Lock;
      this.hasher = this.hash_fn.bind(this);
    }

    Base.prototype.unimplemented = function() {
      return new Error("unimplemented");
    };

    Base.prototype.hash_fn = function(s) {
      return cb(this.unimplemented());
    };

    Base.prototype.store_node = function(_arg, cb) {
      var key, obj, obj_s;
      key = _arg.key, obj = _arg.obj, obj_s = _arg.obj_s;
      return cb(this.unimplemented());
    };

    Base.prototype.commit_root = function(_arg, cb) {
      var key, prev_root, txinfo;
      key = _arg.key, txinfo = _arg.txinfo, prev_root = _arg.prev_root;
      return cb(this.unimplemented());
    };

    Base.prototype.lookup_node = function(_arg, cb) {
      var key;
      key = _arg.key;
      return cb(this.unimplemented());
    };

    Base.prototype.lookup_root = function(cb) {
      return cb(this.unimplemented());
    };

    Base.prototype.unlock = function(cb) {
      this._lock.release();
      return cb(null);
    };

    Base.prototype.upsert = function(_arg, cb) {
      var curr, esc, h, key, last, level, nxt, obj, obj_s, p, path, prev_root, ret, root, sm, sorted_map, tmp, txinfo, v2, val, ___iced_passed_deferral, __iced_deferrals, __iced_k;
      __iced_k = __iced_k_noop;
      ___iced_passed_deferral = iced.findDeferral(arguments);
      key = _arg.key, val = _arg.val, txinfo = _arg.txinfo;
      cb = chain_err(cb, this.unlock.bind(this));
      esc = make_esc(cb, "upsert");
      (function(_this) {
        return (function(__iced_k) {
          __iced_deferrals = new iced.Deferrals(__iced_k, {
            parent: ___iced_passed_deferral,
            filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
            funcname: "Base.upsert"
          });
          _this._lock.acquire(__iced_deferrals.defer({
            lineno: 267
          }));
          __iced_deferrals._fulfill();
        });
      })(this)((function(_this) {
        return function() {
          (function(__iced_k) {
            __iced_deferrals = new iced.Deferrals(__iced_k, {
              parent: ___iced_passed_deferral,
              filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
              funcname: "Base.upsert"
            });
            _this.lookup_root(esc(__iced_deferrals.defer({
              assign_fn: (function() {
                return function() {
                  return root = arguments[0];
                };
              })(),
              lineno: 270
            })));
            __iced_deferrals._fulfill();
          })(function() {
            prev_root = root;
            curr = null;
            (function(__iced_k) {
              if (typeof root !== "undefined" && root !== null) {
                (function(__iced_k) {
                  __iced_deferrals = new iced.Deferrals(__iced_k, {
                    parent: ___iced_passed_deferral,
                    filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
                    funcname: "Base.upsert"
                  });
                  _this.lookup_node({
                    key: root
                  }, esc(__iced_deferrals.defer({
                    assign_fn: (function() {
                      return function() {
                        return curr = arguments[0];
                      };
                    })(),
                    lineno: 274
                  })));
                  __iced_deferrals._fulfill();
                })(__iced_k);
              } else {
                return __iced_k();
              }
            })(function() {
              last = null;
              path = [];
              level = 0;
              (function(__iced_k) {
                var _results, _while;
                _results = [];
                _while = function(__iced_k) {
                  var _break, _continue, _next;
                  _break = function() {
                    return __iced_k(_results);
                  };
                  _continue = function() {
                    return iced.trampoline(function() {
                      return _while(__iced_k);
                    });
                  };
                  _next = function(__iced_next_arg) {
                    _results.push(__iced_next_arg);
                    return _continue();
                  };
                  if (curr == null) {
                    return _break();
                  } else {
                    p = _this.config.prefix_through_level({
                      key: key,
                      level: level
                    });
                    path.push([p, curr, level++]);
                    last = curr;
                    (function(__iced_k) {
                      if ((nxt = curr.tab[p]) != null) {
                        (function(__iced_k) {
                          __iced_deferrals = new iced.Deferrals(__iced_k, {
                            parent: ___iced_passed_deferral,
                            filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
                            funcname: "Base.upsert"
                          });
                          _this.lookup_node({
                            key: nxt
                          }, esc(__iced_deferrals.defer({
                            assign_fn: (function() {
                              return function() {
                                return curr = arguments[0];
                              };
                            })(),
                            lineno: 287
                          })));
                          __iced_deferrals._fulfill();
                        })(__iced_k);
                      } else {
                        return __iced_k(curr = null);
                      }
                    })(_next);
                  }
                };
                _while(__iced_k);
              })(function() {
                var _ref1;
                ret = null;
                _ref1 = (last == null) || (last.type === node_types.INODE) ? [
                  new SortedMap({
                    key: key,
                    val: val
                  }), 0
                ] : !((v2 = last.tab[key]) != null) || !(deq(val, v2)) ? [
                  (new SortedMap({
                    obj: last.tab
                  })).replace({
                    key: key,
                    val: val
                  }), path.length - 1
                ] : [null, 0], sorted_map = _ref1[0], level = _ref1[1];
                (function(__iced_k) {
                  if (sorted_map != null) {
                    (function(__iced_k) {
                      __iced_deferrals = new iced.Deferrals(__iced_k, {
                        parent: ___iced_passed_deferral,
                        filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
                        funcname: "Base.upsert"
                      });
                      _this.hash_tree_r({
                        level: level,
                        sorted_map: sorted_map,
                        prev_root: prev_root
                      }, esc(__iced_deferrals.defer({
                        assign_fn: (function() {
                          return function() {
                            return tmp = arguments[0];
                          };
                        })(),
                        lineno: 302
                      })));
                      __iced_deferrals._fulfill();
                    })(function() {
                      h = tmp;
                      path.reverse();
                      (function(__iced_k) {
                        var _i, _len, _ref2, _results, _while;
                        _ref2 = path;
                        _len = _ref2.length;
                        _i = 0;
                        _results = [];
                        _while = function(__iced_k) {
                          var _break, _continue, _next, _ref3, _ref4;
                          _break = function() {
                            return __iced_k(_results);
                          };
                          _continue = function() {
                            return iced.trampoline(function() {
                              ++_i;
                              return _while(__iced_k);
                            });
                          };
                          _next = function(__iced_next_arg) {
                            _results.push(__iced_next_arg);
                            return _continue();
                          };
                          if (!(_i < _len)) {
                            return _break();
                          } else {
                            _ref3 = _ref2[_i], p = _ref3[0], curr = _ref3[1], level = _ref3[2];
                            if (curr.type === node_types.INODE) {
                              sm = (new SortedMap({
                                node: curr
                              })).replace({
                                key: p,
                                val: h
                              });
                              _ref4 = sm.to_hash({
                                hasher: _this.hasher,
                                prev_root: prev_root,
                                level: level
                              }), key = _ref4.key, obj = _ref4.obj, obj_s = _ref4.obj_s;
                              h = key;
                              (function(__iced_k) {
                                __iced_deferrals = new iced.Deferrals(__iced_k, {
                                  parent: ___iced_passed_deferral,
                                  filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
                                  funcname: "Base.upsert"
                                });
                                _this.store_node({
                                  key: key,
                                  obj: obj,
                                  obj_s: obj_s
                                }, esc(__iced_deferrals.defer({
                                  lineno: 314
                                })));
                                __iced_deferrals._fulfill();
                              })(_next);
                            } else {
                              return _continue();
                            }
                          }
                        };
                        _while(__iced_k);
                      })(function() {
                        (function(__iced_k) {
                          __iced_deferrals = new iced.Deferrals(__iced_k, {
                            parent: ___iced_passed_deferral,
                            filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
                            funcname: "Base.upsert"
                          });
                          _this.commit_root({
                            key: h,
                            txinfo: txinfo,
                            prev_root: prev_root
                          }, esc(__iced_deferrals.defer({
                            lineno: 317
                          })));
                          __iced_deferrals._fulfill();
                        })(function() {
                          return __iced_k(ret = h);
                        });
                      });
                    });
                  } else {
                    return __iced_k();
                  }
                })(function() {
                  return cb(null, ret);
                });
              });
            });
          });
        };
      })(this));
    };

    Base.prototype.verify_node = function(_arg, cb) {
      var err, h, key, node;
      key = _arg.key, node = _arg.node;
      h = this.hasher(JSS(node));
      err = null;
      if (key !== h) {
        err = new Error("Node hash failed: " + key + " != " + h);
      }
      return cb(err);
    };

    Base.prototype.find = function(_arg, cb) {
      var curr, esc, key, level, node, p, root_obj, skip_verify, val, ___iced_passed_deferral, __iced_deferrals, __iced_k;
      __iced_k = __iced_k_noop;
      ___iced_passed_deferral = iced.findDeferral(arguments);
      key = _arg.key, skip_verify = _arg.skip_verify;
      esc = make_esc(cb, "find");
      val = null;
      (function(_this) {
        return (function(__iced_k) {
          __iced_deferrals = new iced.Deferrals(__iced_k, {
            parent: ___iced_passed_deferral,
            filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
            funcname: "Base.find"
          });
          _this.lookup_root(esc(__iced_deferrals.defer({
            assign_fn: (function() {
              return function() {
                curr = arguments[0];
                return root_obj = arguments[1];
              };
            })(),
            lineno: 336
          })));
          __iced_deferrals._fulfill();
        });
      })(this)((function(_this) {
        return function() {
          level = 0;
          (function(__iced_k) {
            var _results, _while;
            _results = [];
            _while = function(__iced_k) {
              var _break, _continue, _next;
              _break = function() {
                return __iced_k(_results);
              };
              _continue = function() {
                return iced.trampoline(function() {
                  return _while(__iced_k);
                });
              };
              _next = function(__iced_next_arg) {
                _results.push(__iced_next_arg);
                return _continue();
              };
              if (typeof curr === "undefined" || curr === null) {
                return _break();
              } else {
                (function(__iced_k) {
                  __iced_deferrals = new iced.Deferrals(__iced_k, {
                    parent: ___iced_passed_deferral,
                    filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
                    funcname: "Base.find"
                  });
                  _this.lookup_node({
                    key: curr
                  }, esc(__iced_deferrals.defer({
                    assign_fn: (function() {
                      return function() {
                        return node = arguments[0];
                      };
                    })(),
                    lineno: 339
                  })));
                  __iced_deferrals._fulfill();
                })(function() {
                  (function(__iced_k) {
                    if (!skip_verify) {
                      (function(__iced_k) {
                        __iced_deferrals = new iced.Deferrals(__iced_k, {
                          parent: ___iced_passed_deferral,
                          filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
                          funcname: "Base.find"
                        });
                        _this.verify_node({
                          key: curr,
                          node: node
                        }, esc(__iced_deferrals.defer({
                          lineno: 341
                        })));
                        __iced_deferrals._fulfill();
                      })(__iced_k);
                    } else {
                      return __iced_k();
                    }
                  })(function() {
                    if (node.type === node_types.LEAF) {
                      val = node.tab[key];
                      curr = null;
                    } else {
                      p = _this.config.prefix_through_level({
                        key: key,
                        level: level
                      });
                      curr = node.tab[p];
                    }
                    return _next(level++);
                  });
                });
              }
            };
            _while(__iced_k);
          })(function() {
            return cb(null, val, root_obj);
          });
        };
      })(this));
    };

    Base.prototype.build = function(_arg, cb) {
      var esc, h, prev_root, sorted_map, ___iced_passed_deferral, __iced_deferrals, __iced_k;
      __iced_k = __iced_k_noop;
      ___iced_passed_deferral = iced.findDeferral(arguments);
      sorted_map = _arg.sorted_map;
      cb = chain_err(cb, this.unlock.bind(this));
      esc = make_esc(cb, "full_build");
      (function(_this) {
        return (function(__iced_k) {
          __iced_deferrals = new iced.Deferrals(__iced_k, {
            parent: ___iced_passed_deferral,
            filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
            funcname: "Base.build"
          });
          _this._lock.acquire(__iced_deferrals.defer({
            lineno: 358
          }));
          __iced_deferrals._fulfill();
        });
      })(this)((function(_this) {
        return function() {
          (function(__iced_k) {
            __iced_deferrals = new iced.Deferrals(__iced_k, {
              parent: ___iced_passed_deferral,
              filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
              funcname: "Base.build"
            });
            _this.lookup_root(esc(__iced_deferrals.defer({
              assign_fn: (function() {
                return function() {
                  return prev_root = arguments[0];
                };
              })(),
              lineno: 359
            })));
            __iced_deferrals._fulfill();
          })(function() {
            (function(__iced_k) {
              __iced_deferrals = new iced.Deferrals(__iced_k, {
                parent: ___iced_passed_deferral,
                filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
                funcname: "Base.build"
              });
              _this.hash_tree_r({
                level: 0,
                sorted_map: sorted_map,
                prev_root: prev_root
              }, esc(__iced_deferrals.defer({
                assign_fn: (function() {
                  return function() {
                    return h = arguments[0];
                  };
                })(),
                lineno: 360
              })));
              __iced_deferrals._fulfill();
            })(function() {
              (function(__iced_k) {
                __iced_deferrals = new iced.Deferrals(__iced_k, {
                  parent: ___iced_passed_deferral,
                  filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
                  funcname: "Base.build"
                });
                _this.commit_root({
                  key: h,
                  prev: prev_root
                }, esc(__iced_deferrals.defer({
                  lineno: 361
                })));
                __iced_deferrals._fulfill();
              })(function() {
                return cb(null);
              });
            });
          });
        };
      })(this));
    };

    Base.prototype.hash_tree_r = function(_arg, cb) {
      var C, M, end, err, h, i, j, key, level, new_sorted_map, obj, obj_s, prefix, prev_root, sorted_map, start, sublist, ___iced_passed_deferral, __iced_deferrals, __iced_k, _begin, _end, _positive;
      __iced_k = __iced_k_noop;
      ___iced_passed_deferral = iced.findDeferral(arguments);
      level = _arg.level, sorted_map = _arg.sorted_map, prev_root = _arg.prev_root;
      err = null;
      key = null;
      (function(_this) {
        return (function(__iced_k) {
          var _ref1;
          if (sorted_map.len() <= _this.config.N) {
            _ref1 = sorted_map.to_hash({
              prev_root: prev_root,
              hasher: _this.hasher,
              level: level,
              type: node_types.LEAF
            }), key = _ref1.key, obj = _ref1.obj, obj_s = _ref1.obj_s;
            (function(__iced_k) {
              __iced_deferrals = new iced.Deferrals(__iced_k, {
                parent: ___iced_passed_deferral,
                filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
                funcname: "Base.hash_tree_r"
              });
              _this.store_node({
                key: key,
                obj: obj,
                obj_s: obj_s
              }, __iced_deferrals.defer({
                assign_fn: (function() {
                  return function() {
                    return err = arguments[0];
                  };
                })(),
                lineno: 372
              }));
              __iced_deferrals._fulfill();
            })(__iced_k);
          } else {
            M = _this.config.M;
            C = _this.config.C;
            j = 0;
            new_sorted_map = new SortedMap({});
            (function(__iced_k) {
              var _i, _results, _while;
              i = 0;
              _begin = 0;
              _end = M;
              _positive = _end > _begin;
              _results = [];
              _while = function(__iced_k) {
                var _break, _continue, _next;
                _break = function() {
                  return __iced_k(_results);
                };
                _continue = function() {
                  return iced.trampoline(function() {
                    if (_positive) {
                      i += 1;
                    } else {
                      i -= 1;
                    }
                    return _while(__iced_k);
                  });
                };
                _next = function(__iced_next_arg) {
                  _results.push(__iced_next_arg);
                  return _continue();
                };
                if (!!((_positive === true && i >= M) || (_positive === false && i <= M))) {
                  return _break();
                } else {

                  prefix = format_hex(i, C);
                  start = j;
                  while (j < sorted_map.len() && (_this.config.prefix_at_level({
                      level: level,
                      obj: sorted_map.at(j)
                    }) === prefix)) {
                    j++;
                  }
                  end = j;
                  (function(__iced_k) {
                    if (end > start) {
                      sublist = sorted_map.slice(start, end);
                      (function(__iced_k) {
                        __iced_deferrals = new iced.Deferrals(__iced_k, {
                          parent: ___iced_passed_deferral,
                          filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
                          funcname: "Base.hash_tree_r"
                        });
                        _this.hash_tree_r({
                          level: level + 1,
                          sorted_map: sublist
                        }, __iced_deferrals.defer({
                          assign_fn: (function() {
                            return function() {
                              err = arguments[0];
                              return h = arguments[1];
                            };
                          })(),
                          lineno: 386
                        }));
                        __iced_deferrals._fulfill();
                      })(function() {
                        (function(__iced_k) {
                          if (err != null) {
                            (function(__iced_k) {
_break()
                            })(__iced_k);
                          } else {
                            return __iced_k();
                          }
                        })(function() {
                          prefix = _this.config.prefix_through_level({
                            level: level,
                            obj: sublist.at(0)
                          });
                          return __iced_k(new_sorted_map.push({
                            key: prefix,
                            val: h
                          }));
                        });
                      });
                    } else {
                      return __iced_k();
                    }
                  })(_next);
                }
              };
              _while(__iced_k);
            })(function() {
              (function(__iced_k) {
                var _ref2;
                if (err == null) {
                  _ref2 = new_sorted_map.to_hash({
                    prev_root: prev_root,
                    hasher: _this.hasher,
                    level: level,
                    type: node_types.INODE
                  }), key = _ref2.key, obj = _ref2.obj, obj_s = _ref2.obj_s;
                  (function(__iced_k) {
                    __iced_deferrals = new iced.Deferrals(__iced_k, {
                      parent: ___iced_passed_deferral,
                      filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
                      funcname: "Base.hash_tree_r"
                    });
                    _this.store_node({
                      key: key,
                      obj: obj,
                      obj_s: obj_s
                    }, __iced_deferrals.defer({
                      assign_fn: (function() {
                        return function() {
                          return err = arguments[0];
                        };
                      })(),
                      lineno: 392
                    }));
                    __iced_deferrals._fulfill();
                  })(__iced_k);
                } else {
                  return __iced_k();
                }
              })(__iced_k);
            });
          }
        });
      })(this)((function(_this) {
        return function() {
          return cb(err, key);
        };
      })(this));
    };

    return Base;

  })();

}).call(this);
