docs: function dyn(data, boff) {
  	/* nomenclature from RFC1951 refers to bit values; these are offset by the implicit constant */
  	var _HLIT = read_bits_5(data, boff) + 257; boff += 5;
  	var _HDIST = read_bits_5(data, boff) + 1; boff += 5;
  	var _HCLEN = read_bits_4(data, boff) + 4; boff += 4;
  	var w = 0;
  
  	/* grab and store code lengths */
  	var clens = use_typed_arrays ? new Uint8Array(19) : zero_fill_array(19);
  	var ctree = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
  	var maxlen = 1;
  	var bl_count =  use_typed_arrays ? new Uint8Array(8) : zero_fill_array(8);
  	var next_code = use_typed_arrays ? new Uint8Array(8) : zero_fill_array(8);
  	var L = clens.length; /* 19 */
  	for(var i = 0; i < _HCLEN; ++i) {
  		clens[CLEN_ORDER[i]] = w = read_bits_3(data, boff);
  		if(maxlen < w) maxlen = w;
  		bl_count[w]++;
  		boff += 3;
  	}
  
  	/* build code tree */
  	var ccode = 0;
  	bl_count[0] = 0;
  	for(i = 1; i <= maxlen; ++i) next_code[i] = ccode = (ccode + bl_count[i-1])<<1;
  	for(i = 0; i < L; ++i) if((ccode = clens[i]) != 0) ctree[i] = next_code[ccode]++;
  	/* cmap[7 bits from stream] = (off&7) + (lit<<3) */
  	var cleni = 0;
  	for(i = 0; i < L; ++i) {
  		cleni = clens[i];
  		if(cleni != 0) {
  			ccode = bitswap8[ctree[i]]>>(8-cleni);
  			for(var j = (1<<(7-cleni))-1; j>=0; --j) dyn_cmap[ccode|(j<<cleni)] = (cleni&7) | (i<<3);
  		}
  	}
  
  	/* read literal and dist codes at once */
  	var hcodes = [];
  	maxlen = 1;
  	for(; hcodes.length < _HLIT + _HDIST;) {
  		ccode = dyn_cmap[read_bits_7(data, boff)];
  		boff += ccode & 7;
  		switch((ccode >>>= 3)) {
  			case 16:
  				w = 3 + read_bits_2(data, boff); boff += 2;
  				ccode = hcodes[hcodes.length - 1];
  				while(w-- > 0) hcodes.push(ccode);
  				break;
  			case 17:
  				w = 3 + read_bits_3(data, boff); boff += 3;
  				while(w-- > 0) hcodes.push(0);
  				break;
  			case 18:
  				w = 11 + read_bits_7(data, boff); boff += 7;
  				while(w -- > 0) hcodes.push(0);
  				break;
  			default:
  				hcodes.push(ccode);
  				if(maxlen < ccode) maxlen = ccode;
  				break;
  		}
  	}
  
  	/* build literal / length trees */
  	var h1 = hcodes.slice(0, _HLIT), h2 = hcodes.slice(_HLIT);
  	for(i = _HLIT; i < 286; ++i) h1[i] = 0;
  	for(i = _HDIST; i < 30; ++i) h2[i] = 0;
  	dyn_len_1 = build_tree(h1, dyn_lmap, 286);
  	dyn_len_2 = build_tree(h2, dyn_dmap, 30);
  	return boff;
  }