<commit_before>part of couclient;

class BagWindow extends Modal {

	static List<BagWindow> openWindows = [];

	static closeId(String id) {
		openWindows.where((BagWindow w) => w.id == id).first.close();
		openWindows.removeWhere((BagWindow w) => w.id == id);
	}

	String id = 'bagWindow' + random.nextInt(9999999).toString();
	String bagId;
	int numSlots;
	int sourceSlotNum;

	BagWindow(this.sourceSlotNum, Map sourceItem) {
		DivElement windowElement = load(sourceItem);
		querySelector("#windowHolder").append(windowElement);
		prepare();
		open();
		openWindows.add(this);
	}

	DivElement load(Map sourceItem) {

		// Header

		Element closeButton = new Element.tag("i")
			..classes.add("fa-li")
			..classes.add("fa")
			..classes.add("fa-times")
			..classes.add("close");

		Element icon = new Element.tag("i")
			..classes.add("fa-li")
			..classes.add("fa")
			..classes.add("fa-info-circle");

		SpanElement titleSpan = new SpanElement()
			..classes.add("iw-title")
			..text = sourceItem["name"];

		if (sourceItem["name"].length >= 24) {
			titleSpan.style.fontSize = "24px";
		}

		Element header = new Element.header()
			..append(icon)
			..append(titleSpan);

		// Content

		Element well = new Element.tag("ur-well");

		int numSlots = sourceItem["subSlots"];
		List<Map> subSlots;

		if (sourceItem["metadata"]["slots"] == null) {
			// Empty bag
			subSlots = [];
			while (subSlots.length < numSlots) {
				subSlots.add(({
					"itemType": "",
					"count": 0,
					"metadata": {}
				}));
			}
		} else {
			// Bag has contents
			subSlots = JSON.decode(sourceItem["metadata"]["slots"]);
		}

		if (subSlots.length != sourceItem["subSlots"]) {
			throw new StateError("Number of slots in bag does not match bag size");
		} else {
			String url = "http://${Configs.utilServerAddress}/getItems?isRegex=true&type=";
			subSlots.where((Map slot) => slot["itemType"] != "").forEach((Map itemInBag) => url += "|${itemInBag["itemType"]}");
			url = url.replaceFirst("|", "");
			HttpRequest.getString(url).then((String str) {
				List<Map> itemsData = JSON.decode(str);
				subSlots.forEach((Map itemInBag) {
					// Item
					DivElement itemInSlot = new DivElement();
					if (itemInBag["itemType"] != "") {
						Map itemData = itemsData.where((Map item) => item["itemType"] == itemInBag["itemType"]).first;
						// Item in slot
						itemInSlot
							..classes.addAll(["item-${itemInBag["itemType"]}", "inventoryItem", "bagInventoryItem"])
							..attributes["name"] = itemData["name"]
							..attributes["count"] = itemInBag["count"].toString()
							..attributes["itemmap"] = JSON.encode(itemInBag)
							..style.backgroundImage = "url(${itemData["iconUrl"]})"
							..style.width = "30px"
							..style.height = "30px"
							..style.margin = "auto"
							..title = itemData["name"];
					} else {
						// Empty slot
						itemInSlot.classes.add("empty-bag-slot");
					}
					// Slot
					DivElement slot = new DivElement()
						..classes.addAll(["box", "bagwindow-box"])
						..append(itemInSlot);

					well.append(slot);
				});
			});
		}

		// Window

		DivElement window = new DivElement()
			..id = id
			..classes.add("window")
			..classes.add("itemWindow")
			..append(header)
			..append(closeButton)
			..append(well);

		return window;
	}

	@override
	close() {
		// Handle window closing
		_destroyEscListener();
		displayElement.hidden = true;
		elementOpen = false;

		//see if there's another window that we want to focus
		for (Element modal in querySelectorAll('.window')) {
			if (!modal.hidden) {
				modals[modal.id].focus();<commit_msg>a bit better positioning of item images in bags<commit_after>part of couclient;

class BagWindow extends Modal {

	static List<BagWindow> openWindows = [];

	static closeId(String id) {
		openWindows.where((BagWindow w) => w.id == id).first.close();
		openWindows.removeWhere((BagWindow w) => w.id == id);
	}

	String id = 'bagWindow' + random.nextInt(9999999).toString();
	String bagId;
	int numSlots;
	int sourceSlotNum;

	BagWindow(this.sourceSlotNum, Map sourceItem) {
		DivElement windowElement = load(sourceItem);
		querySelector("#windowHolder").append(windowElement);
		prepare();
		open();
		openWindows.add(this);
	}

	DivElement load(Map sourceItem) {

		// Header

		Element closeButton = new Element.tag("i")
			..classes.add("fa-li")
			..classes.add("fa")
			..classes.add("fa-times")
			..classes.add("close");

		Element icon = new Element.tag("i")
			..classes.add("fa-li")
			..classes.add("fa")
			..classes.add("fa-info-circle");

		SpanElement titleSpan = new SpanElement()
			..classes.add("iw-title")
			..text = sourceItem["name"];

		if (sourceItem["name"].length >= 24) {
			titleSpan.style.fontSize = "24px";
		}

		Element header = new Element.header()
			..append(icon)
			..append(titleSpan);

		// Content

		Element well = new Element.tag("ur-well");

		int numSlots = sourceItem["subSlots"];
		List<Map> subSlots;

		if (sourceItem["metadata"]["slots"] == null) {
			// Empty bag
			subSlots = [];
			while (subSlots.length < numSlots) {
				subSlots.add(({
					"itemType": "",
					"count": 0,
					"metadata": {}
				}));
			}
		} else {
			// Bag has contents
			subSlots = JSON.decode(sourceItem["metadata"]["slots"]);
		}

		if (subSlots.length != sourceItem["subSlots"]) {
			throw new StateError("Number of slots in bag does not match bag size");
		} else {
			String url = "http://${Configs.utilServerAddress}/getItems?isRegex=true&type=";
			subSlots.where((Map slot) => slot["itemType"] != "").forEach((Map itemInBag) => url += "|${itemInBag["itemType"]}");
			url = url.replaceFirst("|", "");
			HttpRequest.getString(url).then((String str) {
				List<Map> itemsData = JSON.decode(str);
				subSlots.forEach((Map itemInBag) {
					DivElement slot = new DivElement();
					// Item
					DivElement itemInSlot = new DivElement();
					if (itemInBag["itemType"] != "") {
						Map itemData = itemsData.where((Map item) => item["itemType"] == itemInBag["itemType"]).first;
						_sizeItem(slot,itemInSlot,itemData,itemInBag['count']);
					} else {
						// Empty slot
						itemInSlot.classes.add("empty-bag-slot");
					}
					// Slot
					slot
						..classes.addAll(["box", "bagwindow-box"])
						..append(itemInSlot);

					well.append(slot);
				});
			});
		}

		// Window

		DivElement window = new DivElement()
			..id = id
			..classes.add("window")
			..classes.add("itemWindow")
			..append(header)
			..append(closeButton)
			..append(well);

		return window;
	}

	Future _sizeItem(Element slot, Element item, Map i, int count) async {
		ImageElement img = new ImageElement(src: i['spriteUrl']);
		await img.onLoad;

		num scale = 1;
		if (img.height > img.width / i['iconNum']) {
			scale = (slot.contentEdge.height - 10) / img.height;
		} else {
			scale = (slot.contentEdge.width - 10) / (img.width / i['iconNum']);
		}

		item
			..classes.addAll(["item-${i["itemType"]}", "inventoryItem", "bagInventoryItem"])
			..attributes["name"] = i["name"]
			..attributes["count"] = count.toString()
			..attributes["itemmap"] = JSON.encode(i)
			..style.width = (slot.contentEdge.width - 10).toString() + "px"
			..style.height = (slot.contentEdge.height - 10).toString() + "px"
			..style.backgroundImage = 'url(${i['spriteUrl']})'
			..style.backgroundRepeat = 'no-repeat'
			..style.backgroundSize = "${img.width * scale}px ${img.height * scale}px"
			..style.margin = "auto";

		int offset = count;
		if (i['iconNum'] != null && i['iconNum'] < count) {
			offset = i['iconNum'];
		}

		item.style.backgroundPosition = "calc(100% / ${i['iconNum'] - 1} * ${offset - 1}";
	}

	@override
	close() {
		// Handle window closing
		_destroyEscListener();
		displayElement.hidden = true;
		elementOpen = false;

		//see if there's another window that we want to focus
		for (Element modal in querySelectorAll('.window')) {
			if (!modal.hidden) {
				modals[modal.id].focus();
{'fraction_non_alphanumeric': 0.18251863079449288, 'fraction_numerical': 0.005305039787798408, 'mean_word_length': 3.277687736358725, 'pattern_counts': {'":': 6, '<': 12, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2258276', 'n_tokens_mistral': 3156, 'n_tokens_neox': 2605, 'n_words': 533}