class MotorcycleYear { final int year; MotorcycleYear(this.year); @override bool operator ==(Object other) => identical(this, other) || other is MotorcycleYear && runtimeType == other.runtimeType && year == other.year; @override int get hashCode => year.hashCode; } class MotorcycleMake { final String id; final String name; MotorcycleMake({required this.id, required this.name}); factory MotorcycleMake.fromJson(Map json) { return MotorcycleMake( id: json['id']?.toString() ?? json['MakeId']?.toString() ?? '', name: json['name']?.toString() ?? json['MakeName']?.toString() ?? '', ); } Map toJson() => {'id': id, 'name': name}; } class MotorcycleModel { final String id; final String name; final String makeId; final int? year; MotorcycleModel({ required this.id, required this.name, required this.makeId, this.year, }); factory MotorcycleModel.fromJson(Map json) { return MotorcycleModel( id: json['id']?.toString() ?? json['Model_ID']?.toString() ?? json['Model_Id']?.toString() ?? '', name: json['name']?.toString() ?? json['Model_Name']?.toString() ?? '', makeId: json['makeId']?.toString() ?? json['Make_ID']?.toString() ?? '', year: json['year'] as int?, ); } Map toJson() => { 'id': id, 'name': name, 'makeId': makeId, 'year': year, }; } class MotorcycleVariant { final String id; final String name; MotorcycleVariant({required this.id, required this.name}); factory MotorcycleVariant.fromJson(Map json) { return MotorcycleVariant( id: json['id']?.toString() ?? '', name: json['name']?.toString() ?? '', ); } Map toJson() => {'id': id, 'name': name}; } class MotorcycleSelection { final int year; final String makeId; final String makeName; final String modelId; final String modelName; final String? variantId; final String? variantName; MotorcycleSelection({ required this.year, required this.makeId, required this.makeName, required this.modelId, required this.modelName, this.variantId, this.variantName, }); String get displayName { final base = '$year $makeName $modelName'; if (variantName != null && variantName!.isNotEmpty) { return '$base $variantName'; } return base; } Map toJson() => { 'year': year, 'makeId': makeId, 'makeName': makeName, 'modelId': modelId, 'modelName': modelName, 'variantId': variantId, 'variantName': variantName, }; factory MotorcycleSelection.fromJson(Map json) { return MotorcycleSelection( year: json['year'] as int, makeId: json['makeId'] as String, makeName: json['makeName'] as String, modelId: json['modelId'] as String, modelName: json['modelName'] as String, variantId: json['variantId'] as String?, variantName: json['variantName'] as String?, ); } } class MotorcycleSpecification { // Basic final int year; final String manufacturer; final String model; final String? variant; final String? category; final String? marketRegion; // Engine final double? displacementCc; final String? engineConfiguration; final int? cylinderCount; final double? boreMm; final double? strokeMm; final String? compressionRatio; final String? coolingSystem; final String? fuelSystem; final String? fuelType; final String? valveConfiguration; final double? horsepower; final int? horsepowerRpm; final double? torqueLbFt; final int? torqueRpm; final int? redlineRpm; // Transmission final String? transmissionType; final int? gearCount; final String? finalDrive; // Weight & Dimensions final double? wetWeightLbs; final double? dryWeightLbs; final double? seatHeightInches; final double? wheelbaseInches; final double? lengthInches; final double? widthInches; final double? heightInches; // Fuel final double? fuelCapacityGallons; final double? fuelEconomyMpg; final double? estimatedRangeMiles; // Chassis & Brakes & Wheels final String? frameType; final String? frontSuspension; final String? rearSuspension; final String? frontBrake; final String? rearBrake; final String? absType; final String? frontTireSize; final String? rearTireSize; // Performance claims final double? claimedTopSpeedMph; final double? claimedZeroToSixtySec; final double? claimedQuarterMileSec; // Metadata final String? source; final String? sourceUrl; final DateTime? lastUpdated; MotorcycleSpecification({ required this.year, required this.manufacturer, required this.model, this.variant, this.category, this.marketRegion, this.displacementCc, this.engineConfiguration, this.cylinderCount, this.boreMm, this.strokeMm, this.compressionRatio, this.coolingSystem, this.fuelSystem, this.fuelType, this.valveConfiguration, this.horsepower, this.horsepowerRpm, this.torqueLbFt, this.torqueRpm, this.redlineRpm, this.transmissionType, this.gearCount, this.finalDrive, this.wetWeightLbs, this.dryWeightLbs, this.seatHeightInches, this.wheelbaseInches, this.lengthInches, this.widthInches, this.heightInches, this.fuelCapacityGallons, this.fuelEconomyMpg, this.estimatedRangeMiles, this.frameType, this.frontSuspension, this.rearSuspension, this.frontBrake, this.rearBrake, this.absType, this.frontTireSize, this.rearTireSize, this.claimedTopSpeedMph, this.claimedZeroToSixtySec, this.claimedQuarterMileSec, this.source, this.sourceUrl, this.lastUpdated, }); Map toJson() => { 'year': year, 'manufacturer': manufacturer, 'model': model, 'variant': variant, 'category': category, 'marketRegion': marketRegion, 'displacementCc': displacementCc, 'engineConfiguration': engineConfiguration, 'cylinderCount': cylinderCount, 'boreMm': boreMm, 'strokeMm': strokeMm, 'compressionRatio': compressionRatio, 'coolingSystem': coolingSystem, 'fuelSystem': fuelSystem, 'fuelType': fuelType, 'valveConfiguration': valveConfiguration, 'horsepower': horsepower, 'horsepowerRpm': horsepowerRpm, 'torqueLbFt': torqueLbFt, 'torqueRpm': torqueRpm, 'redlineRpm': redlineRpm, 'transmissionType': transmissionType, 'gearCount': gearCount, 'finalDrive': finalDrive, 'wetWeightLbs': wetWeightLbs, 'dryWeightLbs': dryWeightLbs, 'seatHeightInches': seatHeightInches, 'wheelbaseInches': wheelbaseInches, 'lengthInches': lengthInches, 'widthInches': widthInches, 'heightInches': heightInches, 'fuelCapacityGallons': fuelCapacityGallons, 'fuelEconomyMpg': fuelEconomyMpg, 'estimatedRangeMiles': estimatedRangeMiles, 'frameType': frameType, 'frontSuspension': frontSuspension, 'rearSuspension': rearSuspension, 'frontBrake': frontBrake, 'rearBrake': rearBrake, 'absType': absType, 'frontTireSize': frontTireSize, 'rearTireSize': rearTireSize, 'claimedTopSpeedMph': claimedTopSpeedMph, 'claimedZeroToSixtySec': claimedZeroToSixtySec, 'claimedQuarterMileSec': claimedQuarterMileSec, 'source': source, 'sourceUrl': sourceUrl, 'lastUpdated': lastUpdated?.toIso8601String(), }; factory MotorcycleSpecification.fromJson(Map json) { return MotorcycleSpecification( year: json['year'] as int, manufacturer: json['manufacturer'] as String, model: json['model'] as String, variant: json['variant'] as String?, category: json['category'] as String?, marketRegion: json['marketRegion'] as String?, displacementCc: (json['displacementCc'] as num?)?.toDouble(), engineConfiguration: json['engineConfiguration'] as String?, cylinderCount: json['cylinderCount'] as int?, boreMm: (json['boreMm'] as num?)?.toDouble(), strokeMm: (json['strokeMm'] as num?)?.toDouble(), compressionRatio: json['compressionRatio'] as String?, coolingSystem: json['coolingSystem'] as String?, fuelSystem: json['fuelSystem'] as String?, fuelType: json['fuelType'] as String?, valveConfiguration: json['valveConfiguration'] as String?, horsepower: (json['horsepower'] as num?)?.toDouble(), horsepowerRpm: json['horsepowerRpm'] as int?, torqueLbFt: (json['torqueLbFt'] as num?)?.toDouble(), torqueRpm: json['torqueRpm'] as int?, redlineRpm: json['redlineRpm'] as int?, transmissionType: json['transmissionType'] as String?, gearCount: json['gearCount'] as int?, finalDrive: json['finalDrive'] as String?, wetWeightLbs: (json['wetWeightLbs'] as num?)?.toDouble(), dryWeightLbs: (json['dryWeightLbs'] as num?)?.toDouble(), seatHeightInches: (json['seatHeightInches'] as num?)?.toDouble(), wheelbaseInches: (json['wheelbaseInches'] as num?)?.toDouble(), lengthInches: (json['lengthInches'] as num?)?.toDouble(), widthInches: (json['widthInches'] as num?)?.toDouble(), heightInches: (json['heightInches'] as num?)?.toDouble(), fuelCapacityGallons: (json['fuelCapacityGallons'] as num?)?.toDouble(), fuelEconomyMpg: (json['fuelEconomyMpg'] as num?)?.toDouble(), estimatedRangeMiles: (json['estimatedRangeMiles'] as num?)?.toDouble(), frameType: json['frameType'] as String?, frontSuspension: json['frontSuspension'] as String?, rearSuspension: json['rearSuspension'] as String?, frontBrake: json['frontBrake'] as String?, rearBrake: json['rearBrake'] as String?, absType: json['absType'] as String?, frontTireSize: json['frontTireSize'] as String?, rearTireSize: json['rearTireSize'] as String?, claimedTopSpeedMph: (json['claimedTopSpeedMph'] as num?)?.toDouble(), claimedZeroToSixtySec: (json['claimedZeroToSixtySec'] as num?)?.toDouble(), claimedQuarterMileSec: (json['claimedQuarterMileSec'] as num?)?.toDouble(), source: json['source'] as String?, sourceUrl: json['sourceUrl'] as String?, lastUpdated: json['lastUpdated'] != null ? DateTime.parse(json['lastUpdated']) : null, ); } }