lib/HalModuleParser.js
function(fileBuffer) {
		// try no offset
		var r = new buffers.BufferReader(fileBuffer);
		var userModuleStartAddy = r.shiftUInt32(true).toString(16);

		// start over
		r = new buffers.BufferReader(fileBuffer);
		// skip 0x184 for system modules to skip the vector table
		r.skip(388);

		var sysModuleStartAddy = r.shiftUInt32(true).toString(16);

		// start over, test for Mesh modular firmware which has a different offset than Photon/Electron modular firmware
		r = new buffers.BufferReader(fileBuffer);
		// skip 0x200 for Mesh firmware
		r.skip(0x200);
		var meshModule = this._parsePrefix(r);

		// start over, test for Core monolithic firmware which has a different offset than modular firmware
		r = new buffers.BufferReader(fileBuffer);
		// skip 0x10C for Core firmware
		r.skip(0x10C);


		var coreModuleStartAddy = r.shiftUInt32(true).toString(16);

		// start over, test for bluz system part which has a different offset than Photon
		r = new buffers.BufferReader(fileBuffer);
		// skip 0xc0 for bluz system modules to skip the vector table
		r.skip(192);
		var bluzModuleStartAddy = r.shiftUInt32(true);
		// also check for the platform ID since the address is pretty nebulous to check for
		r = new buffers.BufferReader(fileBuffer);
		r.skip(192+12);
		var bluzModulesPlatformID = r.shiftUInt16(true);

		//just system modules have the offset at the beginning.
		// system module addresses always tend to start at 0x2xxxxxxx
		// while user modules tend to start around 0x8xxxxxxx

		// but any valid address right now should start with 80... something, since they're small / in the realm
		// of the bootloader....  we'll need some extra sanity checks somehow later if hardware changes dramatically.
		var mightBeUser = (userModuleStartAddy.indexOf("80") === 0) || (userModuleStartAddy === 'd4000');
		var mightBeSystem = (sysModuleStartAddy.indexOf("80") === 0);
		var isCore = ((userModuleStartAddy.indexOf("20") === 0) && (coreModuleStartAddy === "8005000"));
		var mightBeBluz = (bluzModulesPlatformID == 103 && bluzModuleStartAddy < 262144);
		var isMesh = (meshModule.platformID >= 12 && meshModule.platformID <= 30) && (meshModule.moduleStartAddy === '30000' || meshModule.moduleStartAddy === 'f4000') &&
			(userModuleStartAddy.indexOf("20") == 0);   // stack is located in ram at 0x2000000

		if (isCore) {
			return 0x10C;
		}
		else if (!mightBeUser && mightBeSystem) {
			return 388;
		} else if (mightBeUser && !mightBeSystem) {
			return 0;
		} else if (mightBeBluz) {
			return 192;
		} else if (isMesh) {
			return 0x200;
		} else {
			return 0;
		}
	}
function(fileBuffer) {
		// try no offset
		var r = new buffers.BufferReader(fileBuffer);
		var userModuleStartAddy = r.shiftUInt32(true).toString(16);

		// start over
		r = new buffers.BufferReader(fileBuffer);
		// skip 0x184 for system modules to skip the vector table
		r.skip(388);

		var sysModuleStartAddy = r.shiftUInt32(true).toString(16);

		// start over, test for Mesh modular firmware which has a different offset than Photon/Electron modular firmware
		r = new buffers.BufferReader(fileBuffer);
		// skip 0x200 for Mesh firmware
		r.skip(0x200);
		var meshModule = this._parsePrefix(r);

		// start over, test for Core monolithic firmware which has a different offset than modular firmware
		r = new buffers.BufferReader(fileBuffer);
		// skip 0x10C for Core firmware
		r.skip(0x10C);


		var coreModuleStartAddy = r.shiftUInt32(true).toString(16);

		// start over, test for bluz system part which has a different offset than Photon
		r = new buffers.BufferReader(fileBuffer);
		// skip 0xc0 for bluz system modules to skip the vector table
		r.skip(192);
		var bluzModuleStartAddy = r.shiftUInt32(true);
		// also check for the platform ID since the address is pretty nebulous to check for
		r = new buffers.BufferReader(fileBuffer);
		r.skip(192+12);
		var bluzModulesPlatformID = r.shiftUInt16(true);

		//just system modules have the offset at the beginning.
		// system module addresses always tend to start at 0x2xxxxxxx
		// while user modules tend to start around 0x8xxxxxxx

		// but any valid address right now should start with 80... something, since they're small / in the realm
		// of the bootloader....  we'll need some extra sanity checks somehow later if hardware changes dramatically.
		var mightBeUser = (userModuleStartAddy.indexOf("80") === 0) || (userModuleStartAddy === 'd4000');
		var mightBeSystem = (sysModuleStartAddy.indexOf("80") === 0);
		var isCore = ((userModuleStartAddy.indexOf("20") === 0) && (coreModuleStartAddy === "8005000"));
		var mightBeBluz = (bluzModulesPlatformID == 103 && bluzModuleStartAddy < 262144);
		var isMesh = (meshModule.platformID >= 12 && meshModule.platformID <= 30) && (meshModule.moduleStartAddy === '30000' || meshModule.moduleStartAddy === 'f4000') &&
			(userModuleStartAddy.indexOf("20") == 0);   // stack is located in ram at 0x2000000

		if (isCore) {
			return 0x10C;
		}
		else if (!mightBeUser && mightBeSystem) {
			return 388;
		} else if (mightBeUser && !mightBeSystem) {
			return 0;
		} else if (mightBeBluz) {
			return 192;
		} else if (isMesh) {
			return 0x200;
		} else {
			return 0;
		}
	}
/*
tries to determine where we should be looking in the file.

This changes based on whether or not we're in the bootloader,
and we attempt to validate the result based on the assumption
that firmware addresses tend to start with hex '80' since
they're stored after
0x0800xxxx, etc.

@param fileBuffer
@returns {number}
@private