function normalize(obj, item) {
	const nodeName = item.nodeName;

	switch (nodeName) {
		case "data": {
			const data = parse(item);

			data.encoding = data.encoding || "xml";

			// decode chunks for infinite maps
			if (typeof data.chunks !== "undefined") {
				obj.chunks = obj.chunks || [];
				// infinite maps containing chunk data
				data.chunks.forEach((chunk) => {
					obj.chunks.push({
						x: +chunk.x,
						y: +chunk.y,
						// chunk width is in tiles
						width: +chunk.width,
						// chunk height is in tiles
						height: +chunk.height,
						data: decode(chunk.text, data.encoding, data.compression),
					});
				});
				obj.encoding = "none";
			}
			// Bug on if condition: when parsing data, data.text is sometimes defined when chunks are present
			if (
				typeof data.text !== "undefined" &&
				typeof obj.chunks === "undefined"
			) {
				// Finite maps
				obj.data = decode(data.text, data.encoding, data.compression);
				obj.encoding = "none";
			}
			break;
		}
		case "chunk":
			obj.chunks = obj.chunks || [];
			obj.chunks.push(parse(item));
			break;

		case "imagelayer":
		case "layer":
		case "objectgroup":
		case "group": {
			const layer = parse(item);
			layer.type = nodeName === "layer" ? "tilelayer" : nodeName;
			if (layer.image) {
				layer.image = layer.image.source;
			}

			obj.layers = obj.layers || [];
			obj.layers.push(layer);
			break;
		}
		case "animation":
			obj.animation = parse(item).frames;
			break;

		case "frame":
		case "object": {
			const name = nodeName + "s";
			obj[name] = obj[name] || [];
			obj[name].push(parse(item));
			break;
		}
		case "tile": {
			const tile = parse(item);
			if (tile.image) {
				tile.imagewidth = tile.image.width;
				tile.imageheight = tile.image.height;
				tile.image = tile.image.source;
			}
			obj.tiles = obj.tiles || {};
			obj.tiles[tile.id] = tile;
			break;
		}
		case "tileset": {
			const tileset = parse(item);
			if (tileset.image) {
				tileset.imagewidth = tileset.image.width;
				tileset.imageheight = tileset.image.height;
				tileset.image = tileset.image.source;
			}

			obj.tilesets = obj.tilesets || [];
			obj.tilesets.push(tileset);
			break;
		}
		case "polygon":
		case "polyline": {
			obj[nodeName] = [];

			// Get a point array
			const points = parse(item).points.split(" ");

			// And normalize them into an array of vectors
			for (let i = 0; i < points.length; i++) {
				const v = points[i].split(",");
				obj[nodeName].push({
					x: +v[0],
					y: +v[1],
				});
			}

			break;
		}
		case "properties":
			obj.properties = parse(item);
			break;

		case "property": {
			const property = parse(item);
			// for custom properties, text is used
			const value =
				typeof property.value !== "undefined" ? property.value : property.text;

			obj[property.name] = setTMXValue(
				property.name,
				// in XML type is undefined for "string" values
				property.type || "string",
				value,
			);
			break;
		}
		default:
			obj[nodeName] = parse(item);
			break;
	}
}
Normalize TMX format to Tiled JSON format
@ignore