docs: function parse_wb_bin(data, opts) {
  	var wb = { AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, xmlns: "" };
  	var state = [];
  	var pass = false;
  
  	if(!opts) opts = {};
  	opts.biff = 12;
  
  	var Names = [];
  	var supbooks = ([[]]);
  	supbooks.SheetNames = [];
  	supbooks.XTI = [];
  
  	recordhopper(data, function hopper_wb(val, R_n, RT) {
  		switch(RT) {
  			case 0x009C: /* 'BrtBundleSh' */
  				supbooks.SheetNames.push(val.name);
  				wb.Sheets.push(val); break;
  
  			case 0x0099: /* 'BrtWbProp' */
  				wb.WBProps = val; break;
  
  			case 0x0027: /* 'BrtName' */
  				if(val.Sheet != null) opts.SID = val.Sheet;
  				val.Ref = stringify_formula(val.Ptg, null, null, supbooks, opts);
  				delete opts.SID;
  				delete val.Ptg;
  				Names.push(val);
  				break;
  			case 0x040C: /* 'BrtNameExt' */ break;
  
  			case 0x0165: /* 'BrtSupSelf' */
  			case 0x0166: /* 'BrtSupSame' */
  			case 0x0163: /* 'BrtSupBookSrc' */
  			case 0x029B: /* 'BrtSupAddin' */
  				if(!supbooks[0].length) supbooks[0] = [RT, val];
  				else supbooks.push([RT, val]);
  				supbooks[supbooks.length - 1].XTI = [];
  				break;
  			case 0x016A: /* 'BrtExternSheet' */
  				if(supbooks.length === 0) { supbooks[0] = []; supbooks[0].XTI = []; }
  				supbooks[supbooks.length - 1].XTI = supbooks[supbooks.length - 1].XTI.concat(val);
  				supbooks.XTI = supbooks.XTI.concat(val);
  				break;
  			case 0x0169: /* 'BrtPlaceholderName' */
  				break;
  
  			/* case 'BrtModelTimeGroupingCalcCol' */
  			case 0x0C00: /* 'BrtUid' */
  			case 0x0C01: /* 'BrtRevisionPtr' */
  			case 0x0817: /* 'BrtAbsPath15' */
  			case 0x0216: /* 'BrtBookProtection' */
  			case 0x02A5: /* 'BrtBookProtectionIso' */
  			case 0x009E: /* 'BrtBookView' */
  			case 0x009D: /* 'BrtCalcProp' */
  			case 0x0262: /* 'BrtCrashRecErr' */
  			case 0x0802: /* 'BrtDecoupledPivotCacheID' */
  			case 0x009B: /* 'BrtFileRecover' */
  			case 0x0224: /* 'BrtFileSharing' */
  			case 0x02A4: /* 'BrtFileSharingIso' */
  			case 0x0080: /* 'BrtFileVersion' */
  			case 0x0299: /* 'BrtFnGroup' */
  			case 0x0850: /* 'BrtModelRelationship' */
  			case 0x084D: /* 'BrtModelTable' */
  			case 0x0225: /* 'BrtOleSize' */
  			case 0x0805: /* 'BrtPivotTableRef' */
  			case 0x0254: /* 'BrtSmartTagType' */
  			case 0x081C: /* 'BrtTableSlicerCacheID' */
  			case 0x081B: /* 'BrtTableSlicerCacheIDs' */
  			case 0x0822: /* 'BrtTimelineCachePivotCacheID' */
  			case 0x018D: /* 'BrtUserBookView' */
  			case 0x009A: /* 'BrtWbFactoid' */
  			case 0x045D: /* 'BrtWbProp14' */
  			case 0x0229: /* 'BrtWebOpt' */
  			case 0x082B: /* 'BrtWorkBookPr15' */
  				break;
  
  			case 0x0023: /* 'BrtFRTBegin' */
  				state.push(R_n); pass = true; break;
  			case 0x0024: /* 'BrtFRTEnd' */
  				state.pop(); pass = false; break;
  			case 0x0025: /* 'BrtACBegin' */
  				state.push(R_n); pass = true; break;
  			case 0x0026: /* 'BrtACEnd' */
  				state.pop(); pass = false; break;
  
  			case 0x0010: /* 'BrtFRTArchID$' */ break;
  
  			default:
  				if((R_n||"").indexOf("Begin") > 0){/* empty */}
  				else if((R_n||"").indexOf("End") > 0){/* empty */}
  				else if(!pass || (opts.WTF && state[state.length-1] != "BrtACBegin" && state[state.length-1] != "BrtFRTBegin")) throw new Error("Unexpected record " + RT + " " + R_n);
  		}
  	}, opts);
  
  	parse_wb_defaults(wb);
  
  	// $FlowIgnore
  	wb.Names = Names;
  
  	(wb).supbooks = supbooks;
  	return wb;
  }