diff --git a/elm.json b/elm.json
index 1bf0b5cfc35f45cb205a7fcc07315397d8b7f5a2..602a6f86b0c1ea82f21adc40d52a5b4405b201ec 100644
--- a/elm.json
+++ b/elm.json
@@ -6,6 +6,7 @@
     "elm-version": "0.19.1",
     "dependencies": {
         "direct": {
+            "BrianHicks/elm-csv": "4.0.1",
             "NoRedInk/elm-json-decode-pipeline": "1.0.1",
             "avh4/elm-color": "1.0.0",
             "elm/browser": "1.0.2",
@@ -16,7 +17,6 @@
             "elm-community/graph": "6.0.0",
             "elm-community/list-extra": "8.7.0",
             "elm-community/typed-svg": "7.0.0",
-            "ericgj/elm-csv-decode": "2.0.1",
             "folkertdev/one-true-path-experiment": "6.0.0",
             "gampleman/elm-visualization": "2.4.1",
             "lovasoa/elm-csv": "1.1.7",
@@ -52,7 +52,8 @@
             "justinmimbs/time-extra": "1.2.0",
             "robinheghan/murmur3": "1.0.0",
             "rtfeldman/elm-hex": "1.0.0",
-            "ryan-haskell/date-format": "1.0.0"
+            "ryan-haskell/date-format": "1.0.0",
+            "ericgj/elm-csv-decode": "2.0.1"
         }
     },
     "test-dependencies": {
diff --git a/public/csv/smartphone_dataset.csv b/public/csv/smartphone_dataset.csv
index 19e51692bd0a8a95faf7f072d5c7b6d02166675b..04d6208a9e2e768061d867968aad2d80f3db2d0f 100644
--- a/public/csv/smartphone_dataset.csv
+++ b/public/csv/smartphone_dataset.csv
@@ -1,4 +1,4 @@
-,index,brand,model,price,rating,5G,NFC,IR_blaster,processor_name,processor_brand,num_cores,processor_speed,ram,Battery,fast_charging,Internal_mem,RAM,display,screen_size,resolution,refresh_rate,camera,card,os
+id,index,brand,model,price,rating,5G,NFC,IR_blaster,processor_name,processor_brand,num_cores,processor_speed,ram,Battery,fast_charging,Internal_mem,RAM,display,screen_size,resolution,refresh_rate,camera,card,os
 0,2,oneplus,OnePlus 11 5G,54999,89.0,True,True,False,Snapdragon 8 Gen2,snapdragon,octa core, 3.2 GHz Processor,"12 GB RAM, 256 GB inbuilt",5000.0,100, 256 GB inbuilt,12,"6.7 inches, 1440 x 3216 px, 120 Hz Display with Punch Hole",6.7 inches,1440 x 3216 ,120,50 MP + 48 MP + 32 MP Triple Rear & 16 MP Front Camera,Memory Card Not Supported,Android v13
 1,3,oneplus,OnePlus Nord CE 2 Lite 5G,19989,81.0,True,False,False,Snapdragon 695,snapdragon,octa core, 2.2 GHz Processor,"6 GB RAM, 128 GB inbuilt",5000.0,33, 128 GB inbuilt,6,"6.59 inches, 1080 x 2412 px, 120 Hz Display with Punch Hole",6.59 inches,1080 x 2412 ,120,64 MP + 2 MP + 2 MP Triple Rear & 16 MP Front Camera,"Memory Card (Hybrid), upto 1 TB",Android v12
 2,4,samsung,Samsung Galaxy A14 5G,16499,75.0,True,False,False,Exynos 1330,exynos,octa core, 2.4 GHz Processor,"4 GB RAM, 64 GB inbuilt",5000.0,15, 64 GB inbuilt,4,"6.6 inches, 1080 x 2408 px, 90 Hz Display with Water Drop Notch",6.6 inches,1080 x 2408 ,90,50 MP + 2 MP + 2 MP Triple Rear & 13 MP Front Camera,"Memory Card Supported, upto 1 TB",Android v13
diff --git a/public/main.js b/public/main.js
index 26913da1d67211e17f54b5d2ec9a5349efb5b0f5..d4b73307bcdb86331305056c8bf40a8cb56d2296 100644
--- a/public/main.js
+++ b/public/main.js
@@ -6174,21 +6174,819 @@ var $author$project$Main$subscriptions = function (_v0) {
 };
 var $elm$core$Platform$Cmd$batch = _Platform_batch;
 var $elm$core$Platform$Cmd$none = $elm$core$Platform$Cmd$batch(_List_Nil);
-var $elm$core$String$lines = _String_lines;
-var $author$project$Main$Smartphone = F8(
-	function (id, brand, model, price, rating, g5, nfc, ir_blaster) {
-		return {brand: brand, g5: g5, id: id, ir_blaster: ir_blaster, model: model, nfc: nfc, price: price, rating: rating};
+var $BrianHicks$elm_csv$Csv$Decode$FieldNamesFromFirstRow = {$: 'FieldNamesFromFirstRow'};
+var $BrianHicks$elm_csv$Csv$Decode$ParsingError = function (a) {
+	return {$: 'ParsingError', a: a};
+};
+var $elm$core$Result$andThen = F2(
+	function (callback, result) {
+		if (result.$ === 'Ok') {
+			var value = result.a;
+			return callback(value);
+		} else {
+			var msg = result.a;
+			return $elm$core$Result$Err(msg);
+		}
 	});
-var $elm$core$List$filter = F2(
-	function (isGood, list) {
-		return A3(
-			$elm$core$List$foldr,
-			F2(
-				function (x, xs) {
-					return isGood(x) ? A2($elm$core$List$cons, x, xs) : xs;
-				}),
+var $BrianHicks$elm_csv$Csv$Decode$DecodingErrors = function (a) {
+	return {$: 'DecodingErrors', a: a};
+};
+var $BrianHicks$elm_csv$Csv$Decode$OnlyColumn_ = {$: 'OnlyColumn_'};
+var $elm$core$Basics$composeL = F3(
+	function (g, f, x) {
+		return g(
+			f(x));
+	});
+var $elm$core$List$append = F2(
+	function (xs, ys) {
+		if (!ys.b) {
+			return xs;
+		} else {
+			return A3($elm$core$List$foldr, $elm$core$List$cons, ys, xs);
+		}
+	});
+var $elm$core$List$concat = function (lists) {
+	return A3($elm$core$List$foldr, $elm$core$List$append, _List_Nil, lists);
+};
+var $BrianHicks$elm_csv$Csv$Decode$NoFieldNamesOnFirstRow = {$: 'NoFieldNamesOnFirstRow'};
+var $elm$core$String$trim = _String_trim;
+var $BrianHicks$elm_csv$Csv$Decode$getFieldNames = F2(
+	function (headers, rows) {
+		var fromList = function (names) {
+			return A3(
+				$elm$core$List$foldl,
+				F2(
+					function (name, _v2) {
+						var soFar = _v2.a;
+						var i = _v2.b;
+						return _Utils_Tuple2(
+							A3($elm$core$Dict$insert, name, i, soFar),
+							i + 1);
+					}),
+				_Utils_Tuple2($elm$core$Dict$empty, 0),
+				names).a;
+		};
+		switch (headers.$) {
+			case 'NoFieldNames':
+				return $elm$core$Result$Ok(
+					_Utils_Tuple3(
+						{available: false, names: $elm$core$Dict$empty},
+						0,
+						rows));
+			case 'CustomFieldNames':
+				var names = headers.a;
+				return $elm$core$Result$Ok(
+					_Utils_Tuple3(
+						{
+							available: true,
+							names: fromList(names)
+						},
+						0,
+						rows));
+			default:
+				if (!rows.b) {
+					return $elm$core$Result$Err($BrianHicks$elm_csv$Csv$Decode$NoFieldNamesOnFirstRow);
+				} else {
+					var first = rows.a;
+					var rest = rows.b;
+					return $elm$core$Result$Ok(
+						_Utils_Tuple3(
+							{
+								available: true,
+								names: fromList(
+									A2($elm$core$List$map, $elm$core$String$trim, first))
+							},
+							1,
+							rest));
+				}
+		}
+	});
+var $elm$core$Result$map = F2(
+	function (func, ra) {
+		if (ra.$ === 'Ok') {
+			var a = ra.a;
+			return $elm$core$Result$Ok(
+				func(a));
+		} else {
+			var e = ra.a;
+			return $elm$core$Result$Err(e);
+		}
+	});
+var $BrianHicks$elm_csv$Csv$Decode$applyDecoder = F3(
+	function (fieldNames, _v0, allRows) {
+		var decode = _v0.a;
+		var defaultLocation = $BrianHicks$elm_csv$Csv$Decode$OnlyColumn_;
+		return A2(
+			$elm$core$Result$andThen,
+			function (_v1) {
+				var resolvedNames = _v1.a;
+				var firstRowNumber = _v1.b;
+				var rows = _v1.c;
+				return A2(
+					$elm$core$Result$mapError,
+					A2(
+						$elm$core$Basics$composeL,
+						A2($elm$core$Basics$composeL, $BrianHicks$elm_csv$Csv$Decode$DecodingErrors, $elm$core$List$concat),
+						$elm$core$List$reverse),
+					A2(
+						$elm$core$Result$map,
+						$elm$core$List$reverse,
+						A3(
+							$elm$core$List$foldl,
+							F2(
+								function (row, _v2) {
+									var soFar = _v2.a;
+									var rowNum = _v2.b;
+									return _Utils_Tuple2(
+										function () {
+											var _v3 = A4(decode, defaultLocation, resolvedNames, rowNum, row);
+											if (_v3.$ === 'Ok') {
+												var val = _v3.a;
+												if (soFar.$ === 'Ok') {
+													var values = soFar.a;
+													return $elm$core$Result$Ok(
+														A2($elm$core$List$cons, val, values));
+												} else {
+													var errs = soFar.a;
+													return $elm$core$Result$Err(errs);
+												}
+											} else {
+												var err = _v3.a;
+												if (soFar.$ === 'Ok') {
+													return $elm$core$Result$Err(
+														_List_fromArray(
+															[err]));
+												} else {
+													var errs = soFar.a;
+													return $elm$core$Result$Err(
+														A2($elm$core$List$cons, err, errs));
+												}
+											}
+										}(),
+										rowNum + 1);
+								}),
+							_Utils_Tuple2(
+								$elm$core$Result$Ok(_List_Nil),
+								firstRowNumber),
+							rows).a));
+			},
+			A2($BrianHicks$elm_csv$Csv$Decode$getFieldNames, fieldNames, allRows));
+	});
+var $BrianHicks$elm_csv$Csv$Parser$AdditionalCharactersAfterClosingQuote = function (a) {
+	return {$: 'AdditionalCharactersAfterClosingQuote', a: a};
+};
+var $BrianHicks$elm_csv$Csv$Parser$SourceEndedWithoutClosingQuote = function (a) {
+	return {$: 'SourceEndedWithoutClosingQuote', a: a};
+};
+var $elm$core$String$cons = _String_cons;
+var $elm$core$String$fromChar = function (_char) {
+	return A2($elm$core$String$cons, _char, '');
+};
+var $elm$core$Basics$ge = _Utils_ge;
+var $BrianHicks$elm_csv$Csv$Parser$parse = F2(
+	function (config, source) {
+		var finalLength = $elm$core$String$length(source);
+		var parseQuotedField = F4(
+			function (isFieldSeparator, soFar, startOffset, endOffset) {
+				parseQuotedField:
+				while (true) {
+					if ((endOffset - finalLength) >= 0) {
+						return $elm$core$Result$Err($BrianHicks$elm_csv$Csv$Parser$SourceEndedWithoutClosingQuote);
+					} else {
+						if (A3($elm$core$String$slice, endOffset, endOffset + 1, source) === '\"') {
+							var segment = A3($elm$core$String$slice, startOffset, endOffset, source);
+							if (((endOffset + 1) - finalLength) >= 0) {
+								return $elm$core$Result$Ok(
+									_Utils_Tuple3(
+										_Utils_ap(soFar, segment),
+										endOffset + 1,
+										false));
+							} else {
+								var next = A3($elm$core$String$slice, endOffset + 1, endOffset + 2, source);
+								if (next === '\"') {
+									var newPos = endOffset + 2;
+									var $temp$isFieldSeparator = isFieldSeparator,
+										$temp$soFar = soFar + (segment + '\"'),
+										$temp$startOffset = newPos,
+										$temp$endOffset = newPos;
+									isFieldSeparator = $temp$isFieldSeparator;
+									soFar = $temp$soFar;
+									startOffset = $temp$startOffset;
+									endOffset = $temp$endOffset;
+									continue parseQuotedField;
+								} else {
+									if (isFieldSeparator(next)) {
+										return $elm$core$Result$Ok(
+											_Utils_Tuple3(
+												_Utils_ap(soFar, segment),
+												endOffset + 2,
+												false));
+									} else {
+										if (next === '\n') {
+											return $elm$core$Result$Ok(
+												_Utils_Tuple3(
+													_Utils_ap(soFar, segment),
+													endOffset + 2,
+													true));
+										} else {
+											if ((next === '\u000D') && (A3($elm$core$String$slice, endOffset + 2, endOffset + 3, source) === '\n')) {
+												return $elm$core$Result$Ok(
+													_Utils_Tuple3(
+														_Utils_ap(soFar, segment),
+														endOffset + 3,
+														true));
+											} else {
+												return $elm$core$Result$Err($BrianHicks$elm_csv$Csv$Parser$AdditionalCharactersAfterClosingQuote);
+											}
+										}
+									}
+								}
+							}
+						} else {
+							var $temp$isFieldSeparator = isFieldSeparator,
+								$temp$soFar = soFar,
+								$temp$startOffset = startOffset,
+								$temp$endOffset = endOffset + 1;
+							isFieldSeparator = $temp$isFieldSeparator;
+							soFar = $temp$soFar;
+							startOffset = $temp$startOffset;
+							endOffset = $temp$endOffset;
+							continue parseQuotedField;
+						}
+					}
+				}
+			});
+		var parseComma = F4(
+			function (row, rows, startOffset, endOffset) {
+				parseComma:
+				while (true) {
+					if ((endOffset - finalLength) >= 0) {
+						var finalField = A3($elm$core$String$slice, startOffset, endOffset, source);
+						return ((finalField === '') && _Utils_eq(row, _List_Nil)) ? $elm$core$Result$Ok(
+							$elm$core$List$reverse(rows)) : $elm$core$Result$Ok(
+							$elm$core$List$reverse(
+								A2(
+									$elm$core$List$cons,
+									$elm$core$List$reverse(
+										A2($elm$core$List$cons, finalField, row)),
+									rows)));
+					} else {
+						var first = A3($elm$core$String$slice, endOffset, endOffset + 1, source);
+						if (first === ',') {
+							var newPos = endOffset + 1;
+							var $temp$row = A2(
+								$elm$core$List$cons,
+								A3($elm$core$String$slice, startOffset, endOffset, source),
+								row),
+								$temp$rows = rows,
+								$temp$startOffset = newPos,
+								$temp$endOffset = newPos;
+							row = $temp$row;
+							rows = $temp$rows;
+							startOffset = $temp$startOffset;
+							endOffset = $temp$endOffset;
+							continue parseComma;
+						} else {
+							if (first === '\n') {
+								var newPos = endOffset + 1;
+								var $temp$row = _List_Nil,
+									$temp$rows = A2(
+									$elm$core$List$cons,
+									$elm$core$List$reverse(
+										A2(
+											$elm$core$List$cons,
+											A3($elm$core$String$slice, startOffset, endOffset, source),
+											row)),
+									rows),
+									$temp$startOffset = newPos,
+									$temp$endOffset = newPos;
+								row = $temp$row;
+								rows = $temp$rows;
+								startOffset = $temp$startOffset;
+								endOffset = $temp$endOffset;
+								continue parseComma;
+							} else {
+								if ((first === '\u000D') && (A3($elm$core$String$slice, endOffset + 1, endOffset + 2, source) === '\n')) {
+									var newPos = endOffset + 2;
+									var $temp$row = _List_Nil,
+										$temp$rows = A2(
+										$elm$core$List$cons,
+										$elm$core$List$reverse(
+											A2(
+												$elm$core$List$cons,
+												A3($elm$core$String$slice, startOffset, endOffset, source),
+												row)),
+										rows),
+										$temp$startOffset = newPos,
+										$temp$endOffset = newPos;
+									row = $temp$row;
+									rows = $temp$rows;
+									startOffset = $temp$startOffset;
+									endOffset = $temp$endOffset;
+									continue parseComma;
+								} else {
+									if (first === '\"') {
+										var newPos = endOffset + 1;
+										var _v0 = A4(
+											parseQuotedField,
+											function (c) {
+												return c === ',';
+											},
+											'',
+											newPos,
+											newPos);
+										if (_v0.$ === 'Ok') {
+											var _v1 = _v0.a;
+											var value = _v1.a;
+											var afterQuotedField = _v1.b;
+											var rowEnded = _v1.c;
+											if (_Utils_cmp(afterQuotedField, finalLength) > -1) {
+												return $elm$core$Result$Ok(
+													$elm$core$List$reverse(
+														A2(
+															$elm$core$List$cons,
+															$elm$core$List$reverse(
+																A2($elm$core$List$cons, value, row)),
+															rows)));
+											} else {
+												if (rowEnded) {
+													var $temp$row = _List_Nil,
+														$temp$rows = A2(
+														$elm$core$List$cons,
+														$elm$core$List$reverse(
+															A2($elm$core$List$cons, value, row)),
+														rows),
+														$temp$startOffset = afterQuotedField,
+														$temp$endOffset = afterQuotedField;
+													row = $temp$row;
+													rows = $temp$rows;
+													startOffset = $temp$startOffset;
+													endOffset = $temp$endOffset;
+													continue parseComma;
+												} else {
+													var $temp$row = A2($elm$core$List$cons, value, row),
+														$temp$rows = rows,
+														$temp$startOffset = afterQuotedField,
+														$temp$endOffset = afterQuotedField;
+													row = $temp$row;
+													rows = $temp$rows;
+													startOffset = $temp$startOffset;
+													endOffset = $temp$endOffset;
+													continue parseComma;
+												}
+											}
+										} else {
+											var problem = _v0.a;
+											return $elm$core$Result$Err(
+												problem(
+													$elm$core$List$length(rows) + 1));
+										}
+									} else {
+										var $temp$row = row,
+											$temp$rows = rows,
+											$temp$startOffset = startOffset,
+											$temp$endOffset = endOffset + 1;
+										row = $temp$row;
+										rows = $temp$rows;
+										startOffset = $temp$startOffset;
+										endOffset = $temp$endOffset;
+										continue parseComma;
+									}
+								}
+							}
+						}
+					}
+				}
+			});
+		var parseHelp = F5(
+			function (isFieldSeparator, row, rows, startOffset, endOffset) {
+				parseHelp:
+				while (true) {
+					if ((endOffset - finalLength) >= 0) {
+						var finalField = A3($elm$core$String$slice, startOffset, endOffset, source);
+						return ((finalField === '') && _Utils_eq(row, _List_Nil)) ? $elm$core$Result$Ok(
+							$elm$core$List$reverse(rows)) : $elm$core$Result$Ok(
+							$elm$core$List$reverse(
+								A2(
+									$elm$core$List$cons,
+									$elm$core$List$reverse(
+										A2($elm$core$List$cons, finalField, row)),
+									rows)));
+					} else {
+						var first = A3($elm$core$String$slice, endOffset, endOffset + 1, source);
+						if (isFieldSeparator(first)) {
+							var newPos = endOffset + 1;
+							var $temp$isFieldSeparator = isFieldSeparator,
+								$temp$row = A2(
+								$elm$core$List$cons,
+								A3($elm$core$String$slice, startOffset, endOffset, source),
+								row),
+								$temp$rows = rows,
+								$temp$startOffset = newPos,
+								$temp$endOffset = newPos;
+							isFieldSeparator = $temp$isFieldSeparator;
+							row = $temp$row;
+							rows = $temp$rows;
+							startOffset = $temp$startOffset;
+							endOffset = $temp$endOffset;
+							continue parseHelp;
+						} else {
+							if (first === '\n') {
+								var newPos = endOffset + 1;
+								var $temp$isFieldSeparator = isFieldSeparator,
+									$temp$row = _List_Nil,
+									$temp$rows = A2(
+									$elm$core$List$cons,
+									$elm$core$List$reverse(
+										A2(
+											$elm$core$List$cons,
+											A3($elm$core$String$slice, startOffset, endOffset, source),
+											row)),
+									rows),
+									$temp$startOffset = newPos,
+									$temp$endOffset = newPos;
+								isFieldSeparator = $temp$isFieldSeparator;
+								row = $temp$row;
+								rows = $temp$rows;
+								startOffset = $temp$startOffset;
+								endOffset = $temp$endOffset;
+								continue parseHelp;
+							} else {
+								if ((first === '\u000D') && (A3($elm$core$String$slice, endOffset + 1, endOffset + 2, source) === '\n')) {
+									var newPos = endOffset + 2;
+									var $temp$isFieldSeparator = isFieldSeparator,
+										$temp$row = _List_Nil,
+										$temp$rows = A2(
+										$elm$core$List$cons,
+										$elm$core$List$reverse(
+											A2(
+												$elm$core$List$cons,
+												A3($elm$core$String$slice, startOffset, endOffset, source),
+												row)),
+										rows),
+										$temp$startOffset = newPos,
+										$temp$endOffset = newPos;
+									isFieldSeparator = $temp$isFieldSeparator;
+									row = $temp$row;
+									rows = $temp$rows;
+									startOffset = $temp$startOffset;
+									endOffset = $temp$endOffset;
+									continue parseHelp;
+								} else {
+									if (first === '\"') {
+										var newPos = endOffset + 1;
+										var _v2 = A4(parseQuotedField, isFieldSeparator, '', newPos, newPos);
+										if (_v2.$ === 'Ok') {
+											var _v3 = _v2.a;
+											var value = _v3.a;
+											var afterQuotedField = _v3.b;
+											var rowEnded = _v3.c;
+											if (_Utils_cmp(afterQuotedField, finalLength) > -1) {
+												return $elm$core$Result$Ok(
+													$elm$core$List$reverse(
+														A2(
+															$elm$core$List$cons,
+															$elm$core$List$reverse(
+																A2($elm$core$List$cons, value, row)),
+															rows)));
+											} else {
+												if (rowEnded) {
+													var $temp$isFieldSeparator = isFieldSeparator,
+														$temp$row = _List_Nil,
+														$temp$rows = A2(
+														$elm$core$List$cons,
+														$elm$core$List$reverse(
+															A2($elm$core$List$cons, value, row)),
+														rows),
+														$temp$startOffset = afterQuotedField,
+														$temp$endOffset = afterQuotedField;
+													isFieldSeparator = $temp$isFieldSeparator;
+													row = $temp$row;
+													rows = $temp$rows;
+													startOffset = $temp$startOffset;
+													endOffset = $temp$endOffset;
+													continue parseHelp;
+												} else {
+													var $temp$isFieldSeparator = isFieldSeparator,
+														$temp$row = A2($elm$core$List$cons, value, row),
+														$temp$rows = rows,
+														$temp$startOffset = afterQuotedField,
+														$temp$endOffset = afterQuotedField;
+													isFieldSeparator = $temp$isFieldSeparator;
+													row = $temp$row;
+													rows = $temp$rows;
+													startOffset = $temp$startOffset;
+													endOffset = $temp$endOffset;
+													continue parseHelp;
+												}
+											}
+										} else {
+											var problem = _v2.a;
+											return $elm$core$Result$Err(
+												problem(
+													$elm$core$List$length(rows) + 1));
+										}
+									} else {
+										var $temp$isFieldSeparator = isFieldSeparator,
+											$temp$row = row,
+											$temp$rows = rows,
+											$temp$startOffset = startOffset,
+											$temp$endOffset = endOffset + 1;
+										isFieldSeparator = $temp$isFieldSeparator;
+										row = $temp$row;
+										rows = $temp$rows;
+										startOffset = $temp$startOffset;
+										endOffset = $temp$endOffset;
+										continue parseHelp;
+									}
+								}
+							}
+						}
+					}
+				}
+			});
+		var parseSemicolon = F4(
+			function (row, rows, startOffset, endOffset) {
+				parseSemicolon:
+				while (true) {
+					if ((endOffset - finalLength) >= 0) {
+						var finalField = A3($elm$core$String$slice, startOffset, endOffset, source);
+						return ((finalField === '') && _Utils_eq(row, _List_Nil)) ? $elm$core$Result$Ok(
+							$elm$core$List$reverse(rows)) : $elm$core$Result$Ok(
+							$elm$core$List$reverse(
+								A2(
+									$elm$core$List$cons,
+									$elm$core$List$reverse(
+										A2($elm$core$List$cons, finalField, row)),
+									rows)));
+					} else {
+						var first = A3($elm$core$String$slice, endOffset, endOffset + 1, source);
+						if (first === ';') {
+							var newPos = endOffset + 1;
+							var $temp$row = A2(
+								$elm$core$List$cons,
+								A3($elm$core$String$slice, startOffset, endOffset, source),
+								row),
+								$temp$rows = rows,
+								$temp$startOffset = newPos,
+								$temp$endOffset = newPos;
+							row = $temp$row;
+							rows = $temp$rows;
+							startOffset = $temp$startOffset;
+							endOffset = $temp$endOffset;
+							continue parseSemicolon;
+						} else {
+							if (first === '\n') {
+								var newPos = endOffset + 1;
+								var $temp$row = _List_Nil,
+									$temp$rows = A2(
+									$elm$core$List$cons,
+									$elm$core$List$reverse(
+										A2(
+											$elm$core$List$cons,
+											A3($elm$core$String$slice, startOffset, endOffset, source),
+											row)),
+									rows),
+									$temp$startOffset = newPos,
+									$temp$endOffset = newPos;
+								row = $temp$row;
+								rows = $temp$rows;
+								startOffset = $temp$startOffset;
+								endOffset = $temp$endOffset;
+								continue parseSemicolon;
+							} else {
+								if ((first === '\u000D') && (A3($elm$core$String$slice, endOffset + 1, endOffset + 2, source) === '\n')) {
+									var newPos = endOffset + 2;
+									var $temp$row = _List_Nil,
+										$temp$rows = A2(
+										$elm$core$List$cons,
+										$elm$core$List$reverse(
+											A2(
+												$elm$core$List$cons,
+												A3($elm$core$String$slice, startOffset, endOffset, source),
+												row)),
+										rows),
+										$temp$startOffset = newPos,
+										$temp$endOffset = newPos;
+									row = $temp$row;
+									rows = $temp$rows;
+									startOffset = $temp$startOffset;
+									endOffset = $temp$endOffset;
+									continue parseSemicolon;
+								} else {
+									if (first === '\"') {
+										var newPos = endOffset + 1;
+										var _v4 = A4(
+											parseQuotedField,
+											function (c) {
+												return c === ';';
+											},
+											'',
+											newPos,
+											newPos);
+										if (_v4.$ === 'Ok') {
+											var _v5 = _v4.a;
+											var value = _v5.a;
+											var afterQuotedField = _v5.b;
+											var rowEnded = _v5.c;
+											if (_Utils_cmp(afterQuotedField, finalLength) > -1) {
+												return $elm$core$Result$Ok(
+													$elm$core$List$reverse(
+														A2(
+															$elm$core$List$cons,
+															$elm$core$List$reverse(
+																A2($elm$core$List$cons, value, row)),
+															rows)));
+											} else {
+												if (rowEnded) {
+													var $temp$row = _List_Nil,
+														$temp$rows = A2(
+														$elm$core$List$cons,
+														$elm$core$List$reverse(
+															A2($elm$core$List$cons, value, row)),
+														rows),
+														$temp$startOffset = afterQuotedField,
+														$temp$endOffset = afterQuotedField;
+													row = $temp$row;
+													rows = $temp$rows;
+													startOffset = $temp$startOffset;
+													endOffset = $temp$endOffset;
+													continue parseSemicolon;
+												} else {
+													var $temp$row = A2($elm$core$List$cons, value, row),
+														$temp$rows = rows,
+														$temp$startOffset = afterQuotedField,
+														$temp$endOffset = afterQuotedField;
+													row = $temp$row;
+													rows = $temp$rows;
+													startOffset = $temp$startOffset;
+													endOffset = $temp$endOffset;
+													continue parseSemicolon;
+												}
+											}
+										} else {
+											var problem = _v4.a;
+											return $elm$core$Result$Err(
+												problem(
+													$elm$core$List$length(rows) + 1));
+										}
+									} else {
+										var $temp$row = row,
+											$temp$rows = rows,
+											$temp$startOffset = startOffset,
+											$temp$endOffset = endOffset + 1;
+										row = $temp$row;
+										rows = $temp$rows;
+										startOffset = $temp$startOffset;
+										endOffset = $temp$endOffset;
+										continue parseSemicolon;
+									}
+								}
+							}
+						}
+					}
+				}
+			});
+		var fieldSeparator = $elm$core$String$fromChar(config.fieldSeparator);
+		return $elm$core$String$isEmpty(source) ? $elm$core$Result$Ok(_List_Nil) : (_Utils_eq(
+			config.fieldSeparator,
+			_Utils_chr(',')) ? A4(parseComma, _List_Nil, _List_Nil, 0, 0) : (_Utils_eq(
+			config.fieldSeparator,
+			_Utils_chr(';')) ? A4(parseSemicolon, _List_Nil, _List_Nil, 0, 0) : A5(
+			parseHelp,
+			function (s) {
+				return _Utils_eq(s, fieldSeparator);
+			},
 			_List_Nil,
-			list);
+			_List_Nil,
+			0,
+			0)));
+	});
+var $BrianHicks$elm_csv$Csv$Decode$decodeCustom = F4(
+	function (config, fieldNames, decoder, source) {
+		return A2(
+			$elm$core$Result$andThen,
+			A2($BrianHicks$elm_csv$Csv$Decode$applyDecoder, fieldNames, decoder),
+			A2(
+				$elm$core$Result$mapError,
+				$BrianHicks$elm_csv$Csv$Decode$ParsingError,
+				A2($BrianHicks$elm_csv$Csv$Parser$parse, config, source)));
+	});
+var $BrianHicks$elm_csv$Csv$Decode$decodeCsv = $BrianHicks$elm_csv$Csv$Decode$decodeCustom(
+	{
+		fieldSeparator: _Utils_chr(',')
+	});
+var $author$project$Main$Smartphone = function (id) {
+	return function (brand) {
+		return function (model) {
+			return function (price) {
+				return function (rating) {
+					return function (g5) {
+						return function (nfc) {
+							return function (ir_blaster) {
+								return function (processor_name) {
+									return function (processor_brand) {
+										return function (num_cors) {
+											return function (processor_speed) {
+												return function (battery) {
+													return function (fast_charging) {
+														return function (memory) {
+															return function (ram) {
+																return function (screen_size) {
+																	return function (resolution) {
+																		return function (refresh_rate) {
+																			return function (camera) {
+																				return function (card) {
+																					return function (os) {
+																						return {battery: battery, brand: brand, camera: camera, card: card, fast_charging: fast_charging, g5: g5, id: id, ir_blaster: ir_blaster, memory: memory, model: model, nfc: nfc, num_cors: num_cors, os: os, price: price, processor_brand: processor_brand, processor_name: processor_name, processor_speed: processor_speed, ram: ram, rating: rating, refresh_rate: refresh_rate, resolution: resolution, screen_size: screen_size};
+																					};
+																				};
+																			};
+																		};
+																	};
+																};
+															};
+														};
+													};
+												};
+											};
+										};
+									};
+								};
+							};
+						};
+					};
+				};
+			};
+		};
+	};
+};
+var $BrianHicks$elm_csv$Csv$Decode$Decoder = function (a) {
+	return {$: 'Decoder', a: a};
+};
+var $BrianHicks$elm_csv$Csv$Decode$andThen = F2(
+	function (next, _v0) {
+		var first = _v0.a;
+		return $BrianHicks$elm_csv$Csv$Decode$Decoder(
+			F4(
+				function (location, fieldNames, rowNum, row) {
+					return A2(
+						$elm$core$Result$andThen,
+						function (nextValue) {
+							var _v1 = next(nextValue);
+							var _final = _v1.a;
+							return A4(_final, location, fieldNames, rowNum, row);
+						},
+						A4(first, location, fieldNames, rowNum, row));
+				}));
+	});
+var $BrianHicks$elm_csv$Csv$Decode$map = F2(
+	function (transform, _v0) {
+		var decoder = _v0.a;
+		return $BrianHicks$elm_csv$Csv$Decode$Decoder(
+			F4(
+				function (location, fieldNames, rowNum, row) {
+					return A2(
+						$elm$core$Result$map,
+						transform,
+						A4(decoder, location, fieldNames, rowNum, row));
+				}));
+	});
+var $BrianHicks$elm_csv$Csv$Decode$ColumnNotFound = function (a) {
+	return {$: 'ColumnNotFound', a: a};
+};
+var $BrianHicks$elm_csv$Csv$Decode$ExpectedOneColumn = function (a) {
+	return {$: 'ExpectedOneColumn', a: a};
+};
+var $BrianHicks$elm_csv$Csv$Decode$FieldDecodingError = function (a) {
+	return {$: 'FieldDecodingError', a: a};
+};
+var $BrianHicks$elm_csv$Csv$Decode$FieldNotFound = function (a) {
+	return {$: 'FieldNotFound', a: a};
+};
+var $BrianHicks$elm_csv$Csv$Decode$FieldNotProvided = function (a) {
+	return {$: 'FieldNotProvided', a: a};
+};
+var $elm$core$List$drop = F2(
+	function (n, list) {
+		drop:
+		while (true) {
+			if (n <= 0) {
+				return list;
+			} else {
+				if (!list.b) {
+					return list;
+				} else {
+					var x = list.a;
+					var xs = list.b;
+					var $temp$n = n - 1,
+						$temp$list = xs;
+					n = $temp$n;
+					list = $temp$list;
+					continue drop;
+				}
+			}
+		}
 	});
 var $elm$core$List$head = function (list) {
 	if (list.b) {
@@ -6199,59 +6997,460 @@ var $elm$core$List$head = function (list) {
 		return $elm$core$Maybe$Nothing;
 	}
 };
+var $BrianHicks$elm_csv$Csv$Decode$Column = function (a) {
+	return {$: 'Column', a: a};
+};
+var $BrianHicks$elm_csv$Csv$Decode$Field = F2(
+	function (a, b) {
+		return {$: 'Field', a: a, b: b};
+	});
+var $BrianHicks$elm_csv$Csv$Decode$OnlyColumn = {$: 'OnlyColumn'};
+var $BrianHicks$elm_csv$Csv$Decode$locationToColumn = F2(
+	function (fieldNames, location) {
+		switch (location.$) {
+			case 'Column_':
+				var i = location.a;
+				return $BrianHicks$elm_csv$Csv$Decode$Column(i);
+			case 'Field_':
+				var name = location.a;
+				return A2(
+					$BrianHicks$elm_csv$Csv$Decode$Field,
+					name,
+					A2($elm$core$Dict$get, name, fieldNames));
+			default:
+				return $BrianHicks$elm_csv$Csv$Decode$OnlyColumn;
+		}
+	});
+var $BrianHicks$elm_csv$Csv$Decode$fromString = function (convert) {
+	return $BrianHicks$elm_csv$Csv$Decode$Decoder(
+		F4(
+			function (location, _v0, rowNum, row) {
+				var names = _v0.names;
+				var error = function (problem) {
+					return $elm$core$Result$Err(
+						_List_fromArray(
+							[
+								$BrianHicks$elm_csv$Csv$Decode$FieldDecodingError(
+								{
+									column: A2($BrianHicks$elm_csv$Csv$Decode$locationToColumn, names, location),
+									problem: problem,
+									row: rowNum
+								})
+							]));
+				};
+				switch (location.$) {
+					case 'Column_':
+						var colNum = location.a;
+						var _v2 = $elm$core$List$head(
+							A2($elm$core$List$drop, colNum, row));
+						if (_v2.$ === 'Just') {
+							var value = _v2.a;
+							var _v3 = convert(value);
+							if (_v3.$ === 'Ok') {
+								var converted = _v3.a;
+								return $elm$core$Result$Ok(converted);
+							} else {
+								var problem = _v3.a;
+								return error(problem);
+							}
+						} else {
+							return error(
+								$BrianHicks$elm_csv$Csv$Decode$ColumnNotFound(colNum));
+						}
+					case 'Field_':
+						var name = location.a;
+						var _v4 = A2($elm$core$Dict$get, name, names);
+						if (_v4.$ === 'Just') {
+							var colNum = _v4.a;
+							var _v5 = $elm$core$List$head(
+								A2($elm$core$List$drop, colNum, row));
+							if (_v5.$ === 'Just') {
+								var value = _v5.a;
+								var _v6 = convert(value);
+								if (_v6.$ === 'Ok') {
+									var converted = _v6.a;
+									return $elm$core$Result$Ok(converted);
+								} else {
+									var problem = _v6.a;
+									return error(problem);
+								}
+							} else {
+								return error(
+									$BrianHicks$elm_csv$Csv$Decode$FieldNotFound(name));
+							}
+						} else {
+							return $elm$core$Result$Err(
+								_List_fromArray(
+									[
+										$BrianHicks$elm_csv$Csv$Decode$FieldNotProvided(name)
+									]));
+						}
+					default:
+						if (!row.b) {
+							return error(
+								$BrianHicks$elm_csv$Csv$Decode$ColumnNotFound(0));
+						} else {
+							if (!row.b.b) {
+								var only = row.a;
+								var _v8 = convert(only);
+								if (_v8.$ === 'Ok') {
+									var converted = _v8.a;
+									return $elm$core$Result$Ok(converted);
+								} else {
+									var problem = _v8.a;
+									return error(problem);
+								}
+							} else {
+								return error(
+									$BrianHicks$elm_csv$Csv$Decode$ExpectedOneColumn(
+										$elm$core$List$length(row)));
+							}
+						}
+				}
+			}));
+};
+var $BrianHicks$elm_csv$Csv$Decode$string = $BrianHicks$elm_csv$Csv$Decode$fromString($elm$core$Result$Ok);
+var $BrianHicks$elm_csv$Csv$Decode$succeed = function (value) {
+	return $BrianHicks$elm_csv$Csv$Decode$Decoder(
+		F4(
+			function (_v0, _v1, _v2, _v3) {
+				return $elm$core$Result$Ok(value);
+			}));
+};
+var $BrianHicks$elm_csv$Csv$Decode$blank = function (decoder) {
+	return A2(
+		$BrianHicks$elm_csv$Csv$Decode$andThen,
+		function (maybeBlank) {
+			return $elm$core$String$isEmpty(
+				$elm$core$String$trim(maybeBlank)) ? $BrianHicks$elm_csv$Csv$Decode$succeed($elm$core$Maybe$Nothing) : A2($BrianHicks$elm_csv$Csv$Decode$map, $elm$core$Maybe$Just, decoder);
+		},
+		$BrianHicks$elm_csv$Csv$Decode$string);
+};
+var $BrianHicks$elm_csv$Csv$Decode$Field_ = function (a) {
+	return {$: 'Field_', a: a};
+};
+var $BrianHicks$elm_csv$Csv$Decode$field = F2(
+	function (name, _v0) {
+		var decoder = _v0.a;
+		return $BrianHicks$elm_csv$Csv$Decode$Decoder(
+			F3(
+				function (_v1, fieldNames, row) {
+					return A3(
+						decoder,
+						$BrianHicks$elm_csv$Csv$Decode$Field_(name),
+						fieldNames,
+						row);
+				}));
+	});
+var $BrianHicks$elm_csv$Csv$Decode$ExpectedFloat = function (a) {
+	return {$: 'ExpectedFloat', a: a};
+};
 var $elm$core$String$toFloat = _String_toFloat;
-var $author$project$Main$parseRow = F2(
-	function (headers, row) {
-		var values = A2($elm$core$String$split, ',', row);
-		var lookup = function (key) {
-			var _v0 = $elm$core$List$head(
-				A2(
-					$elm$core$List$filter,
-					function (_v1) {
-						var k = _v1.a;
-						return _Utils_eq(k, key);
-					},
-					A3(
-						$elm$core$List$map2,
-						F2(
-							function (h, v) {
-								return _Utils_Tuple2(h, v);
-							}),
-						headers,
-						values)));
-			if (_v0.$ === 'Just') {
-				var _v2 = _v0.a;
-				var value = _v2.b;
-				return value;
-			} else {
-				return '';
+var $BrianHicks$elm_csv$Csv$Decode$float = $BrianHicks$elm_csv$Csv$Decode$fromString(
+	function (value) {
+		var _v0 = $elm$core$String$toFloat(
+			$elm$core$String$trim(value));
+		if (_v0.$ === 'Just') {
+			var parsed = _v0.a;
+			return $elm$core$Result$Ok(parsed);
+		} else {
+			return $elm$core$Result$Err(
+				$BrianHicks$elm_csv$Csv$Decode$ExpectedFloat(value));
+		}
+	});
+var $BrianHicks$elm_csv$Csv$Decode$ExpectedInt = function (a) {
+	return {$: 'ExpectedInt', a: a};
+};
+var $BrianHicks$elm_csv$Csv$Decode$int = $BrianHicks$elm_csv$Csv$Decode$fromString(
+	function (value) {
+		var _v0 = $elm$core$String$toInt(
+			$elm$core$String$trim(value));
+		if (_v0.$ === 'Just') {
+			var parsed = _v0.a;
+			return $elm$core$Result$Ok(parsed);
+		} else {
+			return $elm$core$Result$Err(
+				$BrianHicks$elm_csv$Csv$Decode$ExpectedInt(value));
+		}
+	});
+var $BrianHicks$elm_csv$Csv$Decode$into = $BrianHicks$elm_csv$Csv$Decode$succeed;
+var $BrianHicks$elm_csv$Csv$Decode$map2 = F3(
+	function (transform, _v0, _v1) {
+		var decodeA = _v0.a;
+		var decodeB = _v1.a;
+		return $BrianHicks$elm_csv$Csv$Decode$Decoder(
+			F4(
+				function (location, fieldNames, rowNum, row) {
+					var _v2 = _Utils_Tuple2(
+						A4(decodeA, location, fieldNames, rowNum, row),
+						A4(decodeB, location, fieldNames, rowNum, row));
+					if (_v2.a.$ === 'Ok') {
+						if (_v2.b.$ === 'Ok') {
+							var a = _v2.a.a;
+							var b = _v2.b.a;
+							return $elm$core$Result$Ok(
+								A2(transform, a, b));
+						} else {
+							var b = _v2.b.a;
+							return $elm$core$Result$Err(b);
+						}
+					} else {
+						if (_v2.b.$ === 'Err') {
+							var a = _v2.a.a;
+							var b = _v2.b.a;
+							return $elm$core$Result$Err(
+								_Utils_ap(a, b));
+						} else {
+							var a = _v2.a.a;
+							return $elm$core$Result$Err(a);
+						}
+					}
+				}));
+	});
+var $BrianHicks$elm_csv$Csv$Decode$pipeline = $BrianHicks$elm_csv$Csv$Decode$map2(
+	F2(
+		function (value, fn) {
+			return fn(value);
+		}));
+var $author$project$Main$toBool = function (str) {
+	_v0$2:
+	while (true) {
+		if (str.$ === 'Just') {
+			switch (str.a) {
+				case 'True':
+					return $elm$core$Maybe$Just(true);
+				case 'False':
+					return $elm$core$Maybe$Just(false);
+				default:
+					break _v0$2;
 			}
-		};
-		var model = lookup('model');
-		var nfc = (lookup('NFC') === 'True') ? true : false;
-		var price = $elm$core$String$toFloat(
-			lookup('price'));
-		var rating = $elm$core$String$toFloat(
-			lookup('rating'));
-		var ir_blaster = (lookup('IR_blaster') === 'True') ? true : false;
-		var id = lookup('index');
-		var g5 = (lookup('5G') === 'True') ? true : false;
-		var brand = lookup('brand');
-		return A8($author$project$Main$Smartphone, id, brand, model, price, rating, g5, nfc, ir_blaster);
+		} else {
+			break _v0$2;
+		}
+	}
+	return $elm$core$Maybe$Nothing;
+};
+var $author$project$Main$toCores = function (str) {
+	_v0$4:
+	while (true) {
+		if (str.$ === 'Just') {
+			switch (str.a) {
+				case 'dual core':
+					return $elm$core$Maybe$Just(2);
+				case 'quad core':
+					return $elm$core$Maybe$Just(4);
+				case 'hexa core':
+					return $elm$core$Maybe$Just(6);
+				case 'octa core':
+					return $elm$core$Maybe$Just(8);
+				default:
+					break _v0$4;
+			}
+		} else {
+			break _v0$4;
+		}
+	}
+	return $elm$core$Maybe$Nothing;
+};
+var $elm$core$String$replace = F3(
+	function (before, after, string) {
+		return A2(
+			$elm$core$String$join,
+			after,
+			A2($elm$core$String$split, before, string));
 	});
+var $elm$core$Maybe$withDefault = F2(
+	function (_default, maybe) {
+		if (maybe.$ === 'Just') {
+			var value = maybe.a;
+			return value;
+		} else {
+			return _default;
+		}
+	});
+var $author$project$Main$toGB = function (str) {
+	return $elm$core$String$toFloat(
+		$elm$core$String$trim(
+			A3(
+				$elm$core$String$replace,
+				'GB inbuilt',
+				'',
+				A2($elm$core$Maybe$withDefault, '', str))));
+};
+var $author$project$Main$toGHz = function (str) {
+	return $elm$core$String$toFloat(
+		$elm$core$String$trim(
+			A3(
+				$elm$core$String$replace,
+				'GHz Processor',
+				'',
+				A2($elm$core$Maybe$withDefault, '', str))));
+};
+var $author$project$Main$toInche = function (str) {
+	return $elm$core$String$toFloat(
+		$elm$core$String$trim(
+			A3(
+				$elm$core$String$replace,
+				'inches',
+				'',
+				A2($elm$core$Maybe$withDefault, '', str))));
+};
+var $author$project$Main$decoder = A2(
+	$BrianHicks$elm_csv$Csv$Decode$pipeline,
+	A2(
+		$BrianHicks$elm_csv$Csv$Decode$field,
+		'os',
+		$BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string)),
+	A2(
+		$BrianHicks$elm_csv$Csv$Decode$pipeline,
+		A2(
+			$BrianHicks$elm_csv$Csv$Decode$field,
+			'card',
+			$BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string)),
+		A2(
+			$BrianHicks$elm_csv$Csv$Decode$pipeline,
+			A2(
+				$BrianHicks$elm_csv$Csv$Decode$field,
+				'camera',
+				$BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string)),
+			A2(
+				$BrianHicks$elm_csv$Csv$Decode$pipeline,
+				A2(
+					$BrianHicks$elm_csv$Csv$Decode$field,
+					'refresh_rate',
+					$BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$int)),
+				A2(
+					$BrianHicks$elm_csv$Csv$Decode$pipeline,
+					A2(
+						$BrianHicks$elm_csv$Csv$Decode$field,
+						'resolution',
+						$BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string)),
+					A2(
+						$BrianHicks$elm_csv$Csv$Decode$pipeline,
+						A2(
+							$BrianHicks$elm_csv$Csv$Decode$field,
+							'screen_size',
+							A2(
+								$BrianHicks$elm_csv$Csv$Decode$map,
+								$author$project$Main$toInche,
+								$BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string))),
+						A2(
+							$BrianHicks$elm_csv$Csv$Decode$pipeline,
+							A2(
+								$BrianHicks$elm_csv$Csv$Decode$field,
+								'RAM',
+								$BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$float)),
+							A2(
+								$BrianHicks$elm_csv$Csv$Decode$pipeline,
+								A2(
+									$BrianHicks$elm_csv$Csv$Decode$field,
+									'Internal_mem',
+									A2(
+										$BrianHicks$elm_csv$Csv$Decode$map,
+										$author$project$Main$toGB,
+										$BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string))),
+								A2(
+									$BrianHicks$elm_csv$Csv$Decode$pipeline,
+									A2(
+										$BrianHicks$elm_csv$Csv$Decode$field,
+										'fast_charging',
+										$BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$float)),
+									A2(
+										$BrianHicks$elm_csv$Csv$Decode$pipeline,
+										A2(
+											$BrianHicks$elm_csv$Csv$Decode$field,
+											'Battery',
+											$BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$float)),
+										A2(
+											$BrianHicks$elm_csv$Csv$Decode$pipeline,
+											A2(
+												$BrianHicks$elm_csv$Csv$Decode$field,
+												'processor_speed',
+												A2(
+													$BrianHicks$elm_csv$Csv$Decode$map,
+													$author$project$Main$toGHz,
+													$BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string))),
+											A2(
+												$BrianHicks$elm_csv$Csv$Decode$pipeline,
+												A2(
+													$BrianHicks$elm_csv$Csv$Decode$field,
+													'num_cores',
+													A2(
+														$BrianHicks$elm_csv$Csv$Decode$map,
+														$author$project$Main$toCores,
+														$BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string))),
+												A2(
+													$BrianHicks$elm_csv$Csv$Decode$pipeline,
+													A2(
+														$BrianHicks$elm_csv$Csv$Decode$field,
+														'processor_brand',
+														$BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string)),
+													A2(
+														$BrianHicks$elm_csv$Csv$Decode$pipeline,
+														A2(
+															$BrianHicks$elm_csv$Csv$Decode$field,
+															'processor_name',
+															$BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string)),
+														A2(
+															$BrianHicks$elm_csv$Csv$Decode$pipeline,
+															A2(
+																$BrianHicks$elm_csv$Csv$Decode$field,
+																'IR_blaster',
+																A2(
+																	$BrianHicks$elm_csv$Csv$Decode$map,
+																	$author$project$Main$toBool,
+																	$BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string))),
+															A2(
+																$BrianHicks$elm_csv$Csv$Decode$pipeline,
+																A2(
+																	$BrianHicks$elm_csv$Csv$Decode$field,
+																	'NFC',
+																	A2(
+																		$BrianHicks$elm_csv$Csv$Decode$map,
+																		$author$project$Main$toBool,
+																		$BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string))),
+																A2(
+																	$BrianHicks$elm_csv$Csv$Decode$pipeline,
+																	A2(
+																		$BrianHicks$elm_csv$Csv$Decode$field,
+																		'5G',
+																		A2(
+																			$BrianHicks$elm_csv$Csv$Decode$map,
+																			$author$project$Main$toBool,
+																			$BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string))),
+																	A2(
+																		$BrianHicks$elm_csv$Csv$Decode$pipeline,
+																		A2(
+																			$BrianHicks$elm_csv$Csv$Decode$field,
+																			'rating',
+																			$BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$float)),
+																		A2(
+																			$BrianHicks$elm_csv$Csv$Decode$pipeline,
+																			A2(
+																				$BrianHicks$elm_csv$Csv$Decode$field,
+																				'price',
+																				$BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$float)),
+																			A2(
+																				$BrianHicks$elm_csv$Csv$Decode$pipeline,
+																				A2(
+																					$BrianHicks$elm_csv$Csv$Decode$field,
+																					'model',
+																					$BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string)),
+																				A2(
+																					$BrianHicks$elm_csv$Csv$Decode$pipeline,
+																					A2(
+																						$BrianHicks$elm_csv$Csv$Decode$field,
+																						'brand',
+																						$BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string)),
+																					A2(
+																						$BrianHicks$elm_csv$Csv$Decode$pipeline,
+																						A2(
+																							$BrianHicks$elm_csv$Csv$Decode$field,
+																							'id',
+																							$BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string)),
+																						$BrianHicks$elm_csv$Csv$Decode$into($author$project$Main$Smartphone)))))))))))))))))))))));
 var $author$project$Main$parseCSV = function (csv) {
-	var _v0 = $elm$core$String$lines(csv);
-	if (!_v0.b) {
-		return _List_Nil;
-	} else {
-		var headerLine = _v0.a;
-		var dataLines = _v0.b;
-		var headers = A2($elm$core$String$split, ',', headerLine);
-		return A2(
-			$elm$core$List$map,
-			$author$project$Main$parseRow(headers),
-			dataLines);
-	}
+	return A3($BrianHicks$elm_csv$Csv$Decode$decodeCsv, $BrianHicks$elm_csv$Csv$Decode$FieldNamesFromFirstRow, $author$project$Main$decoder, csv);
 };
 var $author$project$Main$update = F2(
 	function (msg, model) {
@@ -6261,11 +7460,22 @@ var $author$project$Main$update = F2(
 			if (msg.a.$ === 'Ok') {
 				var csvData = msg.a.a;
 				var parsedData = $author$project$Main$parseCSV(csvData);
-				return _Utils_Tuple2(
-					_Utils_update(
-						model,
-						{csvdata: csvData, data: parsedData, error: $elm$core$Maybe$Nothing}),
-					$elm$core$Platform$Cmd$none);
+				if (parsedData.$ === 'Ok') {
+					var data = parsedData.a;
+					return _Utils_Tuple2(
+						_Utils_update(
+							model,
+							{csvdata: csvData, data: data, error: $elm$core$Maybe$Nothing}),
+						$elm$core$Platform$Cmd$none);
+				} else {
+					return _Utils_Tuple2(
+						_Utils_update(
+							model,
+							{
+								error: $elm$core$Maybe$Just('Failed to parse CSV data')
+							}),
+						$elm$core$Platform$Cmd$none);
+				}
 			} else {
 				return _Utils_Tuple2(
 					_Utils_update(
@@ -6315,21 +7525,17 @@ var $author$project$Scatterplot$mapToPoint = function (smartphone) {
 				};
 			}),
 		smartphone.price,
-		smartphone.rating,
-		$elm$core$Maybe$Just(smartphone.id));
+		smartphone.memory,
+		smartphone.id);
 };
 var $author$project$Scatterplot$filterSmartphones = function (smartphoneList) {
 	var filteredSmartphones = A2($elm$core$List$filterMap, $author$project$Scatterplot$mapToPoint, smartphoneList);
-	return A3($author$project$Scatterplot$XyData, 'price', 'rating', filteredSmartphones);
+	return A3($author$project$Scatterplot$XyData, 'price', 'memory', filteredSmartphones);
 };
 var $elm_community$typed_svg$TypedSvg$Types$AnchorMiddle = {$: 'AnchorMiddle'};
 var $elm_community$typed_svg$TypedSvg$Types$Percent = function (a) {
 	return {$: 'Percent', a: a};
 };
-var $author$project$Scatterplot$Point = F3(
-	function (pointName, x, y) {
-		return {pointName: pointName, x: x, y: y};
-	});
 var $elm_community$typed_svg$TypedSvg$Types$Px = function (a) {
 	return {$: 'Px', a: a};
 };
@@ -6697,15 +7903,6 @@ var $gampleman$elm_visualization$Statistics$extentBy = F2(
 	});
 var $gampleman$elm_visualization$Statistics$extent = $gampleman$elm_visualization$Statistics$extentBy($elm$core$Basics$identity);
 var $author$project$Scatterplot$tickCount = 5;
-var $elm$core$Maybe$withDefault = F2(
-	function (_default, maybe) {
-		if (maybe.$ === 'Just') {
-			var value = maybe.a;
-			return value;
-		} else {
-			return _default;
-		}
-	});
 var $author$project$Scatterplot$wideExtent = function (values) {
 	var tup = A2(
 		$elm$core$Maybe$withDefault,
@@ -6906,11 +8103,6 @@ var $gampleman$elm_visualization$Axis$element = F4(
 						A2($elm$core$List$map, drawTick, opts.ticks)));
 			});
 	});
-var $elm$core$Basics$composeL = F3(
-	function (g, f, x) {
-		return g(
-			f(x));
-	});
 var $elm$svg$Svg$Attributes$x = _VirtualDom_attribute('x');
 var $elm$svg$Svg$Attributes$x1 = _VirtualDom_attribute('x1');
 var $elm$svg$Svg$Attributes$x2 = _VirtualDom_attribute('x2');
@@ -7001,7 +8193,6 @@ var $gampleman$elm_visualization$Scale$Continuous$invertTransform = F4(
 				$gampleman$elm_visualization$Interpolation$float),
 			untransform);
 	});
-var $elm$core$Basics$ge = _Utils_ge;
 var $gampleman$elm_visualization$Scale$Continuous$fixPoint = F3(
 	function (maxIterations, initialInput, fn) {
 		var helper = F2(
@@ -7142,10 +8333,6 @@ var $gampleman$elm_visualization$Statistics$tickStep = F3(
 			$elm$core$Basics$sqrt(2)) > -1) ? (step1 * 2) : step1));
 		return (_Utils_cmp(stop, start) < 0) ? (-step2) : step2;
 	});
-var $elm$core$String$cons = _String_cons;
-var $elm$core$String$fromChar = function (_char) {
-	return A2($elm$core$String$cons, _char, '');
-};
 var $elm$core$Bitwise$and = _Bitwise_and;
 var $elm$core$Bitwise$shiftRightBy = _Bitwise_shiftRightBy;
 var $elm$core$String$repeatHelp = F3(
@@ -7353,10 +8540,6 @@ var $author$project$Scatterplot$scatterplot = function (model) {
 		},
 		model.data);
 	var xScaleLocal = $author$project$Scatterplot$xScale(xValues);
-	var kreisbeschriftung = A2(
-		$elm$core$Maybe$withDefault,
-		A3($author$project$Scatterplot$Point, 'Nothing', 0, 0),
-		$elm$core$List$head(model.data)).pointName;
 	var half = function (t) {
 		return (t.b - t.a) / 2;
 	};
@@ -7439,7 +8622,7 @@ var $author$project$Scatterplot$scatterplot = function (model) {
 							]),
 						_List_fromArray(
 							[
-								$elm$html$Html$text('Rating')
+								$elm$html$Html$text('Memory')
 							]))
 					])),
 				A2(
diff --git a/src/Main.elm b/src/Main.elm
index ab2bafa689ff36dacf0cb7762674963379560615..ba887705a9d9b9babf5c631874919d92206cf1a0 100644
--- a/src/Main.elm
+++ b/src/Main.elm
@@ -1,12 +1,11 @@
 module Main exposing (..)
 
 import Browser
-import Dict exposing (Dict)
-import Html exposing (Html, div, li, text, ul)
+import Csv.Decode as Decode exposing (Decoder)
+import Html exposing (Html, div)
 import Http
-import List exposing (map)
+import Result exposing (Result(..))
 import Scatterplot exposing (viewScatterplot)
-import String exposing (lines, split)
 
 
 
@@ -19,17 +18,32 @@ main =
 
 
 -- MODEL
+-- ohne ram,display
 
 
 type alias Smartphone =
-    { id : String
-    , brand : String
-    , model : String
+    { id : Maybe String
+    , brand : Maybe String
+    , model : Maybe String
     , price : Maybe Float
     , rating : Maybe Float
-    , g5 : Bool
-    , nfc : Bool
-    , ir_blaster : Bool
+    , g5 : Maybe Bool
+    , nfc : Maybe Bool
+    , ir_blaster : Maybe Bool
+    , processor_name : Maybe String
+    , processor_brand : Maybe String
+    , num_cors : Maybe Float
+    , processor_speed : Maybe Float
+    , battery : Maybe Float
+    , fast_charging : Maybe Float
+    , memory : Maybe Float
+    , ram : Maybe Float
+    , screen_size : Maybe Float
+    , resolution : Maybe String
+    , refresh_rate : Maybe Int
+    , camera : Maybe String
+    , card : Maybe String
+    , os : Maybe String
     }
 
 
@@ -65,7 +79,12 @@ update msg model =
                 parsedData =
                     parseCSV csvData
             in
-            ( { model | data = parsedData, error = Nothing, csvdata = csvData }, Cmd.none )
+            case parsedData of
+                Ok data ->
+                    ( { model | data = data, error = Nothing, csvdata = csvData }, Cmd.none )
+
+                Err _ ->
+                    ( { model | error = Just "Failed to parse CSV data" }, Cmd.none )
 
         DataReceived (Err _) ->
             ( { model | error = Just "Failed to load data" }, Cmd.none )
@@ -82,17 +101,6 @@ view model =
         ]
 
 
-
--- viewItem : Smartphone -> Html msg
--- viewItem smartphone =
---     li []
---         [ text ("ID: " ++ smartphone.id)
---         , text (", Price: " ++ String.fromFloat smartphone.price)
---         , text (", Rating: " ++ String.fromFloat smartphone.rating)
---         ]
--- SUBSCRIPTIONS
-
-
 subscriptions : Model -> Sub Msg
 subscriptions _ =
     Sub.none
@@ -114,68 +122,92 @@ fetchData =
 -- PARSING CSV
 
 
-parseCSV : String -> List Smartphone
+decoder : Decoder Smartphone
+decoder =
+    Decode.into Smartphone
+        |> Decode.pipeline (Decode.field "id" (Decode.blank Decode.string))
+        |> Decode.pipeline (Decode.field "brand" (Decode.blank Decode.string))
+        |> Decode.pipeline (Decode.field "model" (Decode.blank Decode.string))
+        |> Decode.pipeline (Decode.field "price" (Decode.blank Decode.float))
+        |> Decode.pipeline (Decode.field "rating" (Decode.blank Decode.float))
+        |> Decode.pipeline (Decode.field "5G" (Decode.blank Decode.string |> Decode.map toBool))
+        |> Decode.pipeline (Decode.field "NFC" (Decode.blank Decode.string |> Decode.map toBool))
+        |> Decode.pipeline (Decode.field "IR_blaster" (Decode.blank Decode.string |> Decode.map toBool))
+        |> Decode.pipeline (Decode.field "processor_name" (Decode.blank Decode.string))
+        |> Decode.pipeline (Decode.field "processor_brand" (Decode.blank Decode.string))
+        |> Decode.pipeline (Decode.field "num_cores" (Decode.blank Decode.string |> Decode.map toCores))
+        |> Decode.pipeline (Decode.field "processor_speed" (Decode.blank Decode.string |> Decode.map toGHz))
+        |> Decode.pipeline (Decode.field "Battery" (Decode.blank Decode.float))
+        |> Decode.pipeline (Decode.field "fast_charging" (Decode.blank Decode.float))
+        |> Decode.pipeline (Decode.field "Internal_mem" (Decode.blank Decode.string |> Decode.map toGB))
+        |> Decode.pipeline (Decode.field "RAM" (Decode.blank Decode.float))
+        |> Decode.pipeline (Decode.field "screen_size" (Decode.blank Decode.string |> Decode.map toInche))
+        |> Decode.pipeline (Decode.field "resolution" (Decode.blank Decode.string))
+        |> Decode.pipeline (Decode.field "refresh_rate" (Decode.blank Decode.int))
+        |> Decode.pipeline (Decode.field "camera" (Decode.blank Decode.string))
+        |> Decode.pipeline (Decode.field "card" (Decode.blank Decode.string))
+        |> Decode.pipeline (Decode.field "os" (Decode.blank Decode.string))
+
+
+parseCSV : String -> Result Decode.Error (List Smartphone)
 parseCSV csv =
-    case lines csv of
-        [] ->
-            []
+    Decode.decodeCsv Decode.FieldNamesFromFirstRow decoder csv
 
-        headerLine :: dataLines ->
-            let
-                headers =
-                    split "," headerLine
-            in
-            List.map (parseRow headers) dataLines
 
+toBool : Maybe String -> Maybe Bool
+toBool str =
+    case str of
+        Just "True" ->
+            Just True
 
-parseRow : List String -> String -> Smartphone
-parseRow headers row =
-    let
-        values =
-            split "," row
+        Just "False" ->
+            Just False
 
-        lookup key =
-            case List.head (List.filter (\( k, _ ) -> k == key) (List.map2 (\h v -> ( h, v )) headers values)) of
-                Just ( _, value ) ->
-                    value
+        _ ->
+            Nothing
 
-                Nothing ->
-                    ""
 
-        id =
-            lookup "index"
+toCores : Maybe String -> Maybe Float
+toCores str =
+    case str of
+        Just "dual core" ->
+            Just 2
 
-        brand =
-            lookup "brand"
+        Just "quad core" ->
+            Just 4
 
-        model =
-            lookup "model"
+        Just "hexa core" ->
+            Just 6
 
-        price =
-            String.toFloat (lookup "price")
+        Just "octa core" ->
+            Just 8
 
-        rating =
-            String.toFloat (lookup "rating")
+        _ ->
+            Nothing
 
-        g5 =
-            if lookup "5G" == "True" then
-                True
 
-            else
-                False
+toGHz : Maybe String -> Maybe Float
+toGHz str =
+    str
+        |> Maybe.withDefault ""
+        |> String.replace "GHz Processor" ""
+        |> String.trim
+        |> String.toFloat
 
-        nfc =
-            if lookup "NFC" == "True" then
-                True
 
-            else
-                False
+toGB : Maybe String -> Maybe Float
+toGB str =
+    str
+        |> Maybe.withDefault ""
+        |> String.replace "GB inbuilt" ""
+        |> String.trim
+        |> String.toFloat
 
-        ir_blaster =
-            if lookup "IR_blaster" == "True" then
-                True
 
-            else
-                False
-    in
-    Smartphone id brand model price rating g5 nfc ir_blaster
+toInche : Maybe String -> Maybe Float
+toInche str =
+    str
+        |> Maybe.withDefault ""
+        |> String.replace "inches" ""
+        |> String.trim
+        |> String.toFloat
diff --git a/src/Scatterplot.elm b/src/Scatterplot.elm
index 12620bfdd0ca2cfe1a1ea8639b810b3c8ff8c22a..e1f854083f79fab2ecc43c35eeb0be492d790a15 100644
--- a/src/Scatterplot.elm
+++ b/src/Scatterplot.elm
@@ -1,7 +1,5 @@
 module Scatterplot exposing (..)
 
--- in Ellie: https://ellie-app.com/qQPVFCsZT3La1
-
 import Axis exposing (..)
 import Html exposing (Html)
 import Scale exposing (ContinuousScale)
@@ -20,15 +18,33 @@ type alias Model =
     }
 
 
+
+-- ohne ram,display
+
+
 type alias Smartphone =
-    { id : String
-    , brand : String
-    , model : String
+    { id : Maybe String
+    , brand : Maybe String
+    , model : Maybe String
     , price : Maybe Float
     , rating : Maybe Float
-    , g5 : Bool
-    , nfc : Bool
-    , ir_blaster : Bool
+    , g5 : Maybe Bool
+    , nfc : Maybe Bool
+    , ir_blaster : Maybe Bool
+    , processor_name : Maybe String
+    , processor_brand : Maybe String
+    , num_cors : Maybe Float
+    , processor_speed : Maybe Float
+    , battery : Maybe Float
+    , fast_charging : Maybe Float
+    , memory : Maybe Float
+    , ram : Maybe Float
+    , screen_size : Maybe Float
+    , resolution : Maybe String
+    , refresh_rate : Maybe Int
+    , camera : Maybe String
+    , card : Maybe String
+    , os : Maybe String
     }
 
 
@@ -65,10 +81,9 @@ defaultExtent =
 scatterplot : XyData -> Svg msg
 scatterplot model =
     let
-        kreisbeschriftung : String
-        kreisbeschriftung =
-            (Maybe.withDefault (Point "Nothing" 0 0) (List.head model.data)).pointName
-
+        -- kreisbeschriftung : String
+        -- kreisbeschriftung =
+        --     (Maybe.withDefault (Point "Nothing" 0 0) (List.head model.data)).pointName
         xValues : List Float
         xValues =
             List.map .x model.data
@@ -114,7 +129,7 @@ scatterplot model =
             [ yAxis yValues
             , text_
                 [ x 0, y (Scale.convert yScaleLocal labelPositions.y - 10), textAnchor AnchorMiddle, fontSize <| Px 14 ]
-                [ Html.text "Rating" ]
+                [ Html.text "Memory" ]
             ]
 
         -- datenpunkte zeichnen
@@ -197,7 +212,7 @@ filterSmartphones smartphoneList =
         filteredSmartphones =
             List.filterMap mapToPoint smartphoneList
     in
-    XyData "price" "rating" filteredSmartphones
+    XyData "price" "memory" filteredSmartphones
 
 
 mapToPoint : Smartphone -> Maybe Point
@@ -210,8 +225,8 @@ mapToPoint smartphone =
             }
         )
         smartphone.price
-        smartphone.rating
-        (Just smartphone.id)
+        smartphone.memory
+        smartphone.id
 
 
 viewScatterplot : Model -> Html msg
@@ -226,17 +241,3 @@ viewScatterplot model =
     Html.div []
         [ scatterplot filteredSmartphoneData
         ]
-
-
-
--- type CarType
---     = Small_Sporty_Compact_Large_Sedan
---     | Sports_Car
---     | SUV
---     | Wagon
---     | Minivan
---     | Pickup
--- type WheelDrive
---     = All_Wheel_Drive
---     | Rear_Wheel_Drive
---     | Front_Wheel_Drive